PDA

View Full Version : SafeGivePlayerMoney - What is it for?


HondaCBR
01/01/2012, 12:51 PM
hello I found safegiveplayermoney function:

//forward

forward SafeGivePlayerMoney(playerid, cash);


//usage

SafeGivePlayerMoney(playerid, 1000);


//stock

stock SafeGivePlayerMoney(playerid, cash)
{
PlayerInfo[playerid][pCash] = PlayerInfo[playerid][pCash] += cash;
return 1;
}

My question is, what is this for? Is this some kind of an anticheat? So the only way to give money is buy getting cash and giving player ammount to his cash? Should I use this insted of all the GivePlayerMoney functions?

Do I need something that will check if someone received money in a different way? (So he can get auto banned)

PowerPC603
01/01/2012, 01:10 PM
This is server-sided money so it's an anti-money cheat too.
You could also use a timer that updates a player's money onscreen by the value stored on the server.

Since there are hacking tools available that modify the client-sided money, you would get rich people in no-time.
If you have a server which has houses or something else that's expensive and you would use GetPlayerMoney, it gets the money from the client.
If you have a money-cheater, he could buy everything immediately without working for it.

In case you use this server-sided money and check if he has enough money in his account (PlayerInfo[playerid][pCash] instead of using GetPlayerMoney), he can cheat all he wants, your server will still say he has not enough money, even if he could freeze and set his client-money to $1.000.000.000.

Banning him shouldn't be needed, as your server can use a timer to update the player's client-money every second or so.
Even if he hacks the money, the server will overwrite the client-money and his cheat is cancelled anyway.


// This callback gets called when the server initializes the filterscript
public OnFilterScriptInit()
{
// Start the global money timer, which updates the player's money and score every 500ms
SetTimer("GlobalMoneyTimer", 500, true);

return 1;
}

// This is the global money-timer
// It updates the player's money and score
forward GlobalMoneyTimer();
public GlobalMoneyTimer()
{
// Loop through all players
for (new playerid; playerid < MAX_PLAYERS; playerid++)
{
// Check if the player is still connected
if (IsPlayerConnected(playerid))
{
// Reset the player's money and set it to the stored value in the player's account (do the same for scorepoints)
ResetPlayerMoney(playerid);
GivePlayerMoney(playerid, APlayerData[playerid][pCash]);
SetPlayerScore(playerid, APlayerData[playerid][pScore]);
}
}
}

This is what I use in my own admin-script.
As you see, the timer runs every 500milliseconds (twice per second), it overwrites the client-money by the value stored on the server.
Hacking money is impossible this way.

Even if they succeed (which is unlikely), use the "PlayerInfo[playerid][pCash]" to check if he has enough money instead of GetPlayerMoney.

HondaCBR
01/01/2012, 02:58 PM
right cheers, i will defenitly use this, but the 0.5s money update, will this not lag the server when we get involved with a lot of people playing?

And why are you updating score? Is there a score cheat too?

EDIT: right I tried it, and when I used a command to give me money without doing pCash, just giving me money GivePlayerMoney, it gave me it. :/

Basssiiie
01/01/2012, 04:11 PM
The timer is useless. Just use this:
stock SafeGivePlayerMoney(playerid, cash)
{
PlayerInfo[playerid][pCash] += cash;
ResetPlayerMoney(playerid);
GivePlayerMoney(playerid, PlayerInfo[playerid][pCash]);
return 1;
}
;)


Edit: And SafeGetPlayerMoney, since people can still cheat if you use the regular GetPlayerMoney.
stock SafeGetPlayerMoney(playerid)
{
return PlayerInfo[playerid][pCash];
}

BigETI
01/01/2012, 04:35 PM
You know that you can also hook functions:

stock SS_GivePlayerMoney(playerid, cash)
{
PlayerInfo[playerid][pCash] += cash;
ResetPlayerMoney(playerid);
GivePlayerMoney(playerid, PlayerInfo[playerid][pCash]);
}
#define GivePlayerMoney(%0) SS_GivePlayerMoney(%0)

stock SS_GetPlayerMoney(playerid) return PlayerInfo[playerid][pCash];
#define GetPlayerMoney(%0) SS_GetPlayerMoney(%0)

Then somewhere in your script
Example:
//....
GivePlayerMoney(playerid, 100);
new str[32];
format(str, sizeof(str), "You have now %d$.", GetPlayerMoney(playerid));
SendClientMessage(playerid, 0xFF0000FF, str);
//...
Now it will give and get server side money.

BigETI
01/01/2012, 07:44 PM
Didn't thought about the ALS methode.
Anyways thanks!

PowerPC603
01/01/2012, 08:14 PM
right cheers, i will defenitly use this, but the 0.5s money update, will this not lag the server when we get involved with a lot of people playing?

And why are you updating score? Is there a score cheat too?

EDIT: right I tried it, and when I used a command to give me money without doing pCash, just giving me money GivePlayerMoney, it gave me it. :/

Your timer isn't running in that case.
Just tested the same thing here with giving myself $1000.

The money was counting up, but immediately went down again to the money I had before.
So the timer is resetting my money to the value stored on the server.

Have you started the timer properly? The code I provided used OnfilterscriptInit, but you might be using it in your gamemode, so you need to use OnGameModeInit to start the timer.
You could debug the timer by adding a print statement to see if it runs.

There might be a score cheat (I'm not sure), but I added it anyway just in case.

Your server won't be lagging because of the 0.5s timer. It's only setting 2 values per player, that's not much.
European Trucking has the same timer and it runs smooth with 75 players online.

That server also runs a BIG speedometer-timer every 0.5s for all players too, and still no lag.
That timer updates the speed-readout and fuel-status textdraws, does anti-hack stuff, does 100 distance-checks on speed-camera's to see if a player is speeding and alot more). And that runs for all players too every 0.5s.

And several other timers as well (1s timers).



The timer is useless.

Why would the timer be useless?
It runs perfectly on all servers that use PPC_Trucking.

What if a hacker would succeed in hacking his money and freezing his money onscreen?
When he wants to buy something, he'll always get the message that he doesn't have enough money (as the script checks the server-sided money).
He won't know how much money he really has, since he hacked the money and the value on his screen is incorrect.
The timer just makes sure that he sees the correct amount of money all the time.

Basssiiie
01/01/2012, 08:50 PM
Why would the timer be useless?
It runs perfectly on all servers that use PPC_Trucking.

What if a hacker would succeed in hacking his money and freezing his money onscreen?
When he wants to buy something, he'll always get the message that he doesn't have enough money (as the script checks the server-sided money).
He won't know how much money he really has, since he hacked the money and the value on his screen is incorrect.
The timer just makes sure that he sees the correct amount of money all the time.
If he hacks the money, it's his own fault the counter doesn't show the real amount of money. He shouldn't hack it at all. See it as a risk of money hacking. Anyway, the money will still reset to the correct amount if the player buys or sells something. (And you use SafeGivePlayerMoney) ;)

In my opinion is such timer just a waste of memory usage.

HondaCBR
01/01/2012, 09:32 PM
Thx, I think I will use this one:


stock SS_GivePlayerMoney(playerid, cash)
{
PlayerInfo[playerid][pCash] += cash;
ResetPlayerMoney(playerid);
GivePlayerMoney(playerid, PlayerInfo[playerid][pCash]);
}
#if defined _ALS_GivePlayerMoney
#undef GivePlayerMoney
#else
#define _ALS_GivePlayerMoney
#endif
#define GivePlayerMoney(%0) SS_GivePlayerMoney(%0)

The best thing is by having it, you just do your script normaly using GivePlayerMoney.

Thx everyone.

HondaCBR
01/01/2012, 09:53 PM
The code above, doesnt really work for me.

It changes the money you can see but the acctual money saved in the file stays the same.

This is what I use when you spawn: ResetPlayerMoney(playerid);
GivePlayerMoney(playerid,PlayerInfo[playerid][pCash]);
CurrentMoney[playerid] = PlayerInfo[playerid][pCash];
And it works fine.

But when I try this command
if(strcmp(cmd, "/money", true) == 0)
{
GivePlayerMoney(playerid, 30000);
return 1;
}
I can see at the top 30k more, but in /stats and when I leave and come back I have exactly same ammount as before.

Basssiiie
01/01/2012, 09:59 PM
The code above, doesnt really work for me.

It changes the money you can see but the acctual money saved in the file stays the same.

This is what I use when you spawn: ResetPlayerMoney(playerid);
GivePlayerMoney(playerid,PlayerInfo[playerid][pCash]);
CurrentMoney[playerid] = PlayerInfo[playerid][pCash];
And it works fine.
Just save PlayerInfo[playerid][pCash] into the file then. Now you have two variables with exactly the same amount in them, just a waste. :P


But when I try this command
if(strcmp(cmd, "/money", true) == 0)
{
GivePlayerMoney(playerid, 30000);
return 1;
}
I can see at the top 30k more, but in /stats and when I leave and come back I have exactly same ammount as before.
Make sure the SS_GivePlayerMoney code is above all the other code, maybe even before OnGameModeInit. Because GivePlayerMoney isn't defined correctly before you use the define we gave you. ;)

HondaCBR
01/01/2012, 10:05 PM
It saves when you leave, and /stats show you PlayerInfo[playerid][pCash], so when it sets your cash += whateverm it should also change in stats.

Basssiiie
01/01/2012, 10:16 PM
Can you show us the script of your /stats command?