DarkM Posted February 16, 2010 Share Posted February 16, 2010 I'm using the login system from the guide on the wiki but what do I do if i want dozens of accounts? I don't want to be putting them all into gui.lua so how can I make this easier and cleaner? gui.lua (client): function createLoginWindow() -- define the X and Y positions of the window local X = 0.375 local Y = 0.375 -- define the width and height of the window local Width = 0.25 local Height = 0.25 -- create the window and save its element value into the variable 'wdwLogin' -- click on the function's name to read its documentation wdwLogin = guiCreateWindow(X, Y, Width, Height, "Please Log In", true) -- define new X and Y positions for the first label X = 0.0825 Y = 0.2 -- define new Width and Height values for the first label Width = 0.25 Height = 0.25 -- create the first label, note the final argument passed is 'wdwLogin' meaning the window -- we created above is the parent of this label (so all the position and size values are now relative to the position of that window) guiCreateLabel(X, Y, Width, Height, "Username", true, wdwLogin) -- alter the Y value, so the second lebel is slightly below the first Y = 0.5 guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin) X = 0.415 Y = 0.2 Width = 0.5 Height = 0.15 edtUser = guiCreateEdit(X, Y, Width, Height, "", true, wdwLogin) Y = 0.5 edtPass = guiCreateEdit(X, Y, Width, Height, "", true, wdwLogin) -- Max chars to 50 guiEditSetMaxLength(edtUser, 50) guiEditSetMaxLength(edtPass, 50) X = 0.415 Y = 0.7 Width = 0.25 Height = 0.2 btnLogin = guiCreateButton(X, Y, Width, Height, "Log In", true, wdwLogin) -- make the window invisible guiSetVisible(wdwLogin, false) -- stop players from being able to simply move the window out of the way guiWindowSetMovable(rulesWindow,false) -- stop players from being able to resize the window guiWindowSetSizable(rulesWindow,false) -- now add our onClientGUIClick event to the button we just created addEventHandler("onClientGUIClick", btnLogin, clientSubmitLogin, false) end -- attach the event handler to the root element of the resource -- this means it will only trigger when ts own resource is started addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), function () -- create the log in window and its components createLoginWindow() -- output a bried welcome message tot he player outputChatBox("Welcome to DarkM's RP, please log in.") -- if the GUI was successfully created, the show the GUI to the player if (wdwLogin ~= nil) then guiSetVisible(wdwLogin, true) else -- if the GUI hasn't been properly created, tell the player outputChatBox("An unexpected error has occured and the log in GUI has not been created.") end -- enable the players cursor (so they can select and click on components) showCursor(true) -- set the input focus onto the GUI, allowing players (For example) to press 'T' without the chatbox opening guiSetInputEnabled(true) end ) -- create the function and define the 'button' and 'state' parameters -- (these are passed automatically by onClientGUIClick) function clientSubmitLogin(button,state) if button == "left" and state == "up" then -- get the text entered in the 'unsername' field local username = guiGetText(edtUser) -- get the text entered in the 'password' field local password = guiGetText(edtPass) -- if the username and password both exist if username and password then -- trigger the server event 'submitLogin' and pass the username and password to it triggerServerEvent("submitLogin", getLocalPlayer(), username, password) else -- otherwise, output a message to the player, do not trigger the server -- and do not hide thr gui outputChatBox("Please enter a username and password.") end if username == "user" and password == "apple" then guiGetEnabled(false) guiSetVisible(wdwLogin, false) guiSetVisible(rulesWindow,true) end end end script.lua(server): function loginHandler(username,password) -- check that the username and password are correct if username == "user" and password == "apple" then -- the player has successfully logged in, so spawn them if (source) then setCameraTarget(source, source) fadeCamera(source, false) outputChatBox("Thank you for logging in.", source) end else -- if the username or password are not correct, output message to player outputChatBox("Invalid username and/or password. Please try again.",source) end end addEvent("submitLogin",true) addEventHandler("submitLogin",root,loginHandler) Link to comment
Aibo Posted February 16, 2010 Share Posted February 16, 2010 use XML or SQL. btw why do you need your own authorization system if MTA package already has one? Link to comment
Andre9977 Posted February 16, 2010 Share Posted February 16, 2010 (edited) Use the XML functions or SQL functions based on if you're going to process the data somewhere else but your gameserver. If you are then it is the best to use SQL, otherwise go for XML. All you have to do in the loginHandler is to get the player's username and password from SQL or XML and then compare, so... if username == "user" and password == "apple" then becomes result = executeSQLSelect("players", "player,password", "player = '" .. getPlayerName(source) .. "'") if password == result[1]['password'] then -- log in here Of course you need to check if the account exists in the SQL database. If not then make the player register, etc. Edited February 16, 2010 by Guest Link to comment
Aibo Posted February 16, 2010 Share Posted February 16, 2010 Use the XML functions or SQL functions based on if you're going to process the data somewhere else but your gameserver. If you are then it is the best to use SQL, otherwise go for XML.All you have to do in the loginHandler is to get the player's username and password from SQL or XML and then compare, so... if username == "user" and password == "apple" then becomes result = executeSQLSelect("players", "player", "player = '" .. getPlayerName(source) .. "'") if password == result[1]['password'] then -- log in here Of course you need to check if the account exists in the SQL database. If not then make the player register, etc. you forgot to get 'password' from database Link to comment
Andre9977 Posted February 16, 2010 Share Posted February 16, 2010 I wish there was an easier way to execute a SQL query, so we could just run the query without having to put the table, fields, where clause and possible limit into a separate parameter. SELECT `password` FROM `players` WHERE `player` = '" .. getPlayerName(source) .. "' Also, I don't think we really need to get the `player` again when we already basically have the player's name as our `player`. For some comparing on awkward reasons maybe yes. And also, I think it would be the best to have a SQL table driven by user IDs which are also indexers and queries in theory are better when ran with a indexed integer not a string. executeSQLCreateTable("players", "`id` smallint(7) NOT NULL AUTO_INCREMENT, `name` varchar(21) NOT NULL, `pass` varchar(16) NOT NULL, PRIMARY KEY (`reg_id`)"); Then on your connect function you get the `id` and `pass` where `name` is the player's name. result = executeSQLSelect("players", "id,pass", "player = '" .. getPlayerName(source) .. "'", 1); (also added result limit) the result[1]['id'] you store as the player's ID and in all future queries you use it, for example like this -- where result[1]['id'] from previous code is playerID, for example use the query when your player changes name executeSQLUpdate("players", "player = '" .. newNick .. "'", "id = '" .. playerID .. "'"); Also it would be kind of awesome if there was a function like affected_rows etc. Looks like the inbuilt MTA SQL functions are kind of limited. Sorry for the mistake above. And I'm not sure if any of the code really works, it should. Link to comment
Aibo Posted February 16, 2010 Share Posted February 16, 2010 I wish there was an easier way to execute a SQL query, so we could just run the query without having to put the table, fields, where clause and possible limit into a separate parameter.SELECT `password` FROM `players` WHERE `player` = '" .. getPlayerName(source) .. "' what's wrong with executeSQLQuery? result = executeSQLQuery("SELECT password FROM players WHERE player = '" .. getPlayerName(source) .. "'") Link to comment
Brophy Posted February 16, 2010 Share Posted February 16, 2010 Just a note, SQL is the correct way to go about login and account management, Do not rely on the built in one with MTA, its ok with a few accounts for people who want to use the Admin resource, but the server writes out the file 'accounts.xml' every time a player joins or quits, it locks up until its finished. If there are 100's of accounts, this can take several seconds, and can cause "Network Trouble" messages to appear on all connected clients. Also you do not need to retrieve anything for login tbh, just store players username and password in the same table and check if you get a hit by calling both username and password at the same time, so if you used executeSQLSelect to check the player_data table to find the username where both the username and password matched the ones entered into the gui, you could set that player as logged in via setElementData or better yet, store his username via setElementData, then can retrieve his username with getElementData and query the database again Example: (You would need to write your own client <-> server functions to check what was entered into gui etc) Example Keys: executeSQLSelect = check MTA Wiki for information about this function and arguments usernameVar = username passed from gui passwordVar = password passed from gui player = player who is trying to login -- Just part of a 'function' for login process queryLoginInfo = executeSQLSelect ( "player_data", "username", "username = '"..usernameVar.."' AND password = '"..passwordVar.."'" ) if ( #queryLoginInfo ~= 0 ) then local userAccount = setElementData ( player, "username", usernameVar ) if ( userAccount ) then outputChatBox ( "You are now logged in as: "..usernameVar, player ) end else outputChatBox ( "Login Failed", player ) end You could then check the SQLite db for anything else associated with that username by using getElementData on the player you wish to check and using what it returns in a sql query, that way a player will still have the same username, and able to change ingame names etc Hope you understand and that I haven't confused you hehe. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now