mojira.dev
MC-123364

Player-in-block checking happens after block collision events are done

The bug

The NetHandlerPlayServer.processPlayer (MCP name) function checks if the player's bounding box is intersecting any blocks, and if it is, reverts the player's position to the old one.

However, this check is done even if the player has been teleported by a portal block such as the end portal, which can lead to the following problem:

  1. A player somehow sends a move packet that places them halfway between an end portal block and an end portal frame block

  2. Even though the move is illegal, the end portal's collision function gets called and the player is teleported into the end (Bug 1)

  3. The collision checks whether the player's move was invalid and reverts the player's position, but not dimension change (Bug 2)

  4. The player is dropped into the end at their previous position, likely causing them to fall into the void and die

Doing this check before block collision functions are called (or at least also cancelling the dimension change) would solve the problem.

How to reproduce

  1. Use the following commands to make you intersect with a block and stand in front of an end portal

    /setblock ~2 ~ ~ end_portal
    /setblock ~1 ~ ~1 glass
    /execute align xz run teleport @s ~1.7 ~ ~0.700005 -60 0
  2. Walk forward
    → ❌ You enter the end but at your original position instead of on the platform

Related issues

Attachments

Comments

migrated
[media][media][media]
pokechu22

Do you have a way to reproduce this without modifying the client to send a custom packet? I know it's possible for collision to behave poorly, I'm just not aware of a concrete way to reproduce this as-is (I'd like to try to reproduce on the snapshot, where sending other packets is rather difficult)

The portals/dimension change logic is definitely broken, though (see MC-98153). Were that less broken, would this still be an issue? I'm pretty sure it would still be, as the blocks would be triggered when they shouldn't be.

migrated

Yes, I just figured it out how to do it:

1. Build this:

[media]

2. Stand on the block right next to the corner of the end portal
3. Place a bed on the block you're standing on (so that its corner touches the corner of the end portal), and you should be inside the bed block (this is another bug, I'm guessing)
4. Sneak to the left edge (in the image) of the block the bed is on
5. Once you're right at the edge, try going back into the bed block, still sneaking. You should see your player jumping backwards while you hold W as the server cancels the move events.
6. Move along the bed's edge towards the portal (at an approximately 10-20 degree angle towards the bed). Make sure you keep getting the jumps back as you move which show the collision checking code is being activated.
7. When you eventually reach the portal block, you should get teleported into the end, but at your current coordinates. It might not happen on the first attempt.

pokechu22

Thanks! Can confirm.

The trick with the bed doesn't work in the snapshots anymore, but the goal of it is just to get you stuck inside of a block slightly, which can be done other ways. Here's my setup:

  1. Build up this; note in particular the facing direction (needed for the teleport)

    [media]
  2. Push yourself into the corner of the two glass blocks

  3. Run /tp @p ~ ~ ~-.01. This should push you just barely inside the glass so that other movement is rejected

  4. Break the glass block on top of the portal

  5. Walk diagonally forward (so that you'd move "into" the other glass block)

  6. This bug should occur

marcono1234

I added reproduction steps based on what both of you provided, I hope you are fine with that.

pokechu22

Confirmed for 1.15.2; however, the command needs to be modified slightly: a teleportation of ~.700005 works for getting stuck in a block, but ~.75 no longer does. 1.14.2-pre4 changed the tolerance from 0.0625D to .00001F (this might have been related to MC-147715, but there was another change in Entity that's more likely for that). (1.14.2-pre4 changed it in one instance, while 1.14.2 proper changed a second instance and moved both into a method I now have called isPlayerNotInBlock (func_223133_a). .0625 is still used in several places though. The whole hitbox shrinking thing is pretty weird and I don't know why it's done, but at least .00001 won't cause issues similar to MC-104259).

Avoma

Can confirm in 20w51a.

Avoma

Can confirm in 21w03a.

Avoma

Can confirm in 21w05b.

Avoma

Can confirm in 1.16.5 and 21w08b.

Avoma

Can confirm in 1.17.1. Video attached.

jamesmoton

Can confirm in 22w15a.

Jeuv

Can no longer confirm in 1.21.

migrated

(Unassigned)

Confirmed

Platform

Normal

Collision, Player

collision, movement, player

Minecraft 1.12.2, Minecraft 17w50a, Minecraft 18w22c, Minecraft 1.13-pre1, Minecraft 1.13-pre2, ..., 1.17.1, 22w15a, 1.19.2, 1.20.6, 24w18a

Retrieved