Improves how lingering arena states are handled on shutdown

This commit is contained in:
Kristian Knarvik 2023-04-26 13:47:03 +02:00
parent 401490df58
commit 206a85b23a
9 changed files with 40 additions and 35 deletions

View File

@ -42,9 +42,19 @@ public abstract class AbstractArenaPlayerRegistry<K extends Arena> implements Ar
} }
@Override @Override
public boolean removePlayer(@NotNull UUID playerId) { public boolean removePlayer(@NotNull UUID playerId, boolean restoreState) {
this.entryStates.remove(playerId); // Try and restore the state. If it cannot be restored, retain the entry state
this.saveEntryStates(); 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; return this.arenaPlayers.remove(playerId) != null;
} }
@ -89,7 +99,7 @@ public abstract class AbstractArenaPlayerRegistry<K extends Arena> implements Ar
} }
if (this.entryStates.size() > 0) { if (this.entryStates.size() > 0) {
MiniGames.log(Level.WARNING, entryStates.size() + " un-exited sessions found. This happens if " + 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."); "to fix the players' states.");
} }
} }

View File

@ -35,7 +35,7 @@ public abstract class AbstractArenaSession implements ArenaSession {
@Override @Override
public void triggerQuit(boolean immediately) { public void triggerQuit(boolean immediately) {
// Stop this session // Stop this session
stopSession(); removeSession();
// Teleport the player out of the arena // Teleport the player out of the arena
teleportToExit(immediately); teleportToExit(immediately);
@ -92,17 +92,6 @@ public abstract class AbstractArenaSession implements ArenaSession {
PlayerTeleporter.teleportPlayer(this.player, exitLocation, true, immediately); 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 * Gets the string representation of the session's game-mode
* *

View File

@ -94,20 +94,17 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
} }
@Override @Override
public void restore() { public boolean restore() {
Player player = getPlayer(); Player player = getPlayer();
if (player == null) { if (player == null) {
return; return false;
} }
restore(player); restore(player);
return true;
} }
/** @Override
* Restores the state of the given player public void restore(@NotNull Player player) {
*
* @param player <p>The player to restore the state for</p>
*/
public void restore(Player player) {
player.setFlying(this.originalIsFlying); player.setFlying(this.originalIsFlying);
player.setGameMode(this.originalGameMode); player.setGameMode(this.originalGameMode);
player.setAllowFlight(this.originalAllowFlight); player.setAllowFlight(this.originalAllowFlight);

View File

@ -31,9 +31,10 @@ public interface ArenaPlayerRegistry<K extends Arena> {
/** /**
* Removes this player from players currently playing * Removes this player from players currently playing
* *
* @param playerId <p>The id of the player to remove</p> * @param playerId <p>The id of the player to remove</p>
* @param restoreState <p>Whether to restore the state of the player as part of the removal</p>
*/ */
boolean removePlayer(@NotNull UUID playerId); boolean removePlayer(@NotNull UUID playerId, boolean restoreState);
/** /**
* Gets the player's active dropper arena session * Gets the player's active dropper arena session

View File

@ -19,7 +19,7 @@ public interface PlayerEntryState extends ConfigurationSerializable {
/** /**
* Restores the stored state for the stored player * Restores the stored state for the stored player
*/ */
void restore(); boolean restore();
/** /**
* Restores the stored state for the given player * Restores the stored state for the given player

View File

@ -68,7 +68,7 @@ public class DropperArenaSession extends AbstractArenaSession {
@Override @Override
public void triggerWin() { public void triggerWin() {
// Stop this session // Stop this session
stopSession(); removeSession();
// Check for, and display, records // Check for, and display, records
MiniGames miniGames = MiniGames.getInstance(); MiniGames miniGames = MiniGames.getInstance();
@ -104,7 +104,8 @@ public class DropperArenaSession extends AbstractArenaSession {
@Override @Override
protected void removeSession() { protected void removeSession() {
// Remove this session for game sessions to stop listeners from fiddling more with the player // 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) { if (!removedSession) {
MiniGames.log(Level.SEVERE, "Unable to remove dropper arena session for " + player.getName() + ". " + MiniGames.log(Level.SEVERE, "Unable to remove dropper arena session for " + player.getName() + ". " +
"This will have unintended consequences."); "This will have unintended consequences.");

View File

@ -84,12 +84,18 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
} }
@Override @Override
public void restore() { public boolean restore() {
super.restore();
Player player = getPlayer(); Player player = getPlayer();
if (player == null) { 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); player.setFlySpeed(this.originalFlySpeed);
} }

View File

@ -69,7 +69,7 @@ public class ParkourArenaSession extends AbstractArenaSession {
@Override @Override
public void triggerWin() { public void triggerWin() {
// Stop this session // Stop this session
stopSession(); removeSession();
// Check for, and display, records // Check for, and display, records
MiniGames miniGames = MiniGames.getInstance(); MiniGames miniGames = MiniGames.getInstance();
@ -106,7 +106,8 @@ public class ParkourArenaSession extends AbstractArenaSession {
@Override @Override
protected void removeSession() { protected void removeSession() {
// Remove this session for game sessions to stop listeners from fiddling more with the player // 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) { if (!removedSession) {
MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " + MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " +
"This will have unintended consequences."); "This will have unintended consequences.");

View File

@ -79,7 +79,7 @@ public class PlayerStateChangeListener implements Listener {
if (entryState != null) { if (entryState != null) {
MiniGames.log(Level.INFO, "Found existing state for joining player " + player + MiniGames.log(Level.INFO, "Found existing state for joining player " + player +
". Attempting to restore the player's state."); ". Attempting to restore the player's state.");
playerRegistry.removePlayer(player.getUniqueId()); playerRegistry.removePlayer(player.getUniqueId(), false);
entryState.restore(player); entryState.restore(player);
return entryState.getEntryLocation(); return entryState.getEntryLocation();