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

Packets to change players' rotation affect their distance limit

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.19.3, 23w05a, 23w18a, 1.20.2
    • None
    • Plausible
    • Networking, Player
    • Normal
    • Platform

      The bug

      The Minecraft server checks if each player's move distance is valid according to the number of ServerboundMovePlayerPacket s received per tick. If a player reaches this limit, the server will give a warning message (... moved too quickly! ...). In addition, if the server receives more than 5 ServerboundMovePlayerPacket s per tick, it will give a debug message (... is sending move packets too frequently (... packets since last tick)), effectively reducing the number of packets received to 1. This often causes a rollback of the position for a player moving too quickly.

      The problem is that ServerboundMovePlayerPacket$Rot, which does not affect the player's position, increments the number of the move packets. This means that the more frequently a player moves its rotation, the more likely it is to reach the distance limit. This behavior would be unintentional, given the intent of the code, which limits movement speed.

      Code analysis

      net.minecraft.server.network.ServerGamePacketListenerImpl
      @Override
      public void handleMovePlayer(ServerboundMovePlayerPacket $$0) {
        // ...
      
        ++this.receivedMovePacketCount;
        int $$16 = this.receivedMovePacketCount - this.knownMovePacketCount;
        if ($$16 > 5) {
          LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", this.player.getName().getString(), $$16);
          $$16 = 1; // the number of move packets is reduced to 1
        }
      
        if (!this.player.isChangingDimension()
          && (!this.player.getLevel().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) {
          float $$17 = this.player.isFallFlying() ? 300.0F : 100.0F;
          if ($$15 - $$14 > (double)($$17 * (float)$$16) /* distance limit */ && !this.isSingleplayerOwner()) {
            LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), $$11, $$12, $$13});
      
            // reset the position and return
            this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot());
            return;
          }
        }
      
        // ...
      }
      

            Unassigned Unassigned
            intsuc intsuc
            Votes:
            9 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              CHK: