Jump to content

[HELP] Setting the money of a player through multiple events


Recommended Posts

Hi all, 

Just started Lua scripting and I am already running into something I do not quite understand. I am trying to set the player's money after logging in.
I am not getting any warnings or errors, but the players' money does not get updated for some reason. This is what I tried:

On a successful login I trigger an event which I have in another server file:

triggerEvent ("updateMoney", root)

In my other server file I have the function:

function updateMoneyHandler(token)
    triggerClientEvent ("updateMoneyClient", source, 1000)
end
addEvent("updateMoney",true)
addEventHandler("updateMoney",root,updateMoneyHandler)

So I try to set the user's money to 1000 by sending it to the client. This is my client file:

function updateMoneyClientHandler(gold)
    setPlayerMoney(source, tonumber(gold))
end

addEvent("updateMoneyClient",true)
addEventHandler("updateMoneyClient", root, updateMoneyClientHandler)

All functions are actually being called as I tried to put an outputchatbox in it. Money just isn't updating.

So what am I missing here? I assume I am doing something wrong with the baseElement as I do not quite understand them yet.

Thanks in advance.

Link to post

Dear Bartje,

welcome to the MTA scripting forums! :) I am glad to see new faces around here that nicely ask for help.

Let me help you by commenting on what you have already scripted:

10 minutes ago, Bartje said:

So I try to set the user's money to 1000 by sending it to the client. This is my client file:


function updateMoneyClientHandler(gold)
    setPlayerMoney(source, tonumber(gold))
end

addEvent("updateMoneyClient",true)
addEventHandler("updateMoneyClient", root, updateMoneyClientHandler)

All functions are actually being called as I tried to put an outputchatbox in it. Money just isn't updating.

I think you mixed up the clientside definition with the serverside definition of setPlayerMoney. For the clientside definition the first argument is not a player element but just a number with the money that the local player should have. This is because the local player does only know or care about his own money value, not other people's. Thus you can simply remove the first parameter "source" and just pass the money count.

13 minutes ago, Bartje said:

I assume I am doing something wrong with the baseElement as I do not quite understand them yet.

The source element that you pass as argument after the event name to triggerEvent-style functions is usually the element that wants to receive or has received a change. In your code you have simply specified "root" which is okay if you want to update the money of all players to the same value. But if you want to update the money of just one player...

13 minutes ago, Bartje said:

In my other server file I have the function:


function updateMoneyHandler(token)
    triggerClientEvent ("updateMoneyClient", source, 1000)
end
addEvent("updateMoney",true)
addEventHandler("updateMoney",root,updateMoneyHandler)

 

... then you have to further adjust this code. The first argument to triggerClientEvent can be a player element that should receive the event. You probably want to limit this to the person that actually logged in. Otherwise even non-logged in players would randomly receive the 1000 gold.

- Martin

  • Like 1
Link to post
Posted (edited)

Thanks! I used to play MTA way back. I have a full time job as a front-end web developer and saw this as a nice opportunity to play around.

Setting the playermoney works now with your solution, thanks for that. I also just found out there is a server-side setPlayerMoney function as well.

About the player element. I changed my first trigger to:

triggerEvent ("updateMoney", client)

In the following code, what would root be in this case?

function updateMoneyHandler(token)
  
    triggerClientEvent ("updateMoneyClient", source, 1000)
end
addEvent("updateMoney",true)
addEventHandler("updateMoney",root,updateMoneyHandler)

Should I change this to resourceRoot instead?

Edited by Bartje
Link to post
14 minutes ago, Bartje said:

Thanks! I used to play MTA way back. I have a full time job as a front-end web developer and saw this as a nice opportunity to play around.

Setting the playermoney works now with your solution, thanks for that. I also just found out there is a server-side setPlayerMoney function as well.

I am glad to be of help! It is especially nice to see experienced developers around here. 😉

14 minutes ago, Bartje said:

In the following code, what would root be in this case?


function updateMoneyHandler(token)
  
    triggerClientEvent ("updateMoneyClient", source, 1000)
end
addEvent("updateMoney",true)
addEventHandler("updateMoney",root,updateMoneyHandler)

Should I change this to resourceRoot instead?

I recommend a read of the wiki's event system info for the full details. But in your case the "root" means to listen to the "updateMoney" event triggers on all elements in the MTA element tree. Thus if you were to execute...

triggerEvent("updateMoney", resourceRoot)

your server-local event would also fire. But if you were to use "resourceRoot" for the addEventHandler call instead then executing the above code on another resource would not trigger your event handler. The BIG BUT is: executing...

triggerEvent("updateMoney", root)

does trigger the event handler in both of the above cases. To improve the robustness (not security!) of your resource you can set the propagate argument of addEventHandler to false.

  • Like 1
Link to post
33 minutes ago, The_GTA said:

I recommend a read of the wiki's event system info for the full details. But in your case the "root" means to listen to the "updateMoney" event triggers on all elements in the MTA element tree. Thus if you were to execute...

Alright. So I've got it to work and tested it on two clients at the same time. Works fine. But I still wonder if there is any way to improve this. My currently working code is as followed:

 

server-1.Lua

triggerEvent ("updateMoney", client, token)


server-2.Lua

function updateMoneyHandler(token)
    local query =  exports.mysql:_Query("select gold from accounts where token = ?", token)
    local gold = 0
    for rid, row in ipairs (fromJSON(toJSON(query))) do
        gold = row['gold']
    end
    triggerClientEvent ("updateMoneyClient", source, gold)
end
addEvent("updateMoney",true)
addEventHandler("updateMoney",root ,updateMoneyHandler)

Especially this part is what I am worried about. the 'root' seems to overkill to me, but I still can't find another way to get this to work.

 

client.Lua

function updateMoneyClientHandler(gold)
    setPlayerMoney(tonumber(gold))
end

addEvent("updateMoneyClient",true)
addEventHandler("updateMoneyClient", localPlayer, updateMoneyClientHandler)

 

 

Link to post
15 minutes ago, Bartje said:

server-2.Lua


function updateMoneyHandler(token)
    local query =  exports.mysql:_Query("select gold from accounts where token = ?", token)
    local gold = 0
    for rid, row in ipairs (fromJSON(toJSON(query))) do
        gold = row['gold']
    end
    triggerClientEvent ("updateMoneyClient", source, gold)
end
addEvent("updateMoney",true)
addEventHandler("updateMoney",root ,updateMoneyHandler)

Especially this part is what I am worried about. the 'root' seems to overkill to me, but I still can't find another way to get this to work.

  • line 4: fromJSON(toJSON(query)) ? really? 😁 Why don't you just use ipairs? In case query is false then you just check for that error condition before the loop.
  • if your token is a key to the accounts table then you can improve it to...
function updateMoneyHandler(token)
    local query =  exports.mysql:_Query("select gold from accounts where token = ?", token)
    if not (query) then outputDebugString("failed to query for account gold") return end
    local gold = query[1].gold;
    triggerClientEvent (source, "updateMoneyClient", root, gold)
end

Change in line 5: This way the only client that receives the gold is the element that you triggered "updateMoney" for.

Also: I have no idea in what context you call triggerEvent with "updateMoney" and the client parameter so I am just going to assume that you know what the client global variable is and how to use it.

EDIT: also change the client.Lua to...

function updateMoneyClientHandler(gold)
    setPlayerMoney(tonumber(gold))
end

addEvent("updateMoneyClient",true)
addEventHandler("updateMoneyClient", root, updateMoneyClientHandler)

I did not realize that you also changed that part of the code.

Edited by The_GTA
Link to post
5 minutes ago, The_GTA said:
  • line 4: fromJSON(toJSON(query)) ? really? 😁 Why don't you just use ipairs? In case query is false then you just check for that error condition before the loop.
  • if your token is a key to the accounts table then you can improve it to...

Hehehe this is, definitely not final. Still learning all the Lua basics so I've been playing around to get things to work.

Thanks for your help. Everything seems clear to me now.

  • Like 1
Link to post

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