Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ErrorNoHaltWithStack to alert that a players money was invalid when trying to save #3240

Merged
merged 4 commits into from
Jan 5, 2024

Conversation

lionbryce
Copy link
Contributor

Allowing people to go negative fixes 1 of the main methods of duplicating money since.

Currently, DarkRP just fails to save your money if something allowed you to go negative; this isn't inherently a problem with DarkRP as :canAfford exists, but there've been quite a few addons that make tiny mistakes allowing this to occur so we might as well not let them duplicate money

Considerations:
By default, DarkRP doesn't seem to set the "wallet" column to unsigned anywhere so no need to add any alter tables queries (unless there's a really old commit where it did that I didn't look for)

I also confirmed I was able to do the following w/o having my money reset or unexpected happening:

  • leave & immediately rejoin
  • restart the server w/o leaving (via _restart specifically)
  • leave then restart the server

@FPtje
Copy link
Owner

FPtje commented Dec 31, 2023

Thanks for the PR! This check goes way back to when I started working on DarkRP, so let's go back to 2008 for a little story.

Check out this video:
https://youtu.be/Hg0XxgwuKeA

Specifically the part that says "NO more money hack!". That is the very first version of DarkRP that I released. I made that video because I really needed to convince people to use my version over that of the then official developers of DarkRP.

That money exploit worked as follows, if you don't get it from the video:

When someone used a gunlab, it would "work" for a couple of seconds before giving you the gun and charging you for it. The owner could use those seconds to change the price of guns to 9999999999. Since the gun buying was already inevitable, the person would end up getting the gun, but also be almost 9999999999 in debt. The owner, in turn, would gain that amount of money.

Now there were several fixes to this problem. One being that the payment happens before those seconds of waiting. The other one is this very check that you're removing. The thing with debt in DarkRP, is that nothing in the game is built to deal with it. You can't buy anything, there's no mechanism to bounce back. The payday isn't going to be nearly fast enough to get someone out of debt.

Basically their game is ruined, and this ruined state is immediately persisted! This made people extremely angry, and if the admin wouldn't fix it, they would just stop playing on that server. There's nothing there for them anymore.

So yeah, the choice was made to never allow negative numbers. There are a bunch of functions to handle this nicely, like the canAfford you mentioned, but also a safe money transfer function. Addons can decide to not use those and cause duplication exploits, but that's an impossible thing to try to fix. They might as well skip storeMoney and query the DB directly to store money.

Now something could be said for throwing a big error when someone tries to store negative money. That wouldn't fix the money duplication, but it would warn the people who can fix it. The stack trace would likely hold the culprit of the problem.

I think when throwing the error, it should not cause a halt (i.e. an errorNoHalt should be used), because that would change current behavior. I can imagine an addon exists that first stores an incorrect amount of money before running some more code that then stores the correct amount of money. That would break (even further) with a halting error.

@lionbryce
Copy link
Contributor Author

lionbryce commented Dec 31, 2023

That makes total sense actually, I'll throw together a quick edit

@lionbryce lionbryce changed the title let people go negative to fix certain exploits ErrorNoHaltWithStack to alert that a players money was invalid when trying to save Dec 31, 2023
@Kefta
Copy link
Contributor

Kefta commented Jan 1, 2024

This is a moot point, but I don't think you should return the results of the error call in-case someone has overrided it to provide a return value.

Falco suggested using ErrorNoHalt in the event some addon sets players into the negatives briefly while still allowing server operators to spot that something has gone wrong and what the culprit is

May be worthwhile to split this into 3 separate errors

Also may be worth editing /setmoney to not allow it to put a player into the negatives as everytime they gain money until they end up positive it'll throw an error. Though maybe that has the benefit to server operators in a different way (ie: they have someone who has access that shouldn't)
@lionbryce
Copy link
Contributor Author

This is a moot point, but I don't think you should return the results of the error call in-case someone has overrided it to provide a return value.

As someone who recently detoured tonumber I totally agree

@FPtje
Copy link
Owner

FPtje commented Jan 4, 2024

Thanks! I've pushed some changes to this PR:

  • Use DarkRP.errorNoHalt`. This allows for a fancy explanation
  • Place details (money amount and player) in the error
  • Also implement the check for the offline money. I'm not sure why it wasn't there
  • Made sure the stack trace of some errors is 1 (and not 2, that seemed to miss an entry in the stack trace)

Here's what the error looks like when running directly:

] lua_run DarkRP.storeMoney(Player(2), -1000)
> DarkRP.storeMoney(Player(2), -1000)...
There is 1 Lua problem!
	Please check your console for more information!
	Note: This error likely breaks your server. Make sure to solve the error!
[ERROR] A runtime error has occurred in "lua_run" on line 1.
The best help I can give you is this:

Some addon attempted to store a invalid money amount -1000 for Player (FPtje) Falco (STEAM_0:0:1234567)

Hints:
	- This money amount will not be stored in the database, but it may be set in the game.
	- The database simply stores the last valid, non-negative amount of money.
	- Please try to find the very first time this error happened for this player. Then look at the files mentioned in this error.
	- That will tell you which addon is causing this.
	- IMPORTANT: This is NOT a DarkRP bug!
	- Note: The player can simply rejoin to fix their negative money, until whatever causes this happens again.

The responsibility for the error above lies with (the authors of) one (or more) of these files:
	1. lua_run on line 1
------- End of Simplerr error -------

When the error is in a function, you'll see that the two places are in the stack trace (the definition of foo and its call)

] lua_run function foo() DarkRP.storeMoney(Player(2), -1000) end foo()
> function foo() DarkRP.storeMoney(Player(2), -1000) end foo()...
There is 1 Lua problem!
	Please check your console for more information!
	Note: This error likely breaks your server. Make sure to solve the error!
[ERROR] A runtime error has occurred in "lua_run" on line 1.
The best help I can give you is this:

Some addon attempted to store a invalid money amount -1000 for Player (FPtje) Falco (STEAM_0:0:123456)

Hints:
	- This money amount will not be stored in the database, but it may be set in the game.
	- The database simply stores the last valid, non-negative amount of money.
	- Please try to find the very first time this error happened for this player. Then look at the files mentioned in this error.
	- That will tell you which addon is causing this.
	- IMPORTANT: This is NOT a DarkRP bug!
	- Note: The player can simply rejoin to fix their negative money, until whatever causes this happens again.

The responsibility for the error above lies with (the authors of) one (or more) of these files:
	1. lua_run on line 1
	2. lua_run on line 1
------- End of Simplerr error -------

[DarkRP] There is 1 Lua problem!
Please check your console for more information!

And the result for storeOfflineMoney:

] lua_run DarkRP.storeOfflineMoney(Player(2):SteamID64(), -1000)
> DarkRP.storeOfflineMoney(Player(2):SteamID64(), -1000)...
There is 1 Lua problem!
	Please check your console for more information!
	Note: This error likely breaks your server. Make sure to solve the error!
[ERROR] A runtime error has occurred in "lua_run" on line 1.
The best help I can give you is this:

Some addon attempted to store a invalid money amount -1000 for an offline player with steamID64 765611979781234567

Hints:
	- This money amount will not be stored in the database.
	- Please try to find the very first time this error happened for this player. Then look at the files mentioned in this error.
	- That will tell you which addon is causing this.
	- IMPORTANT: This is NOT a DarkRP bug!

The responsibility for the error above lies with (the authors of) one (or more) of these files:
	1. lua_run on line 1
------- End of Simplerr error -------

@FPtje FPtje merged commit c5afaaa into FPtje:master Jan 5, 2024
2 checks passed
@FPtje FPtje mentioned this pull request Feb 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants