LAN/World Shared Worlds Load Disabled Config on Host After Guest Disconnect
hammy275 opened this issue ยท 3 comments
Was discovered while trying to figure out the second comment in #419. See the Discord thread linked there for all the debugging that led to figuring this out. Thanks @a_lexine on Discord!
Reproduction steps:
- Host does a world share and the other player (going to call them guest) joins.
- Guest leaves and rejoins
- Host changes dimensions
Reason for each step:
- Setup. Nothing crazy happening here.
- The guest leaving calls
PlayerLoggedOutEvent
on the host, meaning the flag to load the disabled config when loading a level (dimension) will be turned on. - A new dimension has been entered and the flag is on, therefore we load the disabled config. Under normal conditions, we would hear from the server soon after on what the config is (as this is only intended to run when you first join a world), but since we aren't actually joining the world for the first time as the host, we never hear from the server, thus are left in the disabled state.
This bug traces itself back to #170, where dimension changing would immediately load the disabled config. My fix is fine both in singleplayer and in dedicated server multiplayer, but NOT in LAN worlds/world sharing mods, hence this issue.
Fixing this is trivial, luckily. ClientLogicSubscriber#onDisconnect()
's current code should be guarded by an if statement that makes sure the provided player
is us. If Minecraft#player
is available, just compare the incoming player to that. If it isn't, compare the incoming player's UUID to Minecraft.getUser().getUUID()
.
As of the latest dev branch before this fix, apparently the consequences of this bug are much less menial. This only happened due to changes during 1.5.0 beta 2's development (combined with other ones from throughout 1.5.0's development), but due to changes around the config system combined with servers being authoritative for Immersives, the server keeps its config state set to true for both the server-wide perspective and for the host player, while the host client has all Immersives disabled. However, ImmersiveMC doesn't enforce the client's configuration option when receiving a packet from the server telling some Immersive to become active, so the Immersive is left fully functional! This likely doesn't work for all Immersives, as some still do check the config every tick, but most block-based Immersives are server-authoritative in this manner. This makes the major problem actually be a desync where the server thinks an Immersive is active on the client but the client doesn't actually have it active, since Immersives are cleared due to the client thinking it's disconnecting.
Either way, the fix is properly in place now for the next ImmersiveMC release, and will be backported down the version tree. I may want to dig into using proper "exited to title screen"/"joined a world (not level)" events, since onDisconnect()
is crossing the client/server boundary in its usage here, but that's to maybe happen in the future.