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
public boolean removePlayer(@NotNull UUID playerId) {
this.entryStates.remove(playerId);
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<K extends Arena> 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.");
}
}

View File

@ -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
*

View File

@ -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 <p>The player to restore the state for</p>
*/
public void restore(Player player) {
@Override
public void restore(@NotNull Player player) {
player.setFlying(this.originalIsFlying);
player.setGameMode(this.originalGameMode);
player.setAllowFlight(this.originalAllowFlight);

View File

@ -32,8 +32,9 @@ public interface ArenaPlayerRegistry<K extends Arena> {
* Removes this player from players currently playing
*
* @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

View File

@ -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

View File

@ -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.");

View File

@ -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);
}

View File

@ -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.");

View File

@ -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();