FlorinSzasz Posted November 19, 2023 Share Posted November 19, 2023 Hi everyone! I am working on an anti-cheat resource for my server. I wonder what method should i use ? - make a timer and loop through all players for money,xp, x,y,z, and check with db data and so on... (i call the db once for data and i will use a formula for checks )! - or make a timer for every player on the server and the apply the same things! *Note: my server is not up (hosted), at first i plan to have at least 50 slots. Maybe later if i will have players i will go to 100 / 150 / 200 and so on if i need to. Which method will be better for long term if there will be more players. Link to comment
Moderators IIYAMA Posted November 19, 2023 Moderators Share Posted November 19, 2023 2 hours ago, FlorinSzasz said: I wonder what method should i use ? Preventing is better than checking for unusual values. Especially when you can't don't keep track of how they have been changed. This could have been done by an exploit instead of real cheats. I personally consider exploiting almost cheating, since the developers should be responsible to deliver decent code. Back to the subject: Value changes in databases are often done by user input. This should be your primary objective. For example if you have a marker that opens a GUI to transfer money: addEvent("onPlayerTransferMoney", true) addEventHandler("onPlayerTransferMoney", resourceRoot, function (marker, transferAccountId) -- Possible cheating? = hard returns if not isElement(marker) then return end local playerX, playerY, playerZ = getElementPosition(client) local markerX, markerY, markerZ = getElementPosition(marker) if getDistanceBetweenPoints3D ( playerX, playerY, playerZ, markerX, markerY, markerZ ) > 10 then return end -- More user friendly returns if not checkPassiveTimer("event:onPlayerTransferMoney", client, 1000) then return outputChatBox(client, "You can only transfer money every 1 sec.") end -- Source code: https://wiki.multitheftauto.com/wiki/CheckPassiveTimer if not transferAccountId then return end -- resume operations -- end) Check if marker exist Check if player is close enough to the marker Limit execution speed (else users can create database lag by spamming the UI button) Building an anti cheat system to check for anomalies in your database should be a secondary objective. In this case you could start with defining limits. For example a money limit. A soft limit to detect possible cheating and a hard limit to define the impossible. For a soft limit you only report to yourself, as it might be very active player. And for a hard limit, you could for example freeze the money. In this case you could inform the user that you are investigating the issue. > As you might not know if the user itself is responsible for the anomaly or if another user is responsible. That user could also be helpful in finding/knowing the exploit that is responsible for the anomaly. 1 Link to comment
FlorinSzasz Posted November 19, 2023 Author Share Posted November 19, 2023 27 minutes ago, IIYAMA said: Preventing is better than checking for unusual values. Especially when you can't don't keep track of how they have been changed. This could have been done by an exploit instead of real cheats. I personally consider exploiting almost cheating, since the developers should be responsible to deliver decent code. Back to the subject: Value changes in databases are often done by user input. This should be your primary objective. For example if you have a marker that opens a GUI to transfer money: addEvent("onPlayerTransferMoney", true) addEventHandler("onPlayerTransferMoney", resourceRoot, function (marker, transferAccountId) -- Possible cheating? = hard returns if not isElement(marker) then return end local playerX, playerY, playerZ = getElementPosition(client) local markerX, markerY, markerZ = getElementPosition(marker) if getDistanceBetweenPoints3D ( playerX, playerY, playerZ, markerX, markerY, markerZ ) > 10 then return end -- More user friendly returns if not checkPassiveTimer("event:onPlayerTransferMoney", client, 1000) then return outputChatBox(client, "You can only transfer money every 1 sec.") end -- Source code: https://wiki.multitheftauto.com/wiki/CheckPassiveTimer if not transferAccountId then return end -- resume operations -- end) Check if marker exist Check if player is close enough to the marker Limit execution speed (else users can create database lag by spamming the UI button) Building an anti cheat system to check for anomalies in your database should be a secondary objective. In this case you could start with defining limits. For example a money limit. A soft limit to detect possible cheating and a hard limit to define the impossible. For a soft limit you only report to yourself, as it might be very active player. And for a hard limit, you could for example freeze the money. In this case you could inform the user that you are investigating the issue. > As you might not know if the user itself is responsible for the anomaly or if another user is responsible. That user could also be helpful in finding/knowing the exploit that is responsible for the anomaly. I dont allow players to spam the db or something with anything in any script i wrote! I just want to know if i should use a timer and loop through all players when i check some things like money and xp and other or use a timer for every player, i dont want to tank the server performance. Even if this are the only timers /timer which will run. As an example you login, i get the data for now only money from db and have it stored in a table. I want to see your money every 20 - 30 seconds and from 1000$ you go to 999999999$ something is wrong. 1 Link to comment
Moderators IIYAMA Posted November 19, 2023 Moderators Share Posted November 19, 2023 20 minutes ago, FlorinSzasz said: I want to see your money every 20 - 30 seconds and from 1000$ you go to 999999999$ something is wrong. If you are worrying about performance, in that case you might consider using MySQL triggers. Those are as close as it gets to your db, making sure you do not cause overhead and align the value-checks with the update moments. https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html Create a value-check table / rollback table: Stores the value that it is being incremented (within 30 seconds) Stores the future time, when elapse the incrementing value can be ignored and resets to 0 Create a trigger which triggers on update Do behaviour of value-check table. If the value jumps too much UP: Report to a separate table Freeze account Rollback manually / automatic (not recommended) 1 Link to comment
FlorinSzasz Posted November 19, 2023 Author Share Posted November 19, 2023 21 minutes ago, IIYAMA said: If you are worrying about performance, in that case you might consider using MySQL triggers. Those are as close as it gets to your db, making sure you do not cause overhead and align the value-checks with the update moments. https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html Create a value-check table / rollback table: Stores the value that it is being incremented (within 30 seconds) Stores the future time, when elapse the incrementing value can be ignored and resets to 0 Create a trigger which triggers on update Do behaviour of value-check table. If the value jumps too much UP: Report to a separate table Freeze account Rollback manually / automatic (not recommended) Thx is somehow close to what i meant. 1 Link to comment
MTA Anti-Cheat Team Dutchman101 Posted November 20, 2023 MTA Anti-Cheat Team Share Posted November 20, 2023 For every aspect of things a cheat/lua injector can result in, there is specifically tailored ways to prevent it. Scripters with a good sense of security-by-design can do so much more than follow basic "Script security" guidelines that apply mostly to triggers and such. In case of player money, there should be a solid foundation (before anything else) that consists of not using GTA money as the truth/unit, but handle anything to do with money by yourself using your account system that operates through SQL database. At any time a player does anything that can lead to money increasing, being given or deposited, it has to happen through a trigger handling the event (context in which the player experiences a money change). Secure your triggers (also read https://wiki.mtasa.com/wiki/Script_security) and you're done. It's important to understand that as part of it, you are redefining money: i repeat, do not use GTA money. Use a field in your SQL database that defines the unit money, and it's an entire different virtual entity than GTA money. Obviously, also avoid using elementdata to store or update player money. Of course, even when you incorporate my suggestions on how to handle money different in an integral way, extra checking like explained by @IIYAMA is a good stick behind the door, in case someone manages to find and exploit a script security flaw in your triggers. @FlorinSzasz 1 1 Link to comment
pixel77 Posted November 26, 2023 Share Posted November 26, 2023 And what if a cheater is flying or creating explosions, or changes other players positions, teleporting to other players with setElementPosition? @Dutchman101 Link to comment
FlorinSzasz Posted November 26, 2023 Author Share Posted November 26, 2023 17 minutes ago, pixel77 said: And what if a cheater is flying or creating explosions, or changes other players positions, teleporting to other players with setElementPosition? @Dutchman101 This is very simple check for distances how far he should travel by foot/car/ plane in a certain time and check with timers and if something is not right bang. Well if u have teleports you have to check if the player used a command or not. Link to comment
Mtaowner Posted November 27, 2023 Share Posted November 27, 2023 This is impossible. Regarding measuring distances: this is very funny. What if you're flying fast and crash into a wall? you will get banned. Even the slightest deviation of the trajectory, which cannot be tracked in any way and is not even visible to eye, can give an advantage to cheater. Link to comment
pixel77 Posted November 27, 2023 Share Posted November 27, 2023 Yes, or jump out of a plane/helicopter, or jump off the roof. But what about explosions? Link to comment
FlorinSzasz Posted November 27, 2023 Author Share Posted November 27, 2023 4 hours ago, Mtaowner said: This is impossible. Regarding measuring distances: this is very funny. What if you're flying fast and crash into a wall? you will get banned. Even the slightest deviation of the trajectory, which cannot be tracked in any way and is not even visible to eye, can give an advantage to cheater. well even if you fly with hydra u wont be much faster than an infernus with max speed + nos in flat line in 30 seconds time so yeah. I tested the distances in best case the player will have on my server but they wont have that case 99.9% of time. The anti-cheat has to be 100% server side. You have to get creative when you make it, also you have to make it to work on your gamemode, for e.g my anti-cheat wont work on your gm. 2 hours ago, pixel77 said: Yes, or jump out of a plane/helicopter, or jump off the roof. But what about explosions? Well you disable them short term. For long term you have to think when most of the explosions take place so you make the code work right. Link to comment
pixel77 Posted December 12, 2023 Share Posted December 12, 2023 How did you solved the distance measurement on server side? With timers? Link to comment
FlorinSzasz Posted December 12, 2023 Author Share Posted December 12, 2023 24 minutes ago, pixel77 said: How did you solved the distance measurement on server side? With timers? You need a table with all players location and then you loop through all players who are in server and check were they are now and get the distance between points and thats it. There is a limit how far they can go in a certain time like 10s 20s or 30s if they go to far in that time they are out. Also if player dies you should update the location in that moment not after timer resets. Link to comment
pixel77 Posted December 13, 2023 Share Posted December 13, 2023 I see. Thanks. And if I am right, there is nothing against xray/wallhack?! Link to comment
FlorinSzasz Posted December 13, 2023 Author Share Posted December 13, 2023 3 hours ago, pixel77 said: I see. Thanks. And if I am right, there is nothing against xray/wallhack?! if i remember correctly the AC has built in things which can detect some wall hacks if not most of them. If you think someone has xray / wallhack use this for weapons https://wiki.multitheftauto.com/wiki/GetPedWeaponMuzzlePosition and add a 3d line to it to see where they aim. 1 Link to comment
Moderators IIYAMA Posted December 16, 2023 Moderators Share Posted December 16, 2023 On 13/12/2023 at 17:50, FlorinSzasz said: and add a 3d line to it to see where they aim. Bullets do not start from the weapon Muzzle position. The start position is: https://wiki.multitheftauto.com/wiki/GetPedTargetStart And the end position: https://wiki.multitheftauto.com/wiki/GetPedTargetEnd Both can be used to create a vector for the line you are referring to. This is related to the reason why people can shoot around corners without showing more than their elbows. Since the bullets start more to the right of the weapon. 1 Link to comment
pixel77 Posted December 19, 2023 Share Posted December 19, 2023 But it is not relevant, because cheaters can see all of the bones position through walls, without weapon too. Link to comment
FlorinSzasz Posted December 19, 2023 Author Share Posted December 19, 2023 6 hours ago, pixel77 said: But it is not relevant, because cheaters can see all of the bones position through walls, without weapon too. even if they bypass the anti-cheat when it comes to wall hack somehow it wont be usefull at all because if they dont gain any benefit from that only in a dm zone or gamemode and thats all. When they dont have any weapon in hand the wall hack from my point of view wont bring any advantage. Link to comment
pixel77 Posted December 20, 2023 Share Posted December 20, 2023 By the way the https://wiki.multitheftauto.com/wiki/Script_security#Securing_triggerServerEvent article is changed not a long time ago. The old triggerServerEvent validating still working or not? The old validation method server side: addEvent("onRaiseTheRoof", true) addEventHandler("onRaiseTheRoof", resourceRoot, function(arg1, arg2) -- Check data is coming from a client if client then -- The source for this event is always 'resourceRoot' if source ~= resourceRoot then reportNaughtyness( eventName, client, "source" ) return end -- arg1 should be the player if arg1 ~= client then reportNaughtyness( eventName, client, "arg1" ) return end -- arg2 should be between 1 and 100 if arg2 < 1 or arg2 >100 then reportNaughtyness( eventName, client, "arg2" ) return end end -- -- Do usual code for 'onRaiseTheRoof' -- end ) -- Helper function to log illegal things function reportNaughtyness( eventName, client, reason ) -- Report outputConsole( "Possible rogue client!" .. " client:" .. tostring(getPlayerName(client)) .. " eventName:" .. tostring(eventName) .. " reason:" .. tostring(reason) ) end Link to comment
Moderators IIYAMA Posted December 20, 2023 Moderators Share Posted December 20, 2023 6 hours ago, pixel77 said: The old triggerServerEvent validating still working or not? It does. The new method is a utility function, which does everything for you. But also for some parts it forces you to be more strict. For example the: protectedKeys table part. 6 hours ago, pixel77 said: -- The source for this event is always 'resourceRoot' if source ~= resourceRoot then reportNaughtyness( eventName, client, "source" ) return end For resourceRoot you can also block this, instead of reporting. Saves you some lines of code. addEvent("onRaiseTheRoof", true) addEventHandler("onRaiseTheRoof", resourceRoot, function(arg1, arg2) end, false) -- propagate disable, making sure only resourceRoot can be passed as the source 1 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