From f499da1eaac0d0bbe4791e195ebcf93aa7274fa5 Mon Sep 17 00:00:00 2001 From: Gegy Date: Tue, 19 Nov 2024 03:10:17 +0100 Subject: [PATCH] Fix: properly clear out player state when leaving from within a microgame --- .../minigames/common/core/game/impl/GameLobby.java | 8 +++++--- .../common/core/game/impl/LobbyPlayerManager.java | 8 ++++++++ .../common/core/game/impl/MultiGameManager.java | 7 +++---- .../com/lovetropics/minigames/mixin/PlayerListMixin.java | 9 +++++++++ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/impl/GameLobby.java b/src/main/java/com/lovetropics/minigames/common/core/game/impl/GameLobby.java index a8097cd92..74eb56339 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/impl/GameLobby.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/impl/GameLobby.java @@ -228,10 +228,10 @@ void onPlayerLoggedIn(ServerPlayer player) { trackingPlayers.onPlayerLoggedIn(player); } - void onPlayerLoggedOut(ServerPlayer player) { + ServerPlayer onPlayerLoggedOut(ServerPlayer player) { trackingPlayers.onPlayerLoggedOut(player); - players.remove(player, true); + return players.logOut(player); } void onPlayerRegister(ServerPlayer player) { @@ -247,7 +247,7 @@ void onPlayerRegister(ServerPlayer player) { management.onPlayersChanged(); } - void onPlayerLeave(ServerPlayer player, boolean loggingOut) { + ServerPlayer onPlayerLeave(ServerPlayer player, boolean loggingOut) { GamePhase phase = state.getTopPhase(); if (phase != null) { player = phase.onPlayerLeave(player, loggingOut); @@ -261,6 +261,8 @@ void onPlayerLeave(ServerPlayer player, boolean loggingOut) { manager.removePlayerFromLobby(player, this); rewardsMap.grant(player); + + return player; } // TODO: better abstract this logic? diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/impl/LobbyPlayerManager.java b/src/main/java/com/lovetropics/minigames/common/core/game/impl/LobbyPlayerManager.java index b40acfb35..7a1b13f67 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/impl/LobbyPlayerManager.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/impl/LobbyPlayerManager.java @@ -88,6 +88,14 @@ public boolean remove(ServerPlayer player, boolean loggingOut) { return false; } + public ServerPlayer logOut(ServerPlayer player) { + if (registrations.remove(player.getUUID())) { + player = lobby.onPlayerLeave(player, true); + roleSelections.remove(player); + } + return player; + } + @Override public boolean forceRole(ServerPlayer player, @Nullable PlayerRole role) { return registrations.forceRole(player.getUUID(), role); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/impl/MultiGameManager.java b/src/main/java/com/lovetropics/minigames/common/core/game/impl/MultiGameManager.java index 3ad97670c..ea39d4403 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/impl/MultiGameManager.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/impl/MultiGameManager.java @@ -267,14 +267,13 @@ public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { * Also if they have registered for a game poll, they will be removed from the * list of registered players. */ - @SubscribeEvent - public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { - ServerPlayer player = (ServerPlayer) event.getEntity(); + public static ServerPlayer onPlayerLoggedOut(ServerPlayer player) { if (!PlayerIsolation.INSTANCE.isReloading(player)) { for (GameLobby lobby : INSTANCE.lobbies) { - lobby.onPlayerLoggedOut(player); + player = lobby.onPlayerLoggedOut(player); } } + return player; } @SubscribeEvent diff --git a/src/main/java/com/lovetropics/minigames/mixin/PlayerListMixin.java b/src/main/java/com/lovetropics/minigames/mixin/PlayerListMixin.java index 1fcf4ee6d..58b162621 100644 --- a/src/main/java/com/lovetropics/minigames/mixin/PlayerListMixin.java +++ b/src/main/java/com/lovetropics/minigames/mixin/PlayerListMixin.java @@ -2,6 +2,7 @@ import com.lovetropics.minigames.common.core.game.PlayerIsolation; import com.lovetropics.minigames.common.core.game.PlayerListAccess; +import com.lovetropics.minigames.common.core.game.impl.MultiGameManager; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -13,6 +14,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import javax.annotation.Nullable; @@ -81,4 +83,11 @@ private void save(final ServerPlayer player, final CallbackInfo ci) { public void ltminigames$firePlayerLoading(final ServerPlayer player) { EventHooks.firePlayerLoadingEvent(player, playerIo.getPlayerDir(), player.getStringUUID()); } + + // We need to run the rest of the logic with the new player instance + // FIXME: It would be nice to not need to produce new player instances in the logout process - but microgames need it right now to pull players all the way out + @ModifyVariable(method = "remove", at = @At(value= "HEAD"), argsOnly = true) + private ServerPlayer onPlayerLogOut(ServerPlayer player) { + return MultiGameManager.onPlayerLoggedOut(player); + } }