Greatly improves handling of un-exited sessions #25

This commit is contained in:
2023-04-26 13:12:14 +02:00
parent b2fbaf0e68
commit 401490df58
12 changed files with 473 additions and 117 deletions

View File

@ -1,5 +1,8 @@
package net.knarcraft.minigames.arena;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.container.SerializableUUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -7,12 +10,17 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
/**
* An abstract representation of a player's entry state
*/
public abstract class AbstractPlayerEntryState implements PlayerEntryState {
protected final Player player;
protected final UUID playerId;
private final boolean makePlayerInvisible;
private final Location entryLocation;
private final boolean originalIsFlying;
@ -29,7 +37,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
*/
public AbstractPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) {
this.player = player;
this.playerId = player.getUniqueId();
this.makePlayerInvisible = makePlayerInvisible;
this.entryLocation = player.getLocation().clone();
this.originalIsFlying = player.isFlying();
@ -40,24 +48,74 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
this.originalCollideAble = player.isCollidable();
}
/**
* Instantiates a new abstract player entry state
*
* @param playerId <p>The id of the player whose state this should keep track of</p>
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
* @param entryLocation <p>The location the player entered from</p>
* @param originalIsFlying <p>Whether the player was flying before entering the arena</p>
* @param originalGameMode <p>The game-mode of the player before entering the arena</p>
* @param originalAllowFlight <p>Whether the player was allowed flight before entering the arena</p>
* @param originalInvulnerable <p>Whether the player was invulnerable before entering the arena</p>
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
*/
public AbstractPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation,
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
boolean originalInvulnerable, boolean originalIsSwimming,
boolean originalCollideAble) {
this.playerId = playerId;
this.makePlayerInvisible = makePlayerInvisible;
this.entryLocation = entryLocation;
this.originalIsFlying = originalIsFlying;
this.originalGameMode = originalGameMode;
this.originalAllowFlight = originalAllowFlight;
this.originalInvulnerable = originalInvulnerable;
this.originalIsSwimming = originalIsSwimming;
this.originalCollideAble = originalCollideAble;
}
@Override
public @NotNull UUID getPlayerId() {
return this.playerId;
}
@Override
public void setArenaState() {
Player player = getPlayer();
if (player == null) {
return;
}
if (this.makePlayerInvisible) {
this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
PotionEffect.INFINITE_DURATION, 3));
}
}
@Override
public void restore() {
this.player.setFlying(this.originalIsFlying);
this.player.setGameMode(this.originalGameMode);
this.player.setAllowFlight(this.originalAllowFlight);
this.player.setInvulnerable(this.originalInvulnerable);
this.player.setSwimming(this.originalIsSwimming);
this.player.setCollidable(this.originalCollideAble);
Player player = getPlayer();
if (player == null) {
return;
}
restore(player);
}
/**
* Restores the state of the given player
*
* @param player <p>The player to restore the state for</p>
*/
public void restore(Player player) {
player.setFlying(this.originalIsFlying);
player.setGameMode(this.originalGameMode);
player.setAllowFlight(this.originalAllowFlight);
player.setInvulnerable(this.originalInvulnerable);
player.setSwimming(this.originalIsSwimming);
player.setCollidable(this.originalCollideAble);
if (this.makePlayerInvisible) {
this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
player.removePotionEffect(PotionEffectType.INVISIBILITY);
}
}
@ -66,4 +124,34 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
return this.entryLocation;
}
/**
* Gets the player this entry state belongs to
*
* @return <p>The player, or null if not currently online</p>
*/
protected Player getPlayer() {
Player player = Bukkit.getOfflinePlayer(this.playerId).getPlayer();
if (player == null) {
MiniGames.log(Level.WARNING, "Unable to change state for player with id " + this.playerId +
" because the player was not found on the server.");
}
return player;
}
@NotNull
@Override
public Map<String, Object> serialize() {
Map<String, Object> data = new HashMap<>();
data.put("playerId", new SerializableUUID(this.playerId));
data.put("makePlayerInvisible", this.makePlayerInvisible);
data.put("entryLocation", this.entryLocation);
data.put("originalIsFlying", this.originalIsFlying);
data.put("originalGameMode", this.originalGameMode.name());
data.put("originalAllowFlight", this.originalAllowFlight);
data.put("originalInvulnerable", this.originalInvulnerable);
data.put("originalIsSwimming", this.originalIsSwimming);
data.put("originalCollideAble", this.originalCollideAble);
return data;
}
}