kkthxbye-code/csgo_bugs

Hitbox misalignment between client & server

Closed this issue · 4 comments

Hitboxes desync between the client and server in these scenarios:

-Players appearing out of dormant state: The server does not network the player velocity or any of the animation state information when first networking a client to a player. This causes the velocity on the client to be clamped due to a 'teleport' since the server did not network the player position while they were dormant, resulting in the player's upper and lower body as well as legs to not match the server for a number of ticks. Also players appearing out of dormant state while jumping is desynced in this case as the server does not network the amount of time the player was in the air. There are also other cases where this breaks hitbox sync but they are minor.

-Players standing on conveyer belts and moving objects: The server does not network the base velocity of the surface they are standing on, resulting in the client predicting their position incorrectly resulting in major judder and teleporting when standing on conveyer belts and other custom levels involving moving objects

-Players turning around quickly: The client runs code to allow the legs to smoothly shift into place in the function called DoExtraBoneProcessing while the server does not, resulting in the leg & feet hitboxes always being desynced from the server when a player is turning around.

EXAMPLE and USER-MADE FIX for the following issue: https://www.youtube.com/watch?v=hL3gxRv_5Jk
-Players who do not have a frame rate at least as high as the server tickrate, those using cheats, or when experiencing packet loss results in complete hitbox desync up to 58 degrees away from the server hitbox in either direction: When clients do not send usercmds to the server at a constant rate (one per tick), the server will run all of the usercmds that the client sent in sequence. Each usercmd will get simulated by the movement code and then animated by the server's animation code. After all usercmds are finished running, the server will network the new player position and viewangles to other clients. Since the server only networks the newest information to other clients, they do not animate the missing data that the server did, resulting in desynced hitboxes in every single case, such as running, jumping, turning, firing, reloading, flashbang animations, crouching, and more. The hitbox is not usually desynced enough by a legitimate client to cause the hitbox to be desynced such a large amount as a cheat can, but there ARE edge cases where this can happen. The solution to this bug is to have the server only animate the final usercmd sent by clients. The server will still run movement code, but only the final one will be animated and sent to other players. The client code will still interpolate the player models resulting in a smoother appearance but the hitboxes will actually line up with the server in the vast majority of cases. There is no reason for the server to animate every usercmd as it will still appear as a laggy and teleporting player (depending on how many usercmds are being held back by the player) to other people. The server should also do a verification on all of the sent usercmd tickcounts prior to running them to filter out invalid ones so that clients cannot maliciously prevent their player from being animated.

Players appearing out of dormant state are ALWAYS desynced, cheating or not. Read the code in the animstate code on the leaked 2018 source code of csgo. Place a breakpoint in the code when players come out of dormant state. You will see that the position of the player is from their last networked location (possibly across the entire map). Instead of networking the velocity and using this for animating, they take the distance between the current position and the last networked position, clamp it and set that as their velocity. This results in the players having the run animation at full speed, even if they are not moving or are slowly moving. This will take about 2 seconds to finally sync with the server because of the way the code is written to gradually slow down and ramp up player velocity. And since the server does not network the amount of time players were in the air, players who are jumping or falling while being dormant and then not dormant will have a desynced hitbox until the player hits the ground, finishes the animation and then idles or jumps again.

Also, your sv_pure bypass 'fixes' will never be truly fixed unless valve actually adds a heartbeat to the sv_pure file checks. The code is completely useless and anyone with a brain can bypass it with 1 line of code injected into the game

Please stop bickering, especially you @szmarczak

@click4dylan @swoopae

A couple of things.

This repo is still mostly for my own gratification, but you are more than welcome to give input and make pull requests. However, the repo does not contain any exploits that require injection or memory modification, and this is very much on purpose. This is not because I think valve shouldn't do anything about cheaters, but for whatever reason they have mostly given up on client-side cheat detection and instead focus on trustfactor and overwatch+vacnet. As the recent coaching scandal have shown, players love to (what I call) legit cheat; that is, exploiting bugs in the game to get a competitive advantage, but without the inherent risk of injecting or modifying memory. This is the entire reason I find these bugs fun to discover.

I realize that the bug you are describing is not solely exploitable by using cheats, but I've read all the replies in the two issues and the pull-request, and I have seen no reproduction steps that would provide a net advantage. Limiting FPS to less than the server tickrate might indeed manifest the bug, but I don't really see how it could give a net advantage. If I understand your description correctly, running at 32 FPS on a 64 tick server, would make the most recent frame be animated incorrectly when replicated to other clients. Exploiting this without cheating seems hard. Even playing at a low FPS, I would guess that you would have to literally spin around to make the animation difference large enough to be noticable, and the disadvange from playing with low fps would by far outweigh the benifit of a slight desync in animation state. Please correct me if my understanding is wrong.

Lastly, this is not some magic repo that Valve reads, at least to my knowledge. Exploits that gets posted here are fixed because of one of two reason:

  • Because a big youtuber/twitter user sees them and makes a video. If you have no way to show a way of abusing this to get a competitive advantage by "legit cheating", no one is gonna make such a video, as it just wont get the views.

  • Because I email them to the devs. My recommendation would be to email the complete description and the suggested fix to the developers. I have gotten most of my responses from Vitaliy (mcjohn has also responded in the past), so I would suggest mailing them directly as I have never gotten a response from the csgoteamfeedback email.

The bug you have documented is indeed something that should be fixed, I'm just not sure it fits in this repo. If you can make a reproduction case that does provide an advantage without injecting, I will be glad to accept it (it doesn't have to be great, it could be something like a way to desync your angle by a large amount while defusing). Otherwise emailing the devs would be the optimal way.

Great work on documenting the bug and the fix you made, I hope they fix it.

Hey, thanks for the response.

Pretty sure @click4dylan emailed them hundreds of times, I also did. The thing is I feel this fits perfectly here because we're telling Valve how to fix it, with full code snippets, and this repo gets attention from YTers. Over the years Valve showed close to no interest in fixing this so, at least for me, it's a last ditch effort posting here.

Pretty sure there's also an issue on Valve's official github for csgo issues or whatever but they simply don't care about it.

Thanks for understanding.

I'll close this, as there has been no response from the creator. Feel free to submit a pull request with a working PoC and I'll accept it.