The bug
Players becoming visible for other players are not notified about their own data parameter change. This causes them to remain invisible after switching to something different than Spectator mode or to not become invisible when switching to Spectator mode which results in a opaque head.
Unlike MC-104816 this is not permanent and changes in the flags data parameter value (such as shifting, catching fire, glowing) will update the visibility correctly.
How to reproduce (invisible non-Spectator)
- Enter a server or LAN world with at least one other player in a gamemode other than Spectator mode
- Switch to Spectator mode
/gamemode spectator
- Switch back to for example Creative mode
/gamemode creative
→ You will notice that you are still invisible
How to reproduce (opaque Spectator head)
- Enter a server or LAN world with at least one other player in a gamemode other than Spectator mode
- Switch to a gamemode other than Spectator mode
/gamemode creative
- Switch your and the gamemode of at least one other player to Spectator mode
/gamemode spectator @a
→ n - 1 (with n being the number of player switched from non-Spectator to Spectator) players will see their own head opaque
Code analysis
Based on 1.11.2 decompiled using MCP 9.35 rc1
When the gamemode of a player changes the visibility for other players and the player himself is updated. This happens before the player is notified about data parameter changes like for example the flags one which stores if a player is invisible. The problem is that in this case the constructor net.minecraft.network.play.server.SPacketEntityMetadata.SPacketEntityMetadata(int, EntityDataManager, boolean) marks the data manager of the player as not dirty and therefor the player himself is not notified about the changed.
The "opaque Spectator head" case is caused by the same problem but there it might be harder to see the reason, therefor the following shows what happens when you change the gamemode for multiple players. In this scenario there are two players, "Player A" and "Player B" which are both not in Spectator mode.
- Player A is switched to Spectator mode
- Other players are updated
- Player A becomes invisible for Player B
- Player B is switched to Spectator mode
- Other players are updated
- Player A becomes visible for Player B
- Data parameter values of Player A are sent and data manager is set to clear
- Player A becomes visible for Player B
- Entity tracker sends packets for players with dirty data manager
→ Player B receives a packet but Player A does not
- relates to
-
MC-193571 Players render invisible client-side in a server environment when exiting spectator mode whilst having previously spectated an entity
- Open