Jump to content

"Personal" variables


Deddalt

Recommended Posts

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

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. :wink:

Link to comment

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
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. :wink:

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

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

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

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

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