mojira.dev
MC-119417

A spectator can occupy a bed if they enter it and then are switched to spectator mode

The bug

A spectator can occupy a bed if they enter it and then are switched to spectator mode. Expected behavior would be that the spectator would get kicked out of bed and that another player would have been able to join the bed.

How to reproduce

  1. Place a bed and go into it. This requires the player not to be in spectator mode

  2. /gamemode spectator
    → Notice you are still in a bed

  3. Ask another player to go into the bed you are occupying
    → Notice they can't because the bed is occupied

Linked issues

Attachments

Comments 17

First part confirmed. In single player mode, Night doesn't get skipped.

Confirmed. The behavior with not passing night may be related to the fix for MC-47080.

Can confirm in 21w03a.

Can confirm in 21w05b.

Can confirm in 21w06a.

7 more comments

Here's a code analysis along with a fix regarding this issue.

Code Analysis:

The following is based on a decompiled version of Minecraft 1.19.2 using MCP-Reborn.

net.minecraft.server.level.ServerPlayer.java

public class ServerPlayer extends Player {
   ...
   public boolean setGameMode(GameType gameType) {
      if (!this.gameMode.changeGameModeForPlayer(gameType)) {
         return false;
      } else {
         this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float)gameType.getId()));
         if (gameType == GameType.SPECTATOR) {
            this.removeEntitiesOnShoulder();
            this.stopRiding();
         } else {
            this.setCamera(this);
         }

         this.onUpdateAbilities();
         this.updateEffectVisibility();
         return true;
      }
   }
   ...

If we look at the above class, we can see that only two methods are called when a player switches into spectator mode. These methods are removeEntitiesOnShoulder() and stopRiding(). This basically means that when a player changes into spectator mode, any entities that are riding on their shoulders will be dismounted, along with the player themselves being dismounted if they are riding any entity. As a result of only these two methods being called, the player can continue to sleep in a bed even after switching into spectator mode.

Fix:

Simply calling the stopSleeping() method where appropriate within this piece of code will stop players from sleeping in beds upon switching into spectator mode, thus resolving this problem. The following line code can be used to fix this issue.

this.stopSleeping();

Can confirm in 1.18.2.

Can confirm in 1.19.

Can confirm in 1.19.2.

Following on from my code analysis, I've double-checked my proposed fix and I can confidently confirm that it's fully functioning and works as expected, so I've attached two screenshots to this report, one of which shows the current code and the other that shows the fixed code. I feel this information may be quite insightful hence my reasoning for providing it. 🙂

[media][media]

Kroppeb

Filip Randenbäck

Confirmed

Player

/gamemode, bed, game-mode-switch, spectator

Minecraft 1.12, Minecraft 17w31a, Minecraft 1.12.1 Pre-Release 1, Minecraft 1.12.1, Minecraft 1.12.2 Pre-Release 1, ..., 1.18.1, 1.18.2, 1.19, 1.19.2, 1.21

25w33a

Retrieved