Jump to content

Is There An Easier Way For Login System?


DarkM

Recommended Posts

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

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 by Guest
Link to comment
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 :P

Link to comment

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
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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...