Deddalt Posted August 1, 2008 Share Posted August 1, 2008 Alright, I have a sneaking suspicion that when someone does something and I set a variable to a different number/value because of it, it is setting that variable for EVERYONE. So that bothers me. I hate to make another C++ example, but I have to. new variable[MAX_PLAYERS]; So then you do: variable[playerid] = 1; Now the variable is set to 1 for that player, but when I'm using LUA, I didn't notice until just now that I hadn't specified such a thing. Could someone please tell me how to set a variable to a value only for the player it is concerning? Currently I'm trying to make a "failed log-in attempt" variable: logtries = 0 -- at the top of the script, not quite sure this works anyway, but still... function SubmitLogin(thePlayer) local account = getClientAccount(thePlayer) local pass = getAccountData(account, "Player.pass") if(edtPass == pass) triggerServerFunction(onJoin) end else triggerClientFunction(onClientResourceStart) outputChatBox("That log-in information is incorrect. Please try again.",thePlayer,255,0,0) tries = tries + 1 if(tries == 5) local name = getClientName(thePlayer) local ip = getClientIP(thePlayer) banIP(ip) outputChatBox(name.." has been auto-banned. Reason: 5 Failed log-in attempts.") end end Link to comment
robhol Posted August 1, 2008 Share Posted August 1, 2008 You better lose the playerId concept, it's non-existant in MTA. Instead you do: tbl = {}; -- initialize table ("array") tbl[1] = 1; tbl[5] = 5; tbl["abc"] = "wohoo"; tbl[player] = {}; tbl[player]["bank"]= 100000; Ergo, any number, string or element can be used as the index... Lua doesn't have types, any variable can contain anything. These functions are also an option: http://development.mtasa.com/index.php? ... lementData http://development.mtasa.com/index.php? ... lementData Since you came here from SA-MP and PAWN (not C++, FYI) there's a lot of stuff you need to adjust in your way of thinking... for example events (not in SA-MP), client-side scripts (not in SA-MP), GUI (limited in SA-MP) etc, but luckily, the wiki contains info on this.. and if you're struggling, visit the #mta.scripting channel on GTAnet on IRC. Or, of course, this forum. Link to comment
Ace_Gambit Posted August 1, 2008 Share Posted August 1, 2008 Here's a simple example showing how to make sure a global server side variable is not overwritten when a new client is accessing the value. local players = {} function SubmitLogin(thePlayer) local data = players[thePlayer] or false local account = false if (isElement(thePlayer) and data) then account = getClientAccount(thePlayer) [..] players[thePlayer] = data + 1 [..] end end function onPlayerJoin() players[source] = 0 end function onPlayerQuit(reason) players[source] = nil end addEventHandler("onPlayerJoin", root, oPlayerJoin, true) addEventHandler("onPlayerQuit", root, onPlayerQuit, true) Link to comment
Deddalt Posted August 1, 2008 Author Share Posted August 1, 2008 You better lose the playerId concept, it's non-existant in MTA. Instead you do: tbl = {}; -- initialize table ("array") tbl[1] = 1; tbl[5] = 5; tbl["abc"] = "wohoo"; tbl[player] = {}; tbl[player]["bank"]= 100000; Ergo, any number, string or element can be used as the index... Lua doesn't have types, any variable can contain anything. These functions are also an option: http://development.mtasa.com/index.php? ... lementData http://development.mtasa.com/index.php? ... lementData Since you came here from SA-MP and PAWN (not C++, FYI) there's a lot of stuff you need to adjust in your way of thinking... for example events (not in SA-MP), client-side scripts (not in SA-MP), GUI (limited in SA-MP) etc, but luckily, the wiki contains info on this.. and if you're struggling, visit the #mta.scripting channel on GTAnet on IRC. Or, of course, this forum. So how would I use this to make it when someone's login password is wrong, it adds one to the variable for them. Such as my PAWN example, when someone fails to log in, it adds one, and when it gets to five, they get banned. I'm sort of thinking... tbl = {}; -- initialize table ("array") tbl[1] = 1; tbl[5] = 5; tbl["abc"] = "wohoo"; tbl[player] = {}; tbl[player]["logtries"]= 0; function SubmitLogin(thePlayer) local account = getClientAccount(thePlayer) local pass = getAccountData(account, "Player.pass") if(edtPass == pass) triggerServerFunction(onJoin) end else triggerClientFunction(onClientResourceStart) outputChatBox("That log-in information is incorrect. Please try again.",thePlayer,255,0,0) tbl[player]["logtries"] = tbl[player]["logtries"] + 1 -- ************** ? if(tbl[player]["logtries"] >= 5) -- ************** ? local name = getClientName(thePlayer) local ip = getClientIP(thePlayer) banIP(ip) outputChatBox(name.." has been auto-banned. Reason: 5 Failed log-in attempts.") end end end Link to comment
Ace_Gambit Posted August 2, 2008 Share Posted August 2, 2008 You could try a modified version of the code posted earlier. local loginAttempts = {} function SubmitLogin(thePlayer, userPass) local totalAttempts = loginAttempts[thePlayer] or false local account = false local pass = "" local name = "" local ip = "" if (not hasObjectPermissionTo(getThisResource(), "function.getClientIP") or not hasObjectPermissionTo(getThisResource(), "function.banIP")) then outputDebugString("ACL denied access to functions.") return false end if (isElement(thePlayer) and totalAttempts) then account = getClientAccount(thePlayer) if (account) then pass = getAccountData(account, "Player.pass") if (userPass == pass) then triggerClientEvent(source, "onServerLoginSuccess", getRootElement()) else loginAttempts[thePlayer] = totalAttempts + 1 if (totalAttempts < 5) then triggerClientEvent(source, "onServerLoginFailed", getRootElement()) outputChatBox("That log-in information is incorrect. Please try again (" .. totalAttempts .. " attempt(s)).", thePlayer, 255, 0, 0, false) else name = getClientName(thePlayer) or "" ip = getClientIP(thePlayer) or "" banIP(ip) outputChatBox("#FF0000" .. name .. " has been auto-banned. Reason: 5 Failed log-in attempts.", getRootElement(), 255, 255, 255, true) end end end end return true end function onPlayerJoin() loginAttempts[source] = 0 end function onPlayerQuit(reason) loginAttempts[source] = nil end addEventHandler("onPlayerJoin", root, oPlayerJoin, true) addEventHandler("onPlayerQuit", root, onPlayerQuit, true) Link to comment
Deddalt Posted August 2, 2008 Author Share Posted August 2, 2008 Alright, I was going to ask this question in IRC, but I can't manage to find GTAnet. But anyway: Again, this is a PAWN example, but on SA-MP you can use a loop to get information from all the players in the server. Something like: for(new i=0;i) So if you did: if(PlayerInfo[i][pStat] == value) doesthisstuff I'm trying to make a /me command, so it will check every player in the server: function slashMe(commandName, action) for(new i=0;i) -- I NEED TO REPLACE THIS WITH AN LUA EQUIVALENT local x,y,z = getElementPos(source) local name = getClientName(source) local x2,y2,z2 = getElementPos(i) if(x2 <= x + 5 and y2 <= y + 5 and z2 <= z + 5)then outputChatBox("* "name.." "..action,i,255,0,255) -- So it sends a message to anyone within a certain vicinity, for example "John_Appleseed makes cans." (in purple) outputChatBox("* "name.." "..action,source,255,0,255) -- Sends the same message to the player who wrote it so they can be sure of what they wrote. else outputChatBox("* "name.." "..action,source,255,0,255) -- Sends the message only to the player. end end So I really need to have an equivalent to the "player loop" from PAWN coding. Thanks for the help. Link to comment
Ace_Gambit Posted August 2, 2008 Share Posted August 2, 2008 In MTA players are elements (elements of type "player" to be exact). You can get a table of element types with the getElementsByType function. players = getElementsByType("player") for key, value in ipairs(players) do -- end Link to comment
Deddalt Posted August 2, 2008 Author Share Posted August 2, 2008 (edited) function slashMe(commandName, action) for key, value in ipairs(players) do if(action ~= "" and action ~= nil)then local x,y,z = getElementPos(source) local x2,y2,z2 = getElementPos(players) if(x2 <= x + 5 and y2 <= y + 5 and z2 <= z + 5)then local name = getClientName(source) outputChatBox("* "..name.." "..action,players,255,0,255) -- I HAVE A FEELING THIS WON'T WORK RIGHT outputChatBox("* "..name.." "..action,source,255,0,255) end else outputChatBox("USE: /me [action]",source,255,255,0) end end EDIT: Alright, I've figured it out and fixed all of the problems. I used createColSphere(x,y,z,rad) instead. Edited August 2, 2008 by Guest Link to comment
Ace_Gambit Posted August 2, 2008 Share Posted August 2, 2008 Here is what I wrote from what you've told me. I have a feeling that the commented line won't work because it will send the message to everyone in the server. If that's the case, how do I make it send the message only to the players who are within 5... area... units? function slashMe(commandName, action) local x, y, z = 0, 0, 0 local x2, y2, z2 = 0, 0, 0 if(action ~= "" and action)then x, y, z = getElementPosition(source) or 0, 0, 0 for _, player in ipairs((getElementsByType("player") or {})) do x2, y2, z2 = getElementPosition(player) or 0, 0, 0 if ((getDistanceBetweenPoints3D(x, y, z, x2, y2, z2) or 0) <= 5) then outputChatBox("* " .. (getClientName(source) or "") .. " " .. action, player, 255, 0, 255) end end else outputChatBox("USE: /me [action]", source, 255, 255, 0) end end Link to comment
Deddalt Posted August 2, 2008 Author Share Posted August 2, 2008 local chatRadius = 20 --units function chat( message, messageType ) if messageType == 0 then local posX, posY, posZ = getElementPosition( source ) local chatSphere = createColSphere( posX, posY, posZ, chatRadius ) local nearbyPlayers = getElementsWithinColShape( chatSphere, "player" ) destroyElement( chatSphere ) for index, nearbyPlayer in ipairs( nearbyPlayers ) do outputChatBox( message, nearbyPlayer ) end if messageType == 1 then if message ~= "" and message ~= nil then local posX, posY, posZ = getElementPosition(source) local chatSphere = createColSphere(posX,posY,posZ, chatRadius) local nearbyPlayers = getElementsWithinColShape(chatSphere, "player") destroyElement(chatSphere) for index, nearbyPlayer in ipairs(nearbyPlayers) do outputChatBox("* "message, nearbyPlayer,255,0,255) end else outputChatBox("USE: /me [action]",source,255,255,0) end end end addEventHandler('onPlayerChat', getRootElement(), chat) I ended up with this when I was looking around on the wiki. However, thanks for the help! Link to comment
Ace_Gambit Posted August 2, 2008 Share Posted August 2, 2008 Keep in mind that getElementsWithinColShape does not work in DP2. Link to comment
Deddalt Posted August 2, 2008 Author Share Posted August 2, 2008 Neither does setAccountData, so I'm going to wait for dp3 to start up this server, heh. Link to comment
Ace_Gambit Posted August 2, 2008 Share Posted August 2, 2008 setAccountData works for the duration of a session. All data will be lost when you close the server. Link to comment
haybail Posted August 3, 2008 Share Posted August 3, 2008 getElementsWithinColShape works in dp2? just only with players and vehicles. 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