Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-212291

Client can dismount vehicles independently from the server, causing a de-sync

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • 21w05a
    • 21w03a, 1.16.5
    • None
    • Confirmed
    • Networking
    • Important

      This bug report is a continuation of MC-202202, as it was only partially fixed in 21w03a.

      The bug

      A change in snapshot 20w22a allows the client to dismount a vehicle independently from the server, causing a de-sync between the two. This can be triggered in a variety of ways, see How to reproduce.

      When this de-sync occurs, the server will see the player as riding in the vehicle, while the client (the player) sees themselves as dismounted from the vehicle, allowing them walk around freely. Walking around and attempting to break blocks far away from the vehicle will cause vanilla anti-cheat to prevent the blocks from being broken, as the server still thinks the player remains mounted on the vehicle and cannot possibly break blocks that far. Sneaking causes the player to teleport back to the vehicle, as the server thinks the player has just dismounted the vehicle.

      This issue was initially reported as MC-202202, which observed that in snapshot 20w09a code was added to the client which allowed it to dismount a vehicle independently from the server using the sneak key. Since this caused de-sync issues during lag spikes, it was reverted in 21w03a leaving MC-202202 resolved.

      However, the implemented fix for MC-202202 in 21w03a only considered situations when the client uses the sneak key to dismount. It was also noted in MC-202202 that snapshot 20w22a added a way for clients to dismount a vehicle independently from the server during situations not caused by the sneak key, such as when the vehicle moves through a block. This discovery was only reported on MC-202202 a short amount of time before the release of 21w03a, likely being the reason why MC-202202 was not entirely fixed.

      The rest of this bug report covers the unresolved part of MC-202202, where the client can decide to dismount its own vehicle in situations not caused by sneaking, leading to a de-sync.

      Impact

      This bug leads to a de-sync between the client and the server in several scenarios during vanilla gameplay, causing undesirable behavior. Some of these scenarios in the past have been reported as their own bugs, such as MC-190454, MC-191714, MC-200286, MC-201647, and MC-205477. Fixing this bug using the proposed fix (see Code Analysis) will resolve all of these issues, as I was unable to reproduce any of them with the fix (see Workaround).

      This bug can additionally cause a de-sync on third-party servers if the server attempts to keep a player mounted on a vehicle through third-party modifications to the server software. This is a common mechanic used on minigame servers when the player must remain in a vehicle, such as a minecart on a roller coaster. While this was primarily fixed with 21w03a, situations where the client dismounts its own vehicle when not using the sneak key still cause a de-sync. For example, the client currently decides to dismount its vehicle when the vehicle moves through a block, which does not require using the sneak key, leading to a de-sync. This did not occur on versions prior to 20w22a. By implementing the proposed fix, this no longer happens and prevents buggy behavior on these third-party servers.

      How to reproduce

      We may observe the effects of this bug by looking at the other reported issues which are directly caused by this bug. See MC-190454, MC-191714, MC-200286, MC-201647, and MC-205477.

      The reproduction steps of MC-191714 are provided below, which shows this bug. When the farmland is turned into a full dirt block, the horse becomes inside the block, causing the client to decide to dismount the house and create a de-sync

      1. Join a world in Creative mode with cheats enabled using version 20w22a or higher
      2. Run the command /gamerule randomTickSpeed 0
      3. Run the command /fill ~-3 ~-1 ~-3 ~3 ~5 ~3 minecraft:glowstone hollow
      4. Run the command /fill ~-2 ~-1 ~-2 ~2 ~-1 ~2 minecraft:farmland
      5. Run the command
        /summon minecraft:horse ~ ~ ~ {Invulnerable:1b,NoAI:1b,PersistenceRequired:1b,SaddleItem:{id:saddle,Count:1},Tame:1}
        
      6. Mount the horse
      7. Jump at least 1 block in the air with the horse, so the farmland is broken and you are dismounted from the horse
        Notice the de-sync. Walking around and attempting to break blocks far away from the horse will cause anti-cheat to prevent the blocks from being broken, as the server still thinks the player remains mounted on the horse. Sneaking causes the player to teleport back to the horse, as the server thinks the player has just dismounted the horse.

      Another example of this bug can be found in MC-190454, with steps to reproduce shown below. When the husk dies, the client decides to dismount the horse, creating the de-sync.

      1. Join a world in Creative mode with cheats enabled using version 20w22a or higher
      2. Run the command
        /summon minecraft:husk ~ ~ ~ {NoAI:1b,Passengers:[{id:"minecraft:horse",Invulnerable:1b,NoAI:1b,PersistenceRequired:1b,SaddleItem:{id:saddle,Count:1},Tame:1b}]}
        
      3. Mount the horse
      4. Run the command /summon minecraft:tnt
        Notice the de-sync. Walking around and attempting to break blocks far away from the horse will cause anti-cheat to prevent the blocks from being broken, as the server still thinks the player remains mounted on the horse. Sneaking causes the player to teleport back to the horse, as the server thinks the player has just dismounted the horse.

      This bug can also be seen through MC-200286.

      1. Join a world in Creative mode with cheats enabled using version 20w22a or higher
      2. Run the command /fill ~ ~-1 ~ ~ ~-1 ~5 minecraft:obsidian
      3. Run the command /summon minecraft:end_crystal ~ ~ ~5
      4. Run the command /summon minecraft:boat ~ ~ ~2
      5. Mount the boat
      6. Row the boat forward 3 blocks or until inside the end crystal
      7. Look down and right click the boat
        Notice the de-sync. Walking around and attempting to break blocks far away from the boat will cause anti-cheat to prevent the blocks from being broken, as the server still thinks the player remains mounted on the boat. Sneaking causes the player to teleport back to the boat, as the server thinks the player has just dismounted the boat.

      Code analysis

      In snapshot 20w22a, a change was made in the handleMovePlayer() method in net.minecraft.client.multiplayer.ClientPacketListener. This change added a conditional statement that allows the client to dismount a vehicle using the removeVehicle() method. In order to fix this bug, this change would need to be reverted. By doing so, it should no longer be possible to dismount an vehicle on the client, preventing any de-sync issues that may occur.

      It may be possible that this was added to fix another bug or intentionally change behavior. In this case, reverting this change would not be beneficial to the game. We can check the changelog and fixed bugs from 20w22a relating to entity mounting in order to see if this is true. The bugs that fit this category are MC-182967, MC-184629, and MC-184640, and changes that fit this category include the prevention of mounting entities while the shift key is held. I was unable to reproduce these resolved issues and was still unable to mount entities when the shift key was held using the proposed fix, meaning that the proposed fix in this issue should not conflict with other changes or issues from 20w22a.

      Workaround

      The current workaround is to implement the proposed fix described in the Code Analysis section. A client-sided Fabric mod does this for versions 1.16 through 1.16.5 and snapshots 20w22a through 20w51a, with the source code linked here. Use the modification at your own risk, please audit and compile the code from source to ensure safety. As this modification was meant to fix MC-202202, it does not work with snapshots 21w03a or later which contains a partial fix for MC-202202. This also means it back-ports the partial fix for MC-202202 from 21w03a to earlier versions of the game. If you wish to fix this bug in versions 21w03a or later, it is possible to modify the source code and recompile the modification, however this process is not in the scope of this bug report and will not be described here.

            xilefian [Mojang] Felix Jones
            Bytzo Bytzo
            Votes:
            6 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: