mojira.dev
MC-90024

onground assumed wrongly

onground only depends on y translation, and therefore can be set to true even when x,z translation moves the entity off of the ground.

Solution: recheck onground after the move is complete so that the next move does not allow ground-based interaction (jumping, etc.) when the entity really isn't on the ground.


This is a client-side issue. The client calculates onground immediately after the Y portion of a move, which occurs before X and Z. This means that a move can (and often does) move a player off of a block and into midair, while the client still thinks it's onground. Since onground is only calculated during a move, this means that the next move will behave like it's on the ground and will allow jumping even though the client is in midair.

This is nearly impossible to see visually, but it translates to odd movement mechanics server-side making anticheat systems use convoluted workarounds ("player COULD have hit the ground during the Y portion of this move so they might not be cheating").

Linked issues

Comments 8

Am I understanding this right: The server doesn't update onground for players when they only move in x and z directions, malicious clients can abuse this?

This is a client-side issue. The client calculates onground immediately after the Y portion of a move, which occurs before X and Z. This means that a move can (and often does) move a player off of a block and into midair, while the client still thinks it's onground. Since onground is only calculated during a move, this means that the next move will behave like it's on the ground and will allow jumping even though the client is in midair.

This is nearly impossible to see visually, but it translates to odd movement mechanics server-side making anticheat systems use convoluted workarounds ("player COULD have hit the ground during the Y portion of this move so they might not be cheating").

Here's an example that shows the bounding boxes during a series of movements. In this example, the player is moving right to left, and is bunnyhopping onto the slabs and into midair where the trace ends.

https://i.gyazo.com/644b9a70b60902ad780a325602e2d3ed.png

You will notice that the player never actually lands on the slab (second box from the left), but still jumps into the air (the far left bounding box). This is because when the move is actually being made, Y translates first from the position of the previous move, and the player collides with the slab setting onground to true. Then, X and Z happen which translate the player off of the slab and into midair without rechecking onground afterwards.

Is there a way to observe this behavior in vanilla? No worries, the report is staying open, but I'd like to confirm it myself.

It might be observable in third person view with video recording and slow motion play back, consider items with speed modifiers on πŸ™‚. Logging the packet contents/positions and onground state will be more promising, though that needs mods or access to the original code, rather πŸ˜›.

The onground information seems to actually state "this move touched ground", allowing to jump next move. With the player having moved off ground due the x-z-move still being processed after vertical (downwards) collision, this may appear like the player jumping from a (seen statically) in-air position on server side.

Now this needn't be such a great issue in theory, as the player somehow "covered ground" with the last intended move, but it does complicate things on server side, if you attempt to detect cheating, and we don't have any information about what the client actually has calculated (did the x/y/z part of the intended move collide with anything, thus got shortened?), disregarding specialties like stepping up something right now.

Can't judge if it is better to keep as is, extend the protocol by flags (such as x/y/z collided, stepped up, whatever the client did roughly), or if the actual ground position to send to the server should always be (re-) calculated using the resulting position.

The latter makes a lot of sense, as it makes checking stuff server-side much easier and i also assume that the moving shouldn't feel worse/much different. Has this ever been considered?

I assume that it is somewhat "harder" to calculate, because you would have to calculate the distance to ground for the resulting position or use some margin (the latter possibly resulting in other odds and ends), instead of the simple collision with the y-part of a move.

asofold is the project lead of NoCheatPlus of which I am a team member. We call this phenomenon "lostground" internally, and an unfortunate amount of time gets spent trying to account for it.

Unfortunately, there isn't a simple way to replicate this without logging packets, positions each tick, etc. It took me quite some time to figure out exactly what was causing this, initially thinking it was an issue with how Bukkit fired move events.

The solutions asofold suggested above would allow us to more accurately detect and prevent movement exploits. Additionally, if you look at my other open issues, there are other, somewhat related issues that also directly affect our ability to provide quality anticheat software to the multiplayer community πŸ™‚

An easy way to notice it in 15w41b:
-Load a world (Solo) and make sure you are the only player on it
-Place a command block with "/testfor @a {OnGround:1b}
-Set the command block to "Repeat" and "Always Active"
-Place a comparator next to the command block so it can test the result

This setup is made for testing the player's tag OnGround.

Now, you need to jump without moving horizontally. The comparator should not turn on, even though you are on the ground.

Is this still an issue in the most recent versions (currently that is 1.12.2, or the latest 1.13 development snapshot 18w07c) of Minecraft?

Ice

(Unassigned)

Unconfirmed

Minecraft 1.8.8, Minecraft 15w41b

Retrieved