From 206a85b23aed1a03d9aaa9ba13d617f942ff3827 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 26 Apr 2023 13:47:03 +0200 Subject: [PATCH] Improves how lingering arena states are handled on shutdown --- .../arena/AbstractArenaPlayerRegistry.java | 18 ++++++++++++++---- .../minigames/arena/AbstractArenaSession.java | 13 +------------ .../arena/AbstractPlayerEntryState.java | 13 +++++-------- .../minigames/arena/ArenaPlayerRegistry.java | 5 +++-- .../minigames/arena/PlayerEntryState.java | 2 +- .../arena/dropper/DropperArenaSession.java | 5 +++-- .../arena/dropper/DropperPlayerEntryState.java | 12 +++++++++--- .../arena/parkour/ParkourArenaSession.java | 5 +++-- .../listener/PlayerStateChangeListener.java | 2 +- 9 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java index 0844f12..c9b17d7 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java @@ -42,9 +42,19 @@ public abstract class AbstractArenaPlayerRegistry implements Ar } @Override - public boolean removePlayer(@NotNull UUID playerId) { - this.entryStates.remove(playerId); - this.saveEntryStates(); + public boolean removePlayer(@NotNull UUID playerId, boolean restoreState) { + // Try and restore the state. If it cannot be restored, retain the entry state + PlayerEntryState entryState = this.entryStates.remove(playerId); + if (restoreState) { + if (entryState.restore()) { + this.saveEntryStates(); + } else { + this.entryStates.put(playerId, entryState); + } + } else { + this.saveEntryStates(); + } + return this.arenaPlayers.remove(playerId) != null; } @@ -89,7 +99,7 @@ public abstract class AbstractArenaPlayerRegistry implements Ar } if (this.entryStates.size() > 0) { MiniGames.log(Level.WARNING, entryStates.size() + " un-exited sessions found. This happens if " + - "players are leaving in the middle of a game, or the server crashes. MiniGames will do its best " + + "players leave in the middle of a game, or if the server crashes. MiniGames will do its best " + "to fix the players' states."); } } diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java index 8000243..e95e41a 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java @@ -35,7 +35,7 @@ public abstract class AbstractArenaSession implements ArenaSession { @Override public void triggerQuit(boolean immediately) { // Stop this session - stopSession(); + removeSession(); // Teleport the player out of the arena teleportToExit(immediately); @@ -92,17 +92,6 @@ public abstract class AbstractArenaSession implements ArenaSession { PlayerTeleporter.teleportPlayer(this.player, exitLocation, true, immediately); } - /** - * Stops this session, and disables flight mode - */ - protected void stopSession() { - // Remove this session from game sessions to stop listeners from fiddling more with the player - removeSession(); - - // Remove flight mode - entryState.restore(); - } - /** * Gets the string representation of the session's game-mode * diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java index 4c29cce..d1bf53b 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java @@ -94,20 +94,17 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { } @Override - public void restore() { + public boolean restore() { Player player = getPlayer(); if (player == null) { - return; + return false; } restore(player); + return true; } - /** - * Restores the state of the given player - * - * @param player

The player to restore the state for

- */ - public void restore(Player player) { + @Override + public void restore(@NotNull Player player) { player.setFlying(this.originalIsFlying); player.setGameMode(this.originalGameMode); player.setAllowFlight(this.originalAllowFlight); diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java index 5588433..cb10111 100644 --- a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java +++ b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java @@ -31,9 +31,10 @@ public interface ArenaPlayerRegistry { /** * Removes this player from players currently playing * - * @param playerId

The id of the player to remove

+ * @param playerId

The id of the player to remove

+ * @param restoreState

Whether to restore the state of the player as part of the removal

*/ - boolean removePlayer(@NotNull UUID playerId); + boolean removePlayer(@NotNull UUID playerId, boolean restoreState); /** * Gets the player's active dropper arena session diff --git a/src/main/java/net/knarcraft/minigames/arena/PlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/PlayerEntryState.java index 16f8edf..da3f8d8 100644 --- a/src/main/java/net/knarcraft/minigames/arena/PlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/PlayerEntryState.java @@ -19,7 +19,7 @@ public interface PlayerEntryState extends ConfigurationSerializable { /** * Restores the stored state for the stored player */ - void restore(); + boolean restore(); /** * Restores the stored state for the given player diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java index 45aac7f..9d995b5 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java @@ -68,7 +68,7 @@ public class DropperArenaSession extends AbstractArenaSession { @Override public void triggerWin() { // Stop this session - stopSession(); + removeSession(); // Check for, and display, records MiniGames miniGames = MiniGames.getInstance(); @@ -104,7 +104,8 @@ public class DropperArenaSession extends AbstractArenaSession { @Override protected void removeSession() { // Remove this session for game sessions to stop listeners from fiddling more with the player - boolean removedSession = MiniGames.getInstance().getDropperArenaPlayerRegistry().removePlayer(player.getUniqueId()); + boolean removedSession = MiniGames.getInstance().getDropperArenaPlayerRegistry().removePlayer( + player.getUniqueId(), true); if (!removedSession) { MiniGames.log(Level.SEVERE, "Unable to remove dropper arena session for " + player.getName() + ". " + "This will have unintended consequences."); diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java index 9385fdd..3a8e993 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java @@ -84,12 +84,18 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { } @Override - public void restore() { - super.restore(); + public boolean restore() { Player player = getPlayer(); if (player == null) { - return; + return false; } + this.restore(player); + return true; + } + + @Override + public void restore(@NotNull Player player) { + super.restore(player); player.setFlySpeed(this.originalFlySpeed); } diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java index 7947098..6ed5aac 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java @@ -69,7 +69,7 @@ public class ParkourArenaSession extends AbstractArenaSession { @Override public void triggerWin() { // Stop this session - stopSession(); + removeSession(); // Check for, and display, records MiniGames miniGames = MiniGames.getInstance(); @@ -106,7 +106,8 @@ public class ParkourArenaSession extends AbstractArenaSession { @Override protected void removeSession() { // Remove this session for game sessions to stop listeners from fiddling more with the player - boolean removedSession = MiniGames.getInstance().getParkourArenaPlayerRegistry().removePlayer(player.getUniqueId()); + boolean removedSession = MiniGames.getInstance().getParkourArenaPlayerRegistry().removePlayer( + player.getUniqueId(), true); if (!removedSession) { MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " + "This will have unintended consequences."); diff --git a/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java b/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java index 14987b0..e3831fa 100644 --- a/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java @@ -79,7 +79,7 @@ public class PlayerStateChangeListener implements Listener { if (entryState != null) { MiniGames.log(Level.INFO, "Found existing state for joining player " + player + ". Attempting to restore the player's state."); - playerRegistry.removePlayer(player.getUniqueId()); + playerRegistry.removePlayer(player.getUniqueId(), false); entryState.restore(player); return entryState.getEntryLocation();