From cf0962ef707550d7e17a05e835ffa997f7d9f8f5 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Mon, 17 Apr 2023 22:20:42 +0200
Subject: [PATCH 1/9] Makes sure all arena sessions are exited regardless
---
.../java/net/knarcraft/minigames/MiniGames.java | 15 ++++++++-------
.../minigames/listener/PlayerLeaveListener.java | 14 +++++++++++---
2 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java
index f26726a..4bb48ae 100644
--- a/src/main/java/net/knarcraft/minigames/MiniGames.java
+++ b/src/main/java/net/knarcraft/minigames/MiniGames.java
@@ -1,6 +1,7 @@
package net.knarcraft.minigames;
import net.knarcraft.minigames.arena.ArenaSession;
+import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaData;
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
@@ -8,6 +9,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
import net.knarcraft.minigames.arena.dropper.DropperArenaPlayerRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
+import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaData;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
@@ -56,7 +58,6 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
-import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
@@ -277,12 +278,12 @@ public final class MiniGames extends JavaPlugin {
@Override
public void onDisable() {
- // Throw out currently playing players before exiting
- for (Player player : getServer().getOnlinePlayers()) {
- ArenaSession session = getSession(player.getUniqueId());
- if (session != null) {
- session.triggerQuit(true);
- }
+ // Kill all sessions before exiting
+ for (DropperArena arena : dropperArenaHandler.getArenas().values()) {
+ dropperArenaPlayerRegistry.removeForArena(arena);
+ }
+ for (ParkourArena arena : parkourArenaHandler.getArenas().values()) {
+ parkourArenaPlayerRegistry.removeForArena(arena);
}
}
diff --git a/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java b/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java
index 7ca6239..0bfaa5c 100644
--- a/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java
+++ b/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java
@@ -52,28 +52,36 @@ public class PlayerLeaveListener implements Listener {
}
}
- @EventHandler
+ /**
+ * Prevent the player from teleporting away from an arena for any reason
+ *
+ * @param event The triggered teleport event
+ */
+ @EventHandler(ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
Location targetLocation = event.getTo();
- if (targetLocation == null || event.isCancelled()) {
+ if (targetLocation == null) {
return;
}
+ // Ignore if not in an arena session
ArenaSession arenaSession = MiniGames.getInstance().getSession(event.getPlayer().getUniqueId());
if (arenaSession == null) {
return;
}
+ // If teleported to the arena's spawn, it's fine
if (targetLocation.equals(arenaSession.getArena().getSpawnLocation())) {
return;
}
+ // If teleported to the arena's checkpoint, it's fine
if (arenaSession instanceof ParkourArenaSession parkourArenaSession &&
targetLocation.equals(parkourArenaSession.getRegisteredCheckpoint())) {
return;
}
- arenaSession.triggerQuit(false);
+ event.setCancelled(true);
}
}
From 58e25bcb30a642b498300e7ac6730e152321c49c Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Tue, 18 Apr 2023 14:13:07 +0200
Subject: [PATCH 2/9] Adds tab-complete filtering #12
---
.../command/JoinArenaTabCompleter.java | 6 ++++--
.../dropper/DropperGroupListCommand.java | 4 +++-
.../command/dropper/DropperGroupSetCommand.java | 6 ++++--
.../dropper/DropperGroupSwapCommand.java | 6 ++++--
.../dropper/EditDropperArenaTabCompleter.java | 14 ++++++++------
.../dropper/RemoveDropperArenaTabCompleter.java | 4 +++-
.../parkour/EditParkourArenaTabCompleter.java | 14 ++++++++------
.../parkour/ParkourGroupListCommand.java | 4 +++-
.../command/parkour/ParkourGroupSetCommand.java | 6 ++++--
.../parkour/ParkourGroupSwapCommand.java | 6 ++++--
.../parkour/RemoveParkourArenaTabCompleter.java | 4 +++-
.../minigames/util/TabCompleteHelper.java | 17 +++++++++++++++++
12 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java
index 8e0c74d..d33828e 100644
--- a/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java
@@ -11,6 +11,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* An abstract class for an arena joining tab-completer
*/
@@ -34,13 +36,13 @@ public abstract class JoinArenaTabCompleter implements TabCompleter {
public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String label, @NotNull String[] arguments) {
if (arguments.length == 1) {
- return arenaNameSupplier.get();
+ return filterMatchingContains(arenaNameSupplier.get(), arguments[0]);
} else if (arguments.length == 2) {
List gameModes = new ArrayList<>();
for (ArenaGameMode gameMode : gameMode.getValues()) {
gameModes.add(gameMode.name().toLowerCase());
}
- return gameModes;
+ return filterMatchingContains(gameModes, arguments[1]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java
index fe7525d..df496a9 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java
@@ -14,6 +14,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The command for listing groups and the stages within
*/
@@ -84,7 +86,7 @@ public class DropperGroupListCommand implements TabExecutor {
for (DropperArenaGroup group : MiniGames.getInstance().getDropperArenaHandler().getAllGroups()) {
groupNames.add(group.getGroupName());
}
- return groupNames;
+ return filterMatchingContains(groupNames, arguments[0]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java
index 68c14b1..9487453 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java
@@ -15,6 +15,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The command for setting the group of an arena
*/
@@ -62,7 +64,7 @@ public class DropperGroupSetCommand implements TabExecutor {
public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (arguments.length == 1) {
- return TabCompleteHelper.getDropperArenas();
+ return filterMatchingContains(TabCompleteHelper.getDropperArenas(), arguments[0]);
} else if (arguments.length == 2) {
List possibleValues = new ArrayList<>();
possibleValues.add("none");
@@ -70,7 +72,7 @@ public class DropperGroupSetCommand implements TabExecutor {
for (DropperArenaGroup group : MiniGames.getInstance().getDropperArenaHandler().getAllGroups()) {
possibleValues.add(group.getGroupName());
}
- return possibleValues;
+ return filterMatchingContains(possibleValues, arguments[1]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java
index 4de5f2b..5d6c711 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java
@@ -14,6 +14,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The command for swapping the order of two arenas in a group
*/
@@ -63,9 +65,9 @@ public class DropperGroupSwapCommand implements TabExecutor {
for (DropperArena dropperArena : arenaHandler.getArenasInAGroup()) {
arenaNames.add(dropperArena.getArenaName());
}
- return arenaNames;
+ return filterMatchingContains(arenaNames, arguments[0]);
} else if (arguments.length == 2) {
- return getArenaNamesInSameGroup(arguments[0]);
+ return filterMatchingContains(getArenaNamesInSameGroup(arguments[0]), arguments[1]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java
index 0f85127..af5161b 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java
@@ -10,6 +10,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The tab-completer for the edit arena command
*/
@@ -17,12 +19,12 @@ public class EditDropperArenaTabCompleter implements TabCompleter {
@Override
public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
- @NotNull String label, @NotNull String[] args) {
- if (args.length == 1) {
- return TabCompleteHelper.getDropperArenas();
- } else if (args.length == 2) {
- return TabCompleteHelper.getDropperArenaProperties();
- } else if (args.length == 3) {
+ @NotNull String label, @NotNull String[] arguments) {
+ if (arguments.length == 1) {
+ return filterMatchingContains(TabCompleteHelper.getDropperArenas(), arguments[0]);
+ } else if (arguments.length == 2) {
+ return filterMatchingContains(TabCompleteHelper.getDropperArenaProperties(), arguments[1]);
+ } else if (arguments.length == 3) {
//TODO: Tab-complete possible values for the given property
return null;
} else {
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java
index b12234f..1143e3e 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java
@@ -10,6 +10,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The tab-completer for the remove arena command
*/
@@ -20,7 +22,7 @@ public class RemoveDropperArenaTabCompleter implements TabCompleter {
public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (arguments.length == 1) {
- return TabCompleteHelper.getDropperArenas();
+ return filterMatchingContains(TabCompleteHelper.getDropperArenas(), arguments[0]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java
index a9270e7..a6f5593 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java
@@ -10,6 +10,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The tab-completer for the edit arena command
*/
@@ -17,12 +19,12 @@ public class EditParkourArenaTabCompleter implements TabCompleter {
@Override
public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
- @NotNull String label, @NotNull String[] args) {
- if (args.length == 1) {
- return TabCompleteHelper.getParkourArenas();
- } else if (args.length == 2) {
- return TabCompleteHelper.getParkourArenaProperties();
- } else if (args.length == 3) {
+ @NotNull String label, @NotNull String[] arguments) {
+ if (arguments.length == 1) {
+ return filterMatchingContains(TabCompleteHelper.getParkourArenas(), arguments[0]);
+ } else if (arguments.length == 2) {
+ return filterMatchingContains(TabCompleteHelper.getParkourArenaProperties(), arguments[1]);
+ } else if (arguments.length == 3) {
//TODO: Tab-complete possible values for the given property
return null;
} else {
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java
index 7dd31dd..cb423db 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java
@@ -15,6 +15,8 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The command for listing groups and the stages within
*/
@@ -86,7 +88,7 @@ public class ParkourGroupListCommand implements TabExecutor {
for (ParkourArenaGroup group : arenaGroups) {
groupNames.add(group.getGroupName());
}
- return groupNames;
+ return filterMatchingContains(groupNames, arguments[0]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java
index 14a66e2..01e13e3 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java
@@ -15,6 +15,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The command for setting the group of an arena
*/
@@ -62,7 +64,7 @@ public class ParkourGroupSetCommand implements TabExecutor {
public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (arguments.length == 1) {
- return TabCompleteHelper.getParkourArenas();
+ return filterMatchingContains(TabCompleteHelper.getParkourArenas(), arguments[0]);
} else if (arguments.length == 2) {
List possibleValues = new ArrayList<>();
possibleValues.add("none");
@@ -70,7 +72,7 @@ public class ParkourGroupSetCommand implements TabExecutor {
for (ParkourArenaGroup group : MiniGames.getInstance().getParkourArenaHandler().getAllGroups()) {
possibleValues.add(group.getGroupName());
}
- return possibleValues;
+ return filterMatchingContains(possibleValues, arguments[1]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java
index 66a8174..283c53f 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java
@@ -14,6 +14,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The command for swapping the order of two arenas in a group
*/
@@ -63,9 +65,9 @@ public class ParkourGroupSwapCommand implements TabExecutor {
for (ParkourArena parkourArena : arenaHandler.getArenasInAGroup()) {
arenaNames.add(parkourArena.getArenaName());
}
- return arenaNames;
+ return filterMatchingContains(arenaNames, arguments[0]);
} else if (arguments.length == 2) {
- return getArenaNamesInSameGroup(arguments[0]);
+ return filterMatchingContains(getArenaNamesInSameGroup(arguments[0]), arguments[1]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java
index 9605a81..87c0787 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java
@@ -10,6 +10,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
+
/**
* The tab-completer for the remove arena command
*/
@@ -20,7 +22,7 @@ public class RemoveParkourArenaTabCompleter implements TabCompleter {
public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (arguments.length == 1) {
- return TabCompleteHelper.getParkourArenas();
+ return filterMatchingContains(TabCompleteHelper.getParkourArenas(), arguments[0]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java b/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java
index d537525..65749d4 100644
--- a/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java
+++ b/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java
@@ -76,4 +76,21 @@ public final class TabCompleteHelper {
return arenaProperties;
}
+ /**
+ * Finds tab complete values that contain the typed text
+ *
+ * @param values The values to filter
+ * @param typedText The text the player has started typing
+ * @return The given string values that contain the player's typed text
+ */
+ public static List filterMatchingContains(@NotNull List values, @NotNull String typedText) {
+ List configValues = new ArrayList<>();
+ for (String value : values) {
+ if (value.toLowerCase().contains(typedText.toLowerCase())) {
+ configValues.add(value);
+ }
+ }
+ return configValues;
+ }
+
}
From e6bb324da1be26cbf324d06ce83d3fdd7e749d22 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Tue, 18 Apr 2023 17:25:10 +0200
Subject: [PATCH 3/9] Improves messages #16
---
.../net/knarcraft/minigames/MiniGames.java | 4 +-
.../minigames/arena/ArenaHandler.java | 2 +-
.../minigames/arena/ArenaPlayerRegistry.java | 5 +-
.../arena/dropper/DropperArenaHandler.java | 4 +-
.../dropper/DropperArenaPlayerRegistry.java | 10 +-
.../arena/dropper/DropperArenaSession.java | 7 +-
.../arena/parkour/ParkourArenaHandler.java | 4 +-
.../parkour/ParkourArenaPlayerRegistry.java | 10 +-
.../arena/parkour/ParkourArenaSession.java | 7 +-
.../minigames/command/LeaveArenaCommand.java | 5 +-
.../minigames/command/ReloadCommand.java | 3 +-
.../dropper/CreateDropperArenaCommand.java | 7 +-
.../dropper/DropperGroupListCommand.java | 5 +-
.../dropper/DropperGroupSetCommand.java | 5 +-
.../dropper/DropperGroupSwapCommand.java | 9 +-
.../dropper/EditDropperArenaCommand.java | 18 +--
.../dropper/JoinDropperArenaCommand.java | 18 +--
.../dropper/ListDropperArenaCommand.java | 6 +-
.../dropper/RemoveDropperArenaCommand.java | 5 +-
.../parkour/CreateParkourArenaCommand.java | 7 +-
.../parkour/EditParkourArenaCommand.java | 18 +--
.../parkour/JoinParkourArenaCommand.java | 14 +--
.../parkour/ListParkourArenaCommand.java | 6 +-
.../parkour/ParkourGroupListCommand.java | 7 +-
.../parkour/ParkourGroupSetCommand.java | 5 +-
.../parkour/ParkourGroupSwapCommand.java | 9 +-
.../parkour/RemoveParkourArenaCommand.java | 5 +-
.../knarcraft/minigames/config/Message.java | 111 ++++++++++++++++++
.../container/PlaceholderContainer.java | 41 +++++++
.../minigames/listener/CommandListener.java | 3 +-
.../minigames/listener/MoveListener.java | 32 +++--
.../knarcraft/minigames/util/ColorHelper.java | 29 +++++
.../util/DropperArenaStorageHelper.java | 9 +-
.../minigames/util/MaterialHelper.java | 3 +-
.../util/ParkourArenaStorageHelper.java | 9 +-
.../minigames/util/PlayerTeleporter.java | 9 +-
src/main/resources/plugin.yml | 1 +
37 files changed, 335 insertions(+), 117 deletions(-)
create mode 100644 src/main/java/net/knarcraft/minigames/config/Message.java
create mode 100644 src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java
create mode 100644 src/main/java/net/knarcraft/minigames/util/ColorHelper.java
diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java
index 4bb48ae..756c92b 100644
--- a/src/main/java/net/knarcraft/minigames/MiniGames.java
+++ b/src/main/java/net/knarcraft/minigames/MiniGames.java
@@ -280,10 +280,10 @@ public final class MiniGames extends JavaPlugin {
public void onDisable() {
// Kill all sessions before exiting
for (DropperArena arena : dropperArenaHandler.getArenas().values()) {
- dropperArenaPlayerRegistry.removeForArena(arena);
+ dropperArenaPlayerRegistry.removeForArena(arena, true);
}
for (ParkourArena arena : parkourArenaHandler.getArenas().values()) {
- parkourArenaPlayerRegistry.removeForArena(arena);
+ parkourArenaPlayerRegistry.removeForArena(arena, true);
}
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/ArenaHandler.java
index 3c71900..6c37279 100644
--- a/src/main/java/net/knarcraft/minigames/arena/ArenaHandler.java
+++ b/src/main/java/net/knarcraft/minigames/arena/ArenaHandler.java
@@ -170,7 +170,7 @@ public abstract class ArenaHandler>
*/
public void removeArena(@NotNull K arena) {
UUID arenaId = arena.getArenaId();
- this.playerRegistry.removeForArena(arena);
+ this.playerRegistry.removeForArena(arena, false);
this.arenas.remove(arenaId);
this.arenaNameLookup.remove(arena.getArenaNameSanitized());
this.arenaGroups.remove(arenaId);
diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
index d7734a6..3866fb8 100644
--- a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
@@ -10,8 +10,9 @@ public interface ArenaPlayerRegistry {
/**
* Removes all active sessions for the given arena
*
- * @param arena The arena to remove sessions for
+ * @param arena The arena to remove sessions for
+ * @param immediately Whether to immediately teleport the player
*/
- void removeForArena(K arena);
+ void removeForArena(K arena, boolean immediately);
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java
index e2e4eac..f857b61 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.arena.dropper;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaHandler;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.DropperArenaStorageHelper;
import java.io.IOException;
@@ -31,8 +32,7 @@ public class DropperArenaHandler extends ArenaHandler(this.arenaGroups.values()));
} catch (IOException e) {
- MiniGames.log(Level.SEVERE, "Unable to save current arena groups! " +
- "Data loss can occur!");
+ MiniGames.log(Level.SEVERE, Message.ERROR_CANNOT_SAVE_ARENA_GROUPS.getMessage());
MiniGames.log(Level.SEVERE, e.getMessage());
}
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
index 8c3b327..30b120c 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
@@ -44,16 +44,12 @@ public class DropperArenaPlayerRegistry implements ArenaPlayerRegistryThe arena to remove sessions for
- */
- public void removeForArena(DropperArena arena) {
+ @Override
+ public void removeForArena(DropperArena arena, boolean immediately) {
for (Map.Entry entry : this.arenaPlayers.entrySet()) {
if (entry.getValue().getArena() == arena) {
// Kick the player gracefully
- entry.getValue().triggerQuit(false);
+ entry.getValue().triggerQuit(immediately);
this.arenaPlayers.remove(entry.getKey());
}
}
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 2ff11c3..4b2d712 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java
@@ -5,6 +5,7 @@ import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.arena.PlayerEntryState;
import net.knarcraft.minigames.config.DropperConfiguration;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.property.RecordResult;
import net.knarcraft.minigames.util.PlayerTeleporter;
import org.bukkit.Location;
@@ -84,9 +85,9 @@ public class DropperArenaSession implements ArenaSession {
// Mark the arena as cleared
if (this.arena.getData().setCompleted(this.gameMode, this.player)) {
- this.player.sendMessage("You cleared the arena!");
+ this.player.sendMessage(Message.SUCCESS_ARENA_FIRST_CLEAR.getMessage());
}
- this.player.sendMessage("You won!");
+ this.player.sendMessage(Message.SUCCESS_ARENA_WIN.getMessage());
// Teleport the player out of the arena
teleportToExit(false);
@@ -178,7 +179,7 @@ public class DropperArenaSession implements ArenaSession {
// Teleport the player out of the arena
teleportToExit(immediately);
- player.sendMessage("You quit the arena!");
+ player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage());
}
/**
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java
index d177879..ffc657f 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.arena.parkour;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaHandler;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.ParkourArenaStorageHelper;
import java.io.IOException;
@@ -31,8 +32,7 @@ public class ParkourArenaHandler extends ArenaHandler(this.arenaGroups.values()));
} catch (IOException e) {
- MiniGames.log(Level.SEVERE, "Unable to save current arena groups! " +
- "Data loss can occur!");
+ MiniGames.log(Level.SEVERE, Message.ERROR_CANNOT_SAVE_ARENA_GROUPS.getMessage());
MiniGames.log(Level.SEVERE, e.getMessage());
}
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
index 0a20c07..ee882bf 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
@@ -44,16 +44,12 @@ public class ParkourArenaPlayerRegistry implements ArenaPlayerRegistryThe arena to remove sessions for
- */
- public void removeForArena(ParkourArena arena) {
+ @Override
+ public void removeForArena(ParkourArena arena, boolean immediately) {
for (Map.Entry entry : this.arenaPlayers.entrySet()) {
if (entry.getValue().getArena() == arena) {
// Kick the player gracefully
- entry.getValue().triggerQuit(false);
+ entry.getValue().triggerQuit(immediately);
this.arenaPlayers.remove(entry.getKey());
}
}
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 c21fb49..06a952a 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java
@@ -5,6 +5,7 @@ import net.knarcraft.minigames.arena.ArenaGameMode;
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.arena.PlayerEntryState;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.config.ParkourConfiguration;
import net.knarcraft.minigames.property.RecordResult;
import net.knarcraft.minigames.util.PlayerTeleporter;
@@ -99,9 +100,9 @@ public class ParkourArenaSession implements ArenaSession {
// Mark the arena as cleared
if (this.arena.getData().setCompleted(this.gameMode, this.player)) {
- this.player.sendMessage("You cleared the arena!");
+ this.player.sendMessage(Message.SUCCESS_ARENA_FIRST_CLEAR.getMessage());
}
- this.player.sendMessage("You won!");
+ this.player.sendMessage(Message.SUCCESS_ARENA_WIN.getMessage());
// Teleport the player out of the arena
teleportToExit(false);
@@ -188,7 +189,7 @@ public class ParkourArenaSession implements ArenaSession {
// Teleport the player out of the arena
teleportToExit(immediately);
- player.sendMessage("You quit the arena!");
+ player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage());
}
/**
diff --git a/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java
index 3e70afd..177508e 100644
--- a/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.command;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaSession;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -21,13 +22,13 @@ public class LeaveArenaCommand implements TabExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] strings) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId());
if (existingSession == null) {
- commandSender.sendMessage("You are not in a mini-games arena!");
+ commandSender.sendMessage(Message.ERROR_NOT_IN_ARENA.getMessage());
return false;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/ReloadCommand.java b/src/main/java/net/knarcraft/minigames/command/ReloadCommand.java
index cec650a..36168b7 100644
--- a/src/main/java/net/knarcraft/minigames/command/ReloadCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/ReloadCommand.java
@@ -1,6 +1,7 @@
package net.knarcraft.minigames.command;
import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -19,7 +20,7 @@ public class ReloadCommand implements TabExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
MiniGames.getInstance().reload();
- commandSender.sendMessage("Plugin reloaded!");
+ commandSender.sendMessage(Message.SUCCESS_PLUGIN_RELOADED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/CreateDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/CreateDropperArenaCommand.java
index 622b0b4..623c133 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/CreateDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/CreateDropperArenaCommand.java
@@ -3,6 +3,7 @@ package net.knarcraft.minigames.command.dropper;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.StringSanitizer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -19,7 +20,7 @@ public class CreateDropperArenaCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
@@ -40,13 +41,13 @@ public class CreateDropperArenaCommand implements CommandExecutor {
DropperArena existingArena = arenaHandler.getArena(arenaName);
if (existingArena != null) {
- commandSender.sendMessage("There already exists a dropper arena with that name!");
+ commandSender.sendMessage(Message.ERROR_ARENA_NAME_COLLISION.getMessage());
return false;
}
DropperArena arena = new DropperArena(arenaName, player.getLocation(), arenaHandler);
arenaHandler.addArena(arena);
- commandSender.sendMessage("The arena was successfully created!");
+ commandSender.sendMessage(Message.SUCCESS_ARENA_CREATED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java
index df496a9..c571e09 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java
@@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -60,12 +61,12 @@ public class DropperGroupListCommand implements TabExecutor {
@NotNull String groupName) {
DropperArenaGroup arenaGroup = arenaHandler.getGroup(groupName);
if (arenaGroup == null) {
- sender.sendMessage("Unable to find the specified group!");
+ sender.sendMessage(Message.ERROR_GROUP_NOT_FOUND.getMessage());
return false;
}
// Send a list of all stages (arenas in the group)
- StringBuilder builder = new StringBuilder(groupName).append("'s stages:").append("\n");
+ StringBuilder builder = new StringBuilder(Message.SUCCESS_GROUP_STAGES.getMessage("{group}", groupName));
int counter = 1;
for (UUID arenaId : arenaGroup.getArenas()) {
DropperArena arena = arenaHandler.getArena(arenaId);
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java
index 9487453..b1d3008 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java
@@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.StringSanitizer;
import net.knarcraft.minigames.util.TabCompleteHelper;
import org.bukkit.command.Command;
@@ -33,7 +34,7 @@ public class DropperGroupSetCommand implements TabExecutor {
DropperArena specifiedArena = arenaHandler.getArena(arguments[0]);
if (specifiedArena == null) {
- commandSender.sendMessage("Unable to find the specified dropper arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
@@ -55,7 +56,7 @@ public class DropperGroupSetCommand implements TabExecutor {
arenaHandler.setGroup(specifiedArena.getArenaId(), arenaGroup);
- commandSender.sendMessage("The arena's group has been updated");
+ commandSender.sendMessage(Message.SUCCESS_ARENA_GROUP_UPDATED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java
index 5d6c711..f1832ab 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java
@@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -32,26 +33,26 @@ public class DropperGroupSwapCommand implements TabExecutor {
DropperArena arena1 = arenaHandler.getArena(arguments[0]);
if (arena1 == null) {
- commandSender.sendMessage("Unable to find the first specified dropper arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_1_NOT_FOUND.getMessage());
return false;
}
DropperArena arena2 = arenaHandler.getArena(arguments[1]);
if (arena2 == null) {
- commandSender.sendMessage("Unable to find the second specified dropper arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_2_NOT_FOUND.getMessage());
return false;
}
DropperArenaGroup arena1Group = arenaHandler.getGroup(arena1.getArenaId());
DropperArenaGroup arena2Group = arenaHandler.getGroup(arena2.getArenaId());
if (arena1Group == null || !arena1Group.equals(arena2Group)) {
- commandSender.sendMessage("You cannot swap arenas in different groups!");
+ commandSender.sendMessage(Message.ERROR_SWAP_DIFFERENT_GROUPS.getMessage());
return false;
}
arena1Group.swapArenas(arena1Group.getArenas().indexOf(arena1.getArenaId()),
arena1Group.getArenas().indexOf(arena2.getArenaId()));
- commandSender.sendMessage("The arenas have been swapped!");
+ commandSender.sendMessage(Message.SUCCESS_ARENAS_SWAPPED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaCommand.java
index 2e6eb30..7152f30 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaCommand.java
@@ -4,6 +4,8 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
import net.knarcraft.minigames.config.DropperConfiguration;
+import net.knarcraft.minigames.config.Message;
+import net.knarcraft.minigames.container.PlaceholderContainer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
@@ -32,7 +34,7 @@ public class EditDropperArenaCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
@@ -42,29 +44,29 @@ public class EditDropperArenaCommand implements CommandExecutor {
DropperArena specifiedArena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[0]);
if (specifiedArena == null) {
- commandSender.sendMessage("Unable to find the specified dropper arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
DropperArenaEditableProperty editableProperty = DropperArenaEditableProperty.getFromArgumentString(arguments[1]);
if (editableProperty == null) {
- commandSender.sendMessage("Unknown property specified.");
+ commandSender.sendMessage(Message.ERROR_UNKNOWN_PROPERTY.getMessage());
return false;
}
- String currentValueFormat = "Current value of %s is: %s";
-
if (arguments.length < 3) {
// Print the current value of the property
String value = editableProperty.getCurrentValueAsString(specifiedArena);
- commandSender.sendMessage(String.format(currentValueFormat, editableProperty.getArgumentString(), value));
+ commandSender.sendMessage(Message.SUCCESS_CURRENT_VALUE.getMessage(new PlaceholderContainer().add(
+ "{property}", editableProperty.getArgumentString()).add("{value}", value)));
return true;
} else {
boolean successful = changeValue(specifiedArena, editableProperty, arguments[2], player);
if (successful) {
- player.sendMessage(String.format("Property %s changed to: %s", editableProperty, arguments[2]));
+ player.sendMessage(Message.SUCCESS_PROPERTY_CHANGED.getMessage("{property}",
+ editableProperty.getArgumentString()));
} else {
- player.sendMessage("Unable to change the property. Make sure your input is valid!");
+ player.sendMessage(Message.ERROR_PROPERTY_INPUT_INVALID.getMessage());
}
return successful;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
index 155e99e..bd45a53 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
@@ -7,6 +7,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaPlayerRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
import net.knarcraft.minigames.config.DropperConfiguration;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.PlayerTeleporter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -23,7 +24,7 @@ public class JoinDropperArenaCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
@@ -33,20 +34,20 @@ public class JoinDropperArenaCommand implements CommandExecutor {
// Disallow joining if the player is already in a mini-game arena
if (MiniGames.getInstance().getSession(player.getUniqueId()) != null) {
- commandSender.sendMessage("You are already playing a mini-game!");
+ commandSender.sendMessage(Message.ERROR_ALREADY_PLAYING.getMessage());
return false;
}
// Make sure the arena exists
DropperArena specifiedArena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[0]);
if (specifiedArena == null) {
- commandSender.sendMessage("Unable to find the specified dropper arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
// Deny vehicles as allowing this is tricky, and will cause problems in some cases
if (player.isInsideVehicle() || !player.getPassengers().isEmpty()) {
- commandSender.sendMessage("You cannot join an arena while inside a vehicle or carrying a passenger.");
+ commandSender.sendMessage(Message.ERROR_JOIN_IN_VEHICLE_OR_PASSENGER.getMessage());
return false;
}
@@ -80,7 +81,7 @@ public class JoinDropperArenaCommand implements CommandExecutor {
if (MiniGames.getInstance().getDropperConfiguration().mustDoNormalModeFirst() &&
gameMode != DropperArenaGameMode.DEFAULT &&
specifiedArena.getData().hasNotCompleted(DropperArenaGameMode.DEFAULT, player)) {
- player.sendMessage("You must complete this arena in normal mode first!");
+ player.sendMessage(Message.ERROR_NORMAL_MODE_REQUIRED.getMessage());
return false;
}
@@ -92,8 +93,7 @@ public class JoinDropperArenaCommand implements CommandExecutor {
// Try to teleport the player to the arena
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false);
if (!teleported) {
- player.sendMessage("Unable to teleport you to the dropper arena. Make sure you're not in a vehicle," +
- "and not carrying a passenger!");
+ player.sendMessage(Message.ERROR_ARENA_TELEPORT_FAILED.getMessage());
newSession.triggerQuit(false);
return false;
} else {
@@ -118,14 +118,14 @@ public class JoinDropperArenaCommand implements CommandExecutor {
// Require that players beat all arenas in the group in the normal game-mode before trying challenge modes
if (configuration.mustDoNormalModeFirst() && arenaGameMode != DropperArenaGameMode.DEFAULT &&
!arenaGroup.hasBeatenAll(DropperArenaGameMode.DEFAULT, player)) {
- player.sendMessage("You have not yet beaten all arenas in this group!");
+ player.sendMessage(Message.ERROR_GROUP_NORMAL_MODE_REQUIRED.getMessage());
return false;
}
// Require that the player has beaten the previous arena on the same game-mode before trying this one
if (configuration.mustDoGroupedInSequence() &&
arenaGroup.cannotPlay(arenaGameMode, player, dropperArena.getArenaId())) {
- player.sendMessage("You have not yet beaten the previous arena!");
+ player.sendMessage(Message.ERROR_PREVIOUS_ARENA_REQUIRED.getMessage());
return false;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/ListDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/ListDropperArenaCommand.java
index 16e6487..36f6f52 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/ListDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/ListDropperArenaCommand.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames.command.dropper;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.TabCompleteHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -18,10 +19,11 @@ public class ListDropperArenaCommand implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] arguments) {
- sender.sendMessage("Dropper arenas:");
+ StringBuilder builder = new StringBuilder(Message.SUCCESS_DROPPER_ARENAS_LIST.getMessage());
for (String arenaName : TabCompleteHelper.getDropperArenas()) {
- sender.sendMessage(arenaName);
+ builder.append("\n").append(arenaName);
}
+ sender.sendMessage(builder.toString());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaCommand.java
index 861a537..0d3be62 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaCommand.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.command.dropper;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.dropper.DropperArena;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -23,13 +24,13 @@ public class RemoveDropperArenaCommand implements CommandExecutor {
// Get the specified arena
DropperArena targetArena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[0]);
if (targetArena == null) {
- commandSender.sendMessage("Unable to find the specified arena");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
// Remove the arena
MiniGames.getInstance().getDropperArenaHandler().removeArena(targetArena);
- commandSender.sendMessage("The specified arena has been successfully removed");
+ commandSender.sendMessage(Message.SUCCESS_ARENA_REMOVED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/CreateParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/CreateParkourArenaCommand.java
index 0cb281c..08be9ad 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/CreateParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/CreateParkourArenaCommand.java
@@ -3,6 +3,7 @@ package net.knarcraft.minigames.command.parkour;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.StringSanitizer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -19,7 +20,7 @@ public class CreateParkourArenaCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
@@ -40,13 +41,13 @@ public class CreateParkourArenaCommand implements CommandExecutor {
ParkourArena existingArena = arenaHandler.getArena(arenaName);
if (existingArena != null) {
- commandSender.sendMessage("There already exists a parkour arena with that name!");
+ commandSender.sendMessage(Message.ERROR_ARENA_NAME_COLLISION.getMessage());
return false;
}
ParkourArena arena = new ParkourArena(arenaName, player.getLocation(), arenaHandler);
arenaHandler.addArena(arena);
- commandSender.sendMessage("The arena was successfully created!");
+ commandSender.sendMessage(Message.SUCCESS_ARENA_CREATED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaCommand.java
index 8c563cb..8eb128e 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaCommand.java
@@ -3,6 +3,8 @@ package net.knarcraft.minigames.command.parkour;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty;
+import net.knarcraft.minigames.config.Message;
+import net.knarcraft.minigames.container.PlaceholderContainer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
@@ -29,7 +31,7 @@ public class EditParkourArenaCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
@@ -39,29 +41,29 @@ public class EditParkourArenaCommand implements CommandExecutor {
ParkourArena specifiedArena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[0]);
if (specifiedArena == null) {
- commandSender.sendMessage("Unable to find the specified dropper arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
ParkourArenaEditableProperty editableProperty = ParkourArenaEditableProperty.getFromArgumentString(arguments[1]);
if (editableProperty == null) {
- commandSender.sendMessage("Unknown property specified.");
+ commandSender.sendMessage(Message.ERROR_UNKNOWN_PROPERTY.getMessage());
return false;
}
- String currentValueFormat = "Current value of %s is: %s";
-
if (arguments.length < 3) {
// Print the current value of the property
String value = editableProperty.getCurrentValueAsString(specifiedArena);
- commandSender.sendMessage(String.format(currentValueFormat, editableProperty.getArgumentString(), value));
+ commandSender.sendMessage(Message.SUCCESS_CURRENT_VALUE.getMessage(new PlaceholderContainer().add(
+ "{property}", editableProperty.getArgumentString()).add("{value}", value)));
return true;
} else {
boolean successful = changeValue(specifiedArena, editableProperty, arguments[2], player);
if (successful) {
- player.sendMessage(String.format("Property %s changed to: %s", editableProperty, arguments[2]));
+ player.sendMessage(Message.SUCCESS_PROPERTY_CHANGED.getMessage("{property}",
+ editableProperty.getArgumentString()));
} else {
- player.sendMessage("Unable to change the property. Make sure your input is valid!");
+ player.sendMessage(Message.ERROR_PROPERTY_INPUT_INVALID.getMessage());
}
return successful;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
index 2174511..7a02f16 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
@@ -6,6 +6,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
import net.knarcraft.minigames.arena.parkour.ParkourArenaPlayerRegistry;
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.config.ParkourConfiguration;
import net.knarcraft.minigames.util.PlayerTeleporter;
import org.bukkit.command.Command;
@@ -23,7 +24,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
@NotNull String[] arguments) {
if (!(commandSender instanceof Player player)) {
- commandSender.sendMessage("This command must be used by a player");
+ commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
return false;
}
@@ -33,20 +34,20 @@ public class JoinParkourArenaCommand implements CommandExecutor {
// Disallow joining if the player is already in a mini-game arena
if (MiniGames.getInstance().getSession(player.getUniqueId()) != null) {
- commandSender.sendMessage("You are already playing a mini-game!");
+ commandSender.sendMessage(Message.ERROR_ALREADY_PLAYING.getMessage());
return false;
}
// Make sure the arena exists
ParkourArena specifiedArena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[0]);
if (specifiedArena == null) {
- commandSender.sendMessage("Unable to find the specified parkour arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
// Deny vehicles as allowing this is tricky, and will cause problems in some cases
if (player.isInsideVehicle() || !player.getPassengers().isEmpty()) {
- commandSender.sendMessage("You cannot join an arena while inside a vehicle or carrying a passenger.");
+ commandSender.sendMessage(Message.ERROR_JOIN_IN_VEHICLE_OR_PASSENGER.getMessage());
return false;
}
@@ -84,8 +85,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
// Try to teleport the player to the arena
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false);
if (!teleported) {
- player.sendMessage("Unable to teleport you to the parkour arena. Make sure you're not in a vehicle," +
- "and not carrying a passenger!");
+ player.sendMessage(Message.ERROR_ARENA_TELEPORT_FAILED.getMessage());
newSession.triggerQuit(false);
return false;
} else {
@@ -111,7 +111,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
// Require that the player has beaten the previous arena on the same game-mode before trying this one
if (configuration.mustDoGroupedInSequence() &&
arenaGroup.cannotPlay(arenaGameMode, player, parkourArena.getArenaId())) {
- player.sendMessage("You have not yet beaten the previous arena!");
+ player.sendMessage(Message.ERROR_PREVIOUS_ARENA_REQUIRED.getMessage());
return false;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ListParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ListParkourArenaCommand.java
index 212f5db..884f9b3 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ListParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ListParkourArenaCommand.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames.command.parkour;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.TabCompleteHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -18,10 +19,11 @@ public class ListParkourArenaCommand implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] arguments) {
- sender.sendMessage("Parkour arenas:");
+ StringBuilder builder = new StringBuilder(Message.SUCCESS_PARKOUR_ARENAS_LIST.getMessage());
for (String arenaName : TabCompleteHelper.getParkourArenas()) {
- sender.sendMessage(arenaName);
+ builder.append("\n").append(arenaName);
}
+ sender.sendMessage(builder.toString());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java
index cb423db..8e69d65 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java
@@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -61,17 +62,17 @@ public class ParkourGroupListCommand implements TabExecutor {
@NotNull String groupName) {
ParkourArenaGroup arenaGroup = arenaHandler.getGroup(groupName);
if (arenaGroup == null) {
- sender.sendMessage("Unable to find the specified group!");
+ sender.sendMessage(Message.ERROR_GROUP_NOT_FOUND.getMessage());
return false;
}
// Send a list of all stages (arenas in the group)
- StringBuilder builder = new StringBuilder(groupName).append("'s stages:").append("\n");
+ StringBuilder builder = new StringBuilder(Message.SUCCESS_GROUP_STAGES.getMessage("{group}", groupName));
int counter = 1;
for (UUID arenaId : arenaGroup.getArenas()) {
ParkourArena arena = arenaHandler.getArena(arenaId);
if (arena != null) {
- builder.append(counter++).append(". ").append(arena.getArenaName()).append("\n");
+ builder.append("\n").append(counter++).append(". ").append(arena.getArenaName());
}
}
sender.sendMessage(builder.toString());
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java
index 01e13e3..7a60fae 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java
@@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.StringSanitizer;
import net.knarcraft.minigames.util.TabCompleteHelper;
import org.bukkit.command.Command;
@@ -33,7 +34,7 @@ public class ParkourGroupSetCommand implements TabExecutor {
ParkourArena specifiedArena = arenaHandler.getArena(arguments[0]);
if (specifiedArena == null) {
- commandSender.sendMessage("Unable to find the specified parkour arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
@@ -55,7 +56,7 @@ public class ParkourGroupSetCommand implements TabExecutor {
arenaHandler.setGroup(specifiedArena.getArenaId(), arenaGroup);
- commandSender.sendMessage("The arena's group has been updated");
+ commandSender.sendMessage(Message.SUCCESS_ARENA_GROUP_UPDATED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java
index 283c53f..a0c9784 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java
@@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@@ -32,26 +33,26 @@ public class ParkourGroupSwapCommand implements TabExecutor {
ParkourArena arena1 = arenaHandler.getArena(arguments[0]);
if (arena1 == null) {
- commandSender.sendMessage("Unable to find the first specified parkour arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_1_NOT_FOUND.getMessage());
return false;
}
ParkourArena arena2 = arenaHandler.getArena(arguments[1]);
if (arena2 == null) {
- commandSender.sendMessage("Unable to find the second specified parkour arena.");
+ commandSender.sendMessage(Message.ERROR_ARENA_2_NOT_FOUND.getMessage());
return false;
}
ParkourArenaGroup arena1Group = arenaHandler.getGroup(arena1.getArenaId());
ParkourArenaGroup arena2Group = arenaHandler.getGroup(arena2.getArenaId());
if (arena1Group == null || !arena1Group.equals(arena2Group)) {
- commandSender.sendMessage("You cannot swap arenas in different groups!");
+ commandSender.sendMessage(Message.ERROR_SWAP_DIFFERENT_GROUPS.getMessage());
return false;
}
arena1Group.swapArenas(arena1Group.getArenas().indexOf(arena1.getArenaId()),
arena1Group.getArenas().indexOf(arena2.getArenaId()));
- commandSender.sendMessage("The arenas have been swapped!");
+ commandSender.sendMessage(Message.SUCCESS_ARENAS_SWAPPED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaCommand.java
index 7aaa7c8..dc4ee3e 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaCommand.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.command.parkour;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -23,13 +24,13 @@ public class RemoveParkourArenaCommand implements CommandExecutor {
// Get the specified arena
ParkourArena targetArena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[0]);
if (targetArena == null) {
- commandSender.sendMessage("Unable to find the specified arena");
+ commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
return false;
}
// Remove the arena
MiniGames.getInstance().getParkourArenaHandler().removeArena(targetArena);
- commandSender.sendMessage("The specified arena has been successfully removed");
+ commandSender.sendMessage(Message.SUCCESS_ARENA_REMOVED.getMessage());
return true;
}
diff --git a/src/main/java/net/knarcraft/minigames/config/Message.java b/src/main/java/net/knarcraft/minigames/config/Message.java
new file mode 100644
index 0000000..8cf9654
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/config/Message.java
@@ -0,0 +1,111 @@
+package net.knarcraft.minigames.config;
+
+import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.container.PlaceholderContainer;
+import net.knarcraft.minigames.util.ColorHelper;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * A message which ca be displayed to the user
+ */
+public enum Message {
+
+ ERROR_CANNOT_SAVE_ARENA_GROUPS("&cUnable to save current arena groups! Data loss can occur!"),
+ ERROR_MATERIAL_NOT_PARSE_ABLE("&cUnable to parse material: {material}"),
+ ERROR_TELEPORT_WITH_PASSENGER("&cYou cannot be teleported with a passenger!"),
+ ERROR_TELEPORT_IN_VEHICLE("&cYou cannot be teleported while in a vehicle"),
+ ERROR_ARENA_NOT_LOADED("&cCould not load the arena at configuration section {section}. Please check " +
+ "the {file} storage file for issues."),
+ ERROR_ARENA_DATA_NOT_LOADED("&cUnable to load arena data for dropper arena: {arena}"),
+ ERROR_ARENA_NOT_FOUND("&cUnable to find the specified arena."),
+ ERROR_GROUP_NOT_FOUND("&cUnable to find the specified group!"),
+ ERROR_PLAYER_ONLY("&cThis command must be used by a player"),
+ ERROR_ARENA_NAME_COLLISION("&cThere already exists an arena with that name!"),
+ ERROR_NORMAL_MODE_REQUIRED("&cYou must complete this arena in normal mode first!"),
+ ERROR_GROUP_NORMAL_MODE_REQUIRED("&cYou have not yet beaten the default game-mode for all arenas in this group!"),
+ ERROR_PREVIOUS_ARENA_REQUIRED("&cYou have not yet beaten the previous arena!"),
+ ERROR_ARENA_TELEPORT_FAILED("&cUnable to teleport you to the arena."),
+ ERROR_NOT_IN_ARENA("&cYou are not in a mini-games arena!"),
+ ERROR_ALREADY_PLAYING("&cYou are already playing a mini-game!"),
+ ERROR_JOIN_IN_VEHICLE_OR_PASSENGER("&cYou cannot join an arena while inside a vehicle or carrying a passenger."),
+ ERROR_UNKNOWN_PROPERTY("&cUnknown property specified."),
+ ERROR_PROPERTY_INPUT_INVALID("&cUnable to change the property. Make sure your input is valid!"),
+ ERROR_ARENA_1_NOT_FOUND("&cUnable to find the first specified arena."),
+ ERROR_ARENA_2_NOT_FOUND("&cUnable to find the second specified dropper arena."),
+ ERROR_SWAP_DIFFERENT_GROUPS("&cYou cannot swap arenas in different groups!"),
+ ERROR_ILLEGAL_COMMAND("&cYou cannot use that command while in an arena!"),
+ SUCCESS_ARENA_GROUP_UPDATED("&aThe arena's group has been updated"),
+ SUCCESS_PLUGIN_RELOADED("&aPlugin reloaded!"),
+ SUCCESS_ARENA_CREATED("&aThe arena was successfully created!"),
+ SUCCESS_ARENA_FIRST_CLEAR("&aYou cleared the arena!"),
+ SUCCESS_ARENA_WIN("&aYou won!"),
+ SUCCESS_ARENA_QUIT("&aYou quit the arena!"),
+ SUCCESS_CURRENT_VALUE("&aCurrent value of {property} is: {value}"),
+ SUCCESS_PROPERTY_CHANGED("&aProperty {property} successfully changed"),
+ SUCCESS_ARENAS_SWAPPED("&aThe arenas have been swapped!"),
+ SUCCESS_ARENA_REMOVED("&aThe specified arena has been successfully removed"),
+ SUCCESS_DROPPER_ARENAS_LIST("&aDropper arenas:&r"),
+ SUCCESS_PARKOUR_ARENAS_LIST("&aParkour arenas:&r"),
+ SUCCESS_CHECKPOINT_REACHED("&aCheckpoint reached!"),
+ SUCCESS_GROUP_STAGES("&a{group}'s stages:&r"),
+ ;
+
+ private final @NotNull String defaultMessage;
+
+ /**
+ * Instantiates a new message
+ *
+ * @param defaultMessage The default value of the message
+ */
+ Message(@NotNull String defaultMessage) {
+ this.defaultMessage = defaultMessage;
+ }
+
+ /**
+ * Gets the message this enum represents
+ *
+ * @return The formatted message
+ */
+ public @NotNull String getMessage() {
+ return formatMessage(this.defaultMessage);
+ }
+
+ /**
+ * Gets the message this enum represents
+ *
+ * @param placeholder The placeholder to replace
+ * @param replacement The replacement to use
+ * @return The formatted message
+ */
+ public @NotNull String getMessage(@NotNull String placeholder, @NotNull String replacement) {
+ return formatMessage(this.defaultMessage.replace(placeholder, replacement));
+ }
+
+ /**
+ * Gets the message this enum represents
+ *
+ * @param placeholders The placeholder -> replacement map specifying necessary replacements
+ * @return The formatted message
+ */
+ public @NotNull String getMessage(@NotNull PlaceholderContainer placeholders) {
+ String replaced = this.defaultMessage;
+ for (Map.Entry entry : placeholders.getPlaceholders().entrySet()) {
+ replaced = replaced.replace(entry.getKey(), entry.getValue());
+ }
+ return formatMessage(replaced);
+ }
+
+ /**
+ * Gets the formatted version of the given message
+ *
+ * @param message The message to format
+ * @return The formatted message
+ */
+ private @NotNull String formatMessage(@NotNull String message) {
+ String prefix = MiniGames.getInstance().getDescription().getPrefix();
+ return ColorHelper.translateAllColorCodes("#546EED[&r&l" + prefix + "#546EED]&r " + message);
+ }
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java b/src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java
new file mode 100644
index 0000000..ca88158
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java
@@ -0,0 +1,41 @@
+package net.knarcraft.minigames.container;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A container for keeping track of several placeholder to value mappings
+ */
+public class PlaceholderContainer {
+
+ private final Map placeholders;
+
+ /**
+ * Instantiates a new placeholder container
+ */
+ public PlaceholderContainer() {
+ this.placeholders = new HashMap<>();
+ }
+
+ /**
+ * Gets all placeholders
+ *
+ * @return All placeholders
+ */
+ public Map getPlaceholders() {
+ return new HashMap<>(this.placeholders);
+ }
+
+ /**
+ * Adds a new placeholder
+ *
+ * @param placeholder The placeholder to register
+ * @param value The value of the placeholder
+ * @return This object
+ */
+ public PlaceholderContainer add(String placeholder, String value) {
+ this.placeholders.put(placeholder, value);
+ return this;
+ }
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java
index 05391d8..112231d 100644
--- a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java
+++ b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.listener;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaSession;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -40,7 +41,7 @@ public class CommandListener implements Listener {
}
}
- player.sendMessage("You cannot use that command while in an arena!");
+ player.sendMessage(Message.ERROR_ILLEGAL_COMMAND.getMessage());
event.setCancelled(true);
}
diff --git a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java
index c9c2120..42f7630 100644
--- a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java
+++ b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java
@@ -8,6 +8,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
import net.knarcraft.minigames.config.DropperConfiguration;
+import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.config.ParkourConfiguration;
import net.knarcraft.minigames.config.SharedConfiguration;
import org.bukkit.Location;
@@ -80,19 +81,30 @@ public class MoveListener implements Listener {
List checkpoints = arena.getCheckpoints();
for (Location checkpoint : checkpoints) {
Location previousCheckpoint = arenaSession.getRegisteredCheckpoint();
- if (checkpoint.getBlock().equals(event.getTo().getBlock()) && !checkpoint.equals(previousCheckpoint)) {
- if (parkourConfiguration.enforceCheckpointOrder()) {
- int checkpointIndex = checkpoints.indexOf(checkpoint);
- int previousIndex = previousCheckpoint == null ? -1 : checkpoints.indexOf(previousCheckpoint);
- if (checkpointIndex - previousIndex != 1) {
- continue;
- }
- }
- arenaSession.registerCheckpoint(checkpoint.clone());
- event.getPlayer().sendMessage("Checkpoint reached!");
+ // Skip if checkpoint has not been reached
+ if (!checkpoint.getBlock().equals(event.getTo().getBlock())) {
+ continue;
+ }
+
+ // If the checkpoint is the same as the previously reached one, abort
+ if (previousCheckpoint != null && checkpoint.getBlock().equals(previousCheckpoint.getBlock())) {
return;
}
+
+ // If not the correct checkpoint according to the enforced order, abort
+ if (parkourConfiguration.enforceCheckpointOrder()) {
+ int checkpointIndex = checkpoints.indexOf(checkpoint);
+ int previousIndex = previousCheckpoint == null ? -1 : checkpoints.indexOf(previousCheckpoint);
+ if (checkpointIndex - previousIndex != 1) {
+ return;
+ }
+ }
+
+ // Register the checkpoint
+ arenaSession.registerCheckpoint(checkpoint.clone());
+ event.getPlayer().sendMessage(Message.SUCCESS_CHECKPOINT_REACHED.getMessage());
+ return;
}
}
diff --git a/src/main/java/net/knarcraft/minigames/util/ColorHelper.java b/src/main/java/net/knarcraft/minigames/util/ColorHelper.java
new file mode 100644
index 0000000..4b79d19
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/util/ColorHelper.java
@@ -0,0 +1,29 @@
+package net.knarcraft.minigames.util;
+
+import net.md_5.bungee.api.ChatColor;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A helper class for converting colors
+ */
+public class ColorHelper {
+
+ /**
+ * Translates all found color codes to formatting in a string
+ *
+ * @param message The string to search for color codes
+ * @return The message with color codes translated
+ */
+ public static String translateAllColorCodes(String message) {
+ message = ChatColor.translateAlternateColorCodes('&', message);
+ Pattern pattern = Pattern.compile("&?(#[a-fA-F0-9]{6})");
+ Matcher matcher = pattern.matcher(message);
+ while (matcher.find()) {
+ message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group(1)));
+ }
+ return message;
+ }
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java b/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java
index b158669..524b736 100644
--- a/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java
+++ b/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java
@@ -9,6 +9,8 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaStorageKey;
+import net.knarcraft.minigames.config.Message;
+import net.knarcraft.minigames.container.PlaceholderContainer;
import net.knarcraft.minigames.container.SerializableMaterial;
import net.knarcraft.minigames.container.SerializableUUID;
import org.bukkit.Location;
@@ -159,8 +161,8 @@ public final class DropperArenaStorageHelper {
DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey());
if (arenaName == null || spawnLocation == null) {
- MiniGames.log(Level.SEVERE, "Could not load the arena at configuration " +
- "section " + configurationSection.getName() + ". Please check the dropper_arenas storage file for issues.");
+ MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_NOT_LOADED.getMessage(new PlaceholderContainer().add(
+ "{section}", configurationSection.getName()).add("{file}", "dropper_arenas")));
return null;
}
if (winBlockType == null) {
@@ -170,7 +172,8 @@ public final class DropperArenaStorageHelper {
// Generate new, empty arena data if not available
DropperArenaData arenaData = loadDropperArenaData(arenaId);
if (arenaData == null) {
- MiniGames.log(Level.SEVERE, "Unable to load arena data for dropper arena" + arenaId);
+ MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_DATA_NOT_LOADED.getMessage("{arena}",
+ arenaId.toString()));
arenaData = getEmptyDropperData(arenaId);
}
diff --git a/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java b/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java
index 821ba9a..2a50b5a 100644
--- a/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java
+++ b/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java
@@ -1,6 +1,7 @@
package net.knarcraft.minigames.util;
import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@@ -43,7 +44,7 @@ public final class MaterialHelper {
if (matched != null) {
parsedMaterials.add(matched);
} else {
- MiniGames.log(Level.WARNING, "Unable to parse: " + string);
+ MiniGames.log(Level.WARNING, Message.ERROR_MATERIAL_NOT_PARSE_ABLE.getMessage("{material}", string));
}
}
return parsedMaterials;
diff --git a/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java b/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java
index a1d2aff..375ab4b 100644
--- a/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java
+++ b/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java
@@ -9,6 +9,8 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
import net.knarcraft.minigames.arena.parkour.ParkourArenaRecordsRegistry;
import net.knarcraft.minigames.arena.parkour.ParkourArenaStorageKey;
+import net.knarcraft.minigames.config.Message;
+import net.knarcraft.minigames.container.PlaceholderContainer;
import net.knarcraft.minigames.container.SerializableMaterial;
import net.knarcraft.minigames.container.SerializableUUID;
import org.bukkit.Location;
@@ -164,8 +166,8 @@ public final class ParkourArenaStorageHelper {
// The arena name and spawn location must be present
if (arenaName == null || spawnLocation == null) {
- MiniGames.log(Level.SEVERE, "Could not load the arena at configuration " +
- "section " + configurationSection.getName() + ". Please check the parkour_arenas storage file for issues.");
+ MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_NOT_LOADED.getMessage(new PlaceholderContainer().add(
+ "{section}", configurationSection.getName()).add("{file}", "parkour_arena")));
return null;
}
@@ -177,7 +179,8 @@ public final class ParkourArenaStorageHelper {
// Generate new, empty arena data if not available
ParkourArenaData arenaData = loadParkourArenaData(arenaId);
if (arenaData == null) {
- MiniGames.log(Level.SEVERE, "Unable to load arena data for parkour arena" + arenaId);
+ MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_DATA_NOT_LOADED.getMessage("{arena}",
+ arenaId.toString()));
arenaData = getEmptyParkourData(arenaId);
}
diff --git a/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java b/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java
index 4265ec5..974a042 100644
--- a/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java
+++ b/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java
@@ -1,6 +1,7 @@
package net.knarcraft.minigames.util;
import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.config.Message;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@@ -35,7 +36,7 @@ public final class PlayerTeleporter {
passenger.teleport(location);
}
} else {
- player.sendMessage("You cannot be teleported with a passenger!");
+ player.sendMessage(Message.ERROR_TELEPORT_WITH_PASSENGER.getMessage());
return false;
}
}
@@ -45,16 +46,16 @@ public final class PlayerTeleporter {
player.eject();
vehicle.teleport(location);
} else {
- player.sendMessage("You cannot be teleported while in a vehicle");
+ player.sendMessage(Message.ERROR_TELEPORT_IN_VEHICLE.getMessage());
return false;
}
}
- //Stop the existing player velocity to prevent unevenness between players
+ // Stop the existing player velocity to prevent unevenness between players
player.setVelocity(new Vector(0, 0, 0));
player.setInvulnerable(true);
player.teleport(location);
player.setVelocity(new Vector(0, 0, 0));
- //When teleporting a player out of the arena, sometimes the move listener is slow to react, giving the player
+ // When teleporting a player out of the arena, sometimes the move listener is slow to react, giving the player
// lethal velocity, and causing damage. That's why the player is given 5 ticks of invulnerability
if (!immediately) {
Bukkit.getScheduler().runTaskLater(MiniGames.getInstance(), () -> player.setInvulnerable(false), 5);
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 917919f..c548273 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,4 +1,5 @@
name: MiniGames
+prefix: MiniGames
version: '${project.version}'
main: net.knarcraft.minigames.MiniGames
api-version: 1.19
From b2fbaf0e68aec516e7d39b0c28cc46c0fecd6cf7 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Tue, 25 Apr 2023 13:11:11 +0200
Subject: [PATCH 4/9] Removes some redundancy between various classes
---
.../net/knarcraft/minigames/MiniGames.java | 12 +-
.../arena/AbstractArenaPlayerRegistry.java | 52 ++++++
.../minigames/arena/AbstractArenaSession.java | 118 ++++++++++++++
.../net/knarcraft/minigames/arena/Arena.java | 8 +
.../minigames/arena/ArenaPlayerRegistry.java | 28 ++++
.../minigames/arena/ArenaSession.java | 15 --
.../minigames/arena/dropper/DropperArena.java | 6 +-
.../arena/dropper/DropperArenaHandler.java | 3 +-
.../dropper/DropperArenaPlayerRegistry.java | 53 +-----
.../arena/dropper/DropperArenaSession.java | 151 ++++-------------
.../minigames/arena/parkour/ParkourArena.java | 6 +-
.../arena/parkour/ParkourArenaHandler.java | 3 +-
.../parkour/ParkourArenaPlayerRegistry.java | 53 +-----
.../arena/parkour/ParkourArenaSession.java | 153 +++---------------
.../dropper/JoinDropperArenaCommand.java | 4 +-
.../parkour/JoinParkourArenaCommand.java | 4 +-
.../knarcraft/minigames/config/Message.java | 3 +
17 files changed, 285 insertions(+), 387 deletions(-)
create mode 100644 src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java
create mode 100644 src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java
diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java
index 756c92b..cf7e3f6 100644
--- a/src/main/java/net/knarcraft/minigames/MiniGames.java
+++ b/src/main/java/net/knarcraft/minigames/MiniGames.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames;
+import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaData;
@@ -8,7 +9,6 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
import net.knarcraft.minigames.arena.dropper.DropperArenaPlayerRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
-import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaData;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
@@ -77,11 +77,11 @@ public final class MiniGames extends JavaPlugin {
private DropperConfiguration dropperConfiguration;
private ParkourConfiguration parkourConfiguration;
private DropperArenaHandler dropperArenaHandler;
- private DropperArenaPlayerRegistry dropperArenaPlayerRegistry;
+ private ArenaPlayerRegistry dropperArenaPlayerRegistry;
private DropperRecordExpansion dropperRecordExpansion;
private ParkourRecordExpansion parkourRecordExpansion;
private ParkourArenaHandler parkourArenaHandler;
- private ParkourArenaPlayerRegistry parkourArenaPlayerRegistry;
+ private ArenaPlayerRegistry parkourArenaPlayerRegistry;
/**
* Gets an instance of this plugin
@@ -115,7 +115,7 @@ public final class MiniGames extends JavaPlugin {
*
* @return A dropper arena player registry
*/
- public DropperArenaPlayerRegistry getDropperArenaPlayerRegistry() {
+ public ArenaPlayerRegistry getDropperArenaPlayerRegistry() {
return this.dropperArenaPlayerRegistry;
}
@@ -124,7 +124,7 @@ public final class MiniGames extends JavaPlugin {
*
* @return A parkour arena player registry
*/
- public ParkourArenaPlayerRegistry getParkourArenaPlayerRegistry() {
+ public ArenaPlayerRegistry getParkourArenaPlayerRegistry() {
return this.parkourArenaPlayerRegistry;
}
@@ -164,7 +164,7 @@ public final class MiniGames extends JavaPlugin {
* @return The player's current session, or null if not found
*/
public @Nullable ArenaSession getSession(@NotNull UUID playerId) {
- DropperArenaSession dropperArenaSession = dropperArenaPlayerRegistry.getArenaSession(playerId);
+ ArenaSession dropperArenaSession = dropperArenaPlayerRegistry.getArenaSession(playerId);
if (dropperArenaSession != null) {
return dropperArenaSession;
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java
new file mode 100644
index 0000000..3ebbce7
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java
@@ -0,0 +1,52 @@
+package net.knarcraft.minigames.arena;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * A player registry to keep track of currently playing players
+ *
+ * @param The type of arena stored
+ */
+public abstract class AbstractArenaPlayerRegistry implements ArenaPlayerRegistry {
+
+ private final Map arenaPlayers = new HashMap<>();
+ private final Map entryStates = new HashMap<>();
+
+ //TODO: Save all entry states each time the map changes
+ //TODO: If a player joins, and their entry state exists, restore the state
+
+ @Override
+ public void registerPlayer(@NotNull UUID playerId, @NotNull ArenaSession arenaSession) {
+ this.arenaPlayers.put(playerId, arenaSession);
+ this.entryStates.put(playerId, arenaSession.getEntryState());
+ }
+
+ @Override
+ public boolean removePlayer(@NotNull UUID playerId) {
+ this.entryStates.remove(playerId);
+ return this.arenaPlayers.remove(playerId) != null;
+ }
+
+ @Override
+ public @Nullable ArenaSession getArenaSession(@NotNull UUID playerId) {
+ return this.arenaPlayers.getOrDefault(playerId, null);
+ }
+
+ @Override
+ public void removeForArena(K arena, boolean immediately) {
+ for (Map.Entry entry : this.arenaPlayers.entrySet()) {
+ if (entry.getValue().getArena() == arena) {
+ // Kick the player gracefully
+ entry.getValue().triggerQuit(immediately);
+ this.arenaPlayers.remove(entry.getKey());
+ this.entryStates.remove(entry.getKey());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java
new file mode 100644
index 0000000..8000243
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java
@@ -0,0 +1,118 @@
+package net.knarcraft.minigames.arena;
+
+import net.knarcraft.minigames.config.Message;
+import net.knarcraft.minigames.container.PlaceholderContainer;
+import net.knarcraft.minigames.property.RecordResult;
+import net.knarcraft.minigames.util.PlayerTeleporter;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class AbstractArenaSession implements ArenaSession {
+
+ private final @NotNull Arena arena;
+ private final @NotNull ArenaGameMode gameMode;
+ private final @NotNull Player player;
+ protected int deaths;
+ protected final long startTime;
+ protected PlayerEntryState entryState;
+
+ /**
+ * Instantiates a new abstract arena session
+ *
+ * @param arena The arena that's being played in
+ * @param player The player playing the arena
+ * @param gameMode The game-mode
+ */
+ public AbstractArenaSession(@NotNull Arena arena, @NotNull Player player, @NotNull ArenaGameMode gameMode) {
+ this.arena = arena;
+ this.player = player;
+ this.gameMode = gameMode;
+ this.deaths = 0;
+ this.startTime = System.currentTimeMillis();
+ }
+
+ @Override
+ public void triggerQuit(boolean immediately) {
+ // Stop this session
+ stopSession();
+ // Teleport the player out of the arena
+ teleportToExit(immediately);
+
+ player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage());
+ }
+
+ /**
+ * Announces a record set by this player
+ *
+ * @param recordResult The result of the record
+ * @param type The type of record set (time or deaths)
+ */
+ protected void announceRecord(@NotNull RecordResult recordResult, @NotNull String type) {
+ if (recordResult == RecordResult.NONE) {
+ return;
+ }
+
+ // Gets a string representation of the played game-mode
+ String gameModeString = getGameModeString();
+
+ Message recordInfoMessage = switch (recordResult) {
+ case WORLD_RECORD -> Message.RECORD_ACHIEVED_GLOBAL;
+ case PERSONAL_BEST -> Message.RECORD_ACHIEVED_PERSONAL;
+ default -> throw new IllegalStateException("Unexpected value: " + recordResult);
+ };
+ String recordInfo = recordInfoMessage.getMessage("{recordType}", type);
+
+ PlaceholderContainer placeholderContainer = new PlaceholderContainer().add("{gameMode}", gameModeString);
+ placeholderContainer.add("{recordInfo}", recordInfo);
+ player.sendMessage(Message.SUCCESS_RECORD_ACHIEVED.getMessage(placeholderContainer));
+ }
+
+ /**
+ * Registers the player's record if necessary, and prints record information to the player
+ */
+ protected void registerRecord() {
+ ArenaRecordsRegistry recordsRegistry = this.arena.getData().getRecordRegistries().get(this.gameMode);
+ long timeElapsed = System.currentTimeMillis() - this.startTime;
+ announceRecord(recordsRegistry.registerTimeRecord(this.player.getUniqueId(), timeElapsed), "time");
+ announceRecord(recordsRegistry.registerDeathRecord(this.player.getUniqueId(), this.deaths), "least deaths");
+ }
+
+ /**
+ * Teleports the playing player out of the arena
+ */
+ protected void teleportToExit(boolean immediately) {
+ // Teleport the player out of the arena
+ Location exitLocation;
+ if (this.arena.getExitLocation() != null) {
+ exitLocation = this.arena.getExitLocation();
+ } else {
+ exitLocation = this.entryState.getEntryLocation();
+ }
+ 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
+ *
+ * @return The string representation
+ */
+ protected abstract String getGameModeString();
+
+ /**
+ * Removes this session from current sessions
+ */
+ protected abstract void removeSession();
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/arena/Arena.java b/src/main/java/net/knarcraft/minigames/arena/Arena.java
index 97e46d4..ad15e81 100644
--- a/src/main/java/net/knarcraft/minigames/arena/Arena.java
+++ b/src/main/java/net/knarcraft/minigames/arena/Arena.java
@@ -3,6 +3,7 @@ package net.knarcraft.minigames.arena;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.UUID;
@@ -83,4 +84,11 @@ public interface Arena {
*/
@NotNull Location getSpawnLocation();
+ /**
+ * Gets this arena's exit location
+ *
+ * @return This arena's exit location, or null if no such location is set.
+ */
+ @Nullable Location getExitLocation();
+
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
index 3866fb8..c3ff259 100644
--- a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
@@ -1,5 +1,10 @@
package net.knarcraft.minigames.arena;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
/**
* A registry keeping track of all player sessions for some arenas
*
@@ -7,6 +12,29 @@ package net.knarcraft.minigames.arena;
*/
public interface ArenaPlayerRegistry {
+ /**
+ * Registers that the given player has started playing the given dropper arena session
+ *
+ * @param playerId The id of the player that started playing
+ * @param arenaSession The arena session to register
+ */
+ void registerPlayer(@NotNull UUID playerId, @NotNull ArenaSession arenaSession);
+
+ /**
+ * Removes this player from players currently playing
+ *
+ * @param playerId The id of the player to remove
+ */
+ boolean removePlayer(@NotNull UUID playerId);
+
+ /**
+ * Gets the player's active dropper arena session
+ *
+ * @param playerId The id of the player to get arena for
+ * @return The player's active arena session, or null if not currently playing
+ */
+ @Nullable ArenaSession getArenaSession(@NotNull UUID playerId);
+
/**
* Removes all active sessions for the given arena
*
diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java
index ffe4a99..f1afd43 100644
--- a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java
+++ b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java
@@ -1,6 +1,5 @@
package net.knarcraft.minigames.arena;
-import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
@@ -8,13 +7,6 @@ import org.jetbrains.annotations.NotNull;
*/
public interface ArenaSession {
- /**
- * Gets the game-mode the player is playing in this session
- *
- * @return The game-mode for this session
- */
- @NotNull ArenaGameMode getGameMode();
-
/**
* Gets the state of the player when they joined the session
*
@@ -46,11 +38,4 @@ public interface ArenaSession {
*/
@NotNull Arena getArena();
- /**
- * Gets the player playing in this session
- *
- * @return This session's player
- */
- @NotNull Player getPlayer();
-
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java
index 60cb457..eb5cbc0 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java
@@ -150,11 +150,7 @@ public class DropperArena implements Arena {
return this.spawnLocation.clone();
}
- /**
- * Gets this arena's exit location
- *
- * @return This arena's exit location, or null if no such location is set.
- */
+ @Override
public @Nullable Location getExitLocation() {
return this.exitLocation != null ? this.exitLocation.clone() : null;
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java
index f857b61..bc07a47 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.arena.dropper;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaHandler;
+import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.DropperArenaStorageHelper;
@@ -23,7 +24,7 @@ public class DropperArenaHandler extends ArenaHandlerThe registry keeping track of player sessions
*/
- public DropperArenaHandler(DropperArenaPlayerRegistry playerRegistry) {
+ public DropperArenaHandler(ArenaPlayerRegistry playerRegistry) {
super(playerRegistry);
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
index 30b120c..e3cd768 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
@@ -1,58 +1,9 @@
package net.knarcraft.minigames.arena.dropper;
-import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import net.knarcraft.minigames.arena.AbstractArenaPlayerRegistry;
/**
* A registry to keep track of which players are playing in which arenas
*/
-public class DropperArenaPlayerRegistry implements ArenaPlayerRegistry {
-
- private final Map arenaPlayers = new HashMap<>();
-
- /**
- * Registers that the given player has started playing the given dropper arena session
- *
- * @param playerId The id of the player that started playing
- * @param arena The arena session to register
- */
- public void registerPlayer(@NotNull UUID playerId, @NotNull DropperArenaSession arena) {
- this.arenaPlayers.put(playerId, arena);
- }
-
- /**
- * Removes this player from players currently playing
- *
- * @param playerId The id of the player to remove
- */
- public boolean removePlayer(@NotNull UUID playerId) {
- return this.arenaPlayers.remove(playerId) != null;
- }
-
- /**
- * Gets the player's active dropper arena session
- *
- * @param playerId The id of the player to get arena for
- * @return The player's active arena session, or null if not currently playing
- */
- public @Nullable DropperArenaSession getArenaSession(@NotNull UUID playerId) {
- return this.arenaPlayers.getOrDefault(playerId, null);
- }
-
- @Override
- public void removeForArena(DropperArena arena, boolean immediately) {
- for (Map.Entry entry : this.arenaPlayers.entrySet()) {
- if (entry.getValue().getArena() == arena) {
- // Kick the player gracefully
- entry.getValue().triggerQuit(immediately);
- this.arenaPlayers.remove(entry.getKey());
- }
- }
- }
-
+public class DropperArenaPlayerRegistry extends AbstractArenaPlayerRegistry {
}
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 4b2d712..45aac7f 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java
@@ -1,14 +1,11 @@
package net.knarcraft.minigames.arena.dropper;
import net.knarcraft.minigames.MiniGames;
-import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
-import net.knarcraft.minigames.arena.ArenaSession;
+import net.knarcraft.minigames.arena.AbstractArenaSession;
import net.knarcraft.minigames.arena.PlayerEntryState;
import net.knarcraft.minigames.config.DropperConfiguration;
import net.knarcraft.minigames.config.Message;
-import net.knarcraft.minigames.property.RecordResult;
import net.knarcraft.minigames.util.PlayerTeleporter;
-import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -17,14 +14,11 @@ import java.util.logging.Level;
/**
* A representation of a player's current session in a dropper arena
*/
-public class DropperArenaSession implements ArenaSession {
+public class DropperArenaSession extends AbstractArenaSession {
private final @NotNull DropperArena arena;
private final @NotNull Player player;
private final @NotNull DropperArenaGameMode gameMode;
- private int deaths;
- private final long startTime;
- private final PlayerEntryState entryState;
/**
* Instantiates a new dropper arena session
@@ -35,21 +29,28 @@ public class DropperArenaSession implements ArenaSession {
*/
public DropperArenaSession(@NotNull DropperArena dropperArena, @NotNull Player player,
@NotNull DropperArenaGameMode gameMode) {
+ super(dropperArena, player, gameMode);
this.arena = dropperArena;
this.player = player;
this.gameMode = gameMode;
- this.deaths = 0;
- this.startTime = System.currentTimeMillis();
DropperConfiguration configuration = MiniGames.getInstance().getDropperConfiguration();
boolean makeInvisible = configuration.makePlayersInvisible();
boolean disableCollision = configuration.disableHitCollision();
this.entryState = new DropperPlayerEntryState(player, gameMode, makeInvisible, disableCollision,
dropperArena.getPlayerHorizontalVelocity());
- // Make the player fly to improve mobility in the air
this.entryState.setArenaState();
}
+ /**
+ * Gets the player playing in this session
+ *
+ * @return This session's player
+ */
+ public @NotNull Player getPlayer() {
+ return this.player;
+ }
+
/**
* Gets the game-mode the player is playing in this session
*
@@ -59,18 +60,12 @@ public class DropperArenaSession implements ArenaSession {
return this.gameMode;
}
- /**
- * Gets the state of the player when they joined the session
- *
- * @return The player's entry state
- */
+ @Override
public @NotNull PlayerEntryState getEntryState() {
return this.entryState;
}
- /**
- * Triggers a win for the player playing in this session
- */
+ @Override
public void triggerWin() {
// Stop this session
stopSession();
@@ -93,26 +88,21 @@ public class DropperArenaSession implements ArenaSession {
teleportToExit(false);
}
- /**
- * Teleports the playing player out of the arena
- *
- * @param immediately Whether to to the teleportation immediately, not using any timers
- */
- private void teleportToExit(boolean immediately) {
- // Teleport the player out of the arena
- Location exitLocation;
- if (this.arena.getExitLocation() != null) {
- exitLocation = this.arena.getExitLocation();
- } else {
- exitLocation = this.entryState.getEntryLocation();
- }
- PlayerTeleporter.teleportPlayer(this.player, exitLocation, true, immediately);
+ @Override
+ public void triggerLoss() {
+ this.deaths++;
+ //Teleport the player back to the top
+ PlayerTeleporter.teleportPlayer(this.player, this.arena.getSpawnLocation(), true, false);
+ this.entryState.setArenaState();
}
- /**
- * Removes this session from current sessions
- */
- private void removeSession() {
+ @Override
+ public @NotNull DropperArena getArena() {
+ return this.arena;
+ }
+
+ @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());
if (!removedSession) {
@@ -121,94 +111,13 @@ public class DropperArenaSession implements ArenaSession {
}
}
- /**
- * Registers the player's record if necessary, and prints record information to the player
- */
- private void registerRecord() {
- ArenaRecordsRegistry recordsRegistry = this.arena.getData().getRecordRegistries().get(this.gameMode);
- long timeElapsed = System.currentTimeMillis() - this.startTime;
- announceRecord(recordsRegistry.registerTimeRecord(this.player.getUniqueId(), timeElapsed), "time");
- announceRecord(recordsRegistry.registerDeathRecord(this.player.getUniqueId(), this.deaths), "least deaths");
- }
-
- /**
- * Announces a record set by this player
- *
- * @param recordResult The result of the record
- * @param type The type of record set (time or deaths)
- */
- private void announceRecord(@NotNull RecordResult recordResult, @NotNull String type) {
- if (recordResult == RecordResult.NONE) {
- return;
- }
-
- // Gets a string representation of the played game-mode
- String gameModeString = switch (this.gameMode) {
+ @Override
+ protected String getGameModeString() {
+ return switch (this.gameMode) {
case DEFAULT -> "default";
case INVERTED -> "inverted";
case RANDOM_INVERTED -> "random";
};
-
- String recordString = "You just set a %s on the %s game-mode!";
- recordString = switch (recordResult) {
- case WORLD_RECORD -> String.format(recordString, "new %s record", gameModeString);
- case PERSONAL_BEST -> String.format(recordString, "personal %s record", gameModeString);
- default -> throw new IllegalStateException("Unexpected value: " + recordResult);
- };
- player.sendMessage(String.format(recordString, type));
- }
-
- /**
- * Triggers a loss for the player playing in this session
- */
- public void triggerLoss() {
- this.deaths++;
- //Teleport the player back to the top
- PlayerTeleporter.teleportPlayer(this.player, this.arena.getSpawnLocation(), true, false);
- this.entryState.setArenaState();
- }
-
- /**
- * Triggers a quit for the player playing in this session
- *
- * @param immediately Whether to to the teleportation immediately, not using any timers
- */
- public void triggerQuit(boolean immediately) {
- // Stop this session
- stopSession();
- // Teleport the player out of the arena
- teleportToExit(immediately);
-
- player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage());
- }
-
- /**
- * Stops this session, and disables flight mode
- */
- private 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 arena this session is being played in
- *
- * @return The session's arena
- */
- public @NotNull DropperArena getArena() {
- return this.arena;
- }
-
- /**
- * Gets the player playing in this session
- *
- * @return This session's player
- */
- public @NotNull Player getPlayer() {
- return this.player;
}
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java
index 9775a2f..088649f 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java
@@ -162,11 +162,7 @@ public class ParkourArena implements Arena {
return this.spawnLocation;
}
- /**
- * Gets this arena's exit location
- *
- * @return This arena's exit location, or null if no such location is set.
- */
+ @Override
public @Nullable Location getExitLocation() {
return this.exitLocation;
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java
index ffc657f..7e52ff6 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java
@@ -2,6 +2,7 @@ package net.knarcraft.minigames.arena.parkour;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaHandler;
+import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.util.ParkourArenaStorageHelper;
@@ -23,7 +24,7 @@ public class ParkourArenaHandler extends ArenaHandlerThe registry keeping track of player sessions
*/
- public ParkourArenaHandler(ParkourArenaPlayerRegistry playerRegistry) {
+ public ParkourArenaHandler(ArenaPlayerRegistry playerRegistry) {
super(playerRegistry);
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
index ee882bf..5f86632 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
@@ -1,58 +1,9 @@
package net.knarcraft.minigames.arena.parkour;
-import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import net.knarcraft.minigames.arena.AbstractArenaPlayerRegistry;
/**
* A registry to keep track of which players are playing in which arenas
*/
-public class ParkourArenaPlayerRegistry implements ArenaPlayerRegistry {
-
- private final Map arenaPlayers = new HashMap<>();
-
- /**
- * Registers that the given player has started playing the given parkour arena session
- *
- * @param playerId The id of the player that started playing
- * @param arena The arena session to register
- */
- public void registerPlayer(@NotNull UUID playerId, @NotNull ParkourArenaSession arena) {
- this.arenaPlayers.put(playerId, arena);
- }
-
- /**
- * Removes this player from players currently playing
- *
- * @param playerId The id of the player to remove
- */
- public boolean removePlayer(@NotNull UUID playerId) {
- return this.arenaPlayers.remove(playerId) != null;
- }
-
- /**
- * Gets the player's active parkour arena session
- *
- * @param playerId The id of the player to get arena for
- * @return The player's active arena session, or null if not currently playing
- */
- public @Nullable ParkourArenaSession getArenaSession(@NotNull UUID playerId) {
- return this.arenaPlayers.getOrDefault(playerId, null);
- }
-
- @Override
- public void removeForArena(ParkourArena arena, boolean immediately) {
- for (Map.Entry entry : this.arenaPlayers.entrySet()) {
- if (entry.getValue().getArena() == arena) {
- // Kick the player gracefully
- entry.getValue().triggerQuit(immediately);
- this.arenaPlayers.remove(entry.getKey());
- }
- }
- }
-
+public class ParkourArenaPlayerRegistry extends AbstractArenaPlayerRegistry {
}
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 06a952a..7947098 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java
@@ -1,13 +1,10 @@
package net.knarcraft.minigames.arena.parkour;
import net.knarcraft.minigames.MiniGames;
-import net.knarcraft.minigames.arena.ArenaGameMode;
-import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
-import net.knarcraft.minigames.arena.ArenaSession;
+import net.knarcraft.minigames.arena.AbstractArenaSession;
import net.knarcraft.minigames.arena.PlayerEntryState;
import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.config.ParkourConfiguration;
-import net.knarcraft.minigames.property.RecordResult;
import net.knarcraft.minigames.util.PlayerTeleporter;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@@ -19,14 +16,11 @@ import java.util.logging.Level;
/**
* A representation of a player's current session in a parkour arena
*/
-public class ParkourArenaSession implements ArenaSession {
+public class ParkourArenaSession extends AbstractArenaSession {
private final @NotNull ParkourArena arena;
private final @NotNull Player player;
private final @NotNull ParkourArenaGameMode gameMode;
- private int deaths;
- private final long startTime;
- private final PlayerEntryState entryState;
private Location reachedCheckpoint = null;
/**
@@ -38,33 +32,17 @@ public class ParkourArenaSession implements ArenaSession {
*/
public ParkourArenaSession(@NotNull ParkourArena parkourArena, @NotNull Player player,
@NotNull ParkourArenaGameMode gameMode) {
+ super(parkourArena, player, gameMode);
this.arena = parkourArena;
this.player = player;
this.gameMode = gameMode;
- this.deaths = 0;
- this.startTime = System.currentTimeMillis();
ParkourConfiguration configuration = MiniGames.getInstance().getParkourConfiguration();
boolean makeInvisible = configuration.makePlayersInvisible();
this.entryState = new ParkourPlayerEntryState(player, makeInvisible);
- // Make the player fly to improve mobility in the air
this.entryState.setArenaState();
}
- @Override
- public @NotNull ArenaGameMode getGameMode() {
- return this.gameMode;
- }
-
- /**
- * Gets the state of the player when they joined the session
- *
- * @return The player's entry state
- */
- public @NotNull PlayerEntryState getEntryState() {
- return this.entryState;
- }
-
/**
* Registers the checkpoint this session's player has reached
*
@@ -83,9 +61,12 @@ public class ParkourArenaSession implements ArenaSession {
return this.reachedCheckpoint;
}
- /**
- * Triggers a win for the player playing in this session
- */
+ @Override
+ public @NotNull PlayerEntryState getEntryState() {
+ return this.entryState;
+ }
+
+ @Override
public void triggerWin() {
// Stop this session
stopSession();
@@ -108,70 +89,7 @@ public class ParkourArenaSession implements ArenaSession {
teleportToExit(false);
}
- /**
- * Teleports the playing player out of the arena
- */
- private void teleportToExit(boolean immediately) {
- // Teleport the player out of the arena
- Location exitLocation;
- if (this.arena.getExitLocation() != null) {
- exitLocation = this.arena.getExitLocation();
- } else {
- exitLocation = this.entryState.getEntryLocation();
- }
- PlayerTeleporter.teleportPlayer(this.player, exitLocation, true, immediately);
- }
-
- /**
- * Removes this session from current sessions
- */
- private 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());
- if (!removedSession) {
- MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " +
- "This will have unintended consequences.");
- }
- }
-
- /**
- * Registers the player's record if necessary, and prints record information to the player
- */
- private void registerRecord() {
- ArenaRecordsRegistry recordsRegistry = this.arena.getData().getRecordRegistries().get(this.gameMode);
- long timeElapsed = System.currentTimeMillis() - this.startTime;
- announceRecord(recordsRegistry.registerTimeRecord(this.player.getUniqueId(), timeElapsed), "time");
- announceRecord(recordsRegistry.registerDeathRecord(this.player.getUniqueId(), this.deaths), "least deaths");
- }
-
- /**
- * Announces a record set by this player
- *
- * @param recordResult The result of the record
- * @param type The type of record set (time or deaths)
- */
- private void announceRecord(@NotNull RecordResult recordResult, @NotNull String type) {
- if (recordResult == RecordResult.NONE) {
- return;
- }
-
- // Gets a string representation of the played game-mode
- String gameModeString = switch (this.gameMode) {
- case DEFAULT -> "default";
- };
-
- String recordString = "You just set a %s on the %s game-mode!";
- recordString = switch (recordResult) {
- case WORLD_RECORD -> String.format(recordString, "new %s record", gameModeString);
- case PERSONAL_BEST -> String.format(recordString, "personal %s record", gameModeString);
- default -> throw new IllegalStateException("Unexpected value: " + recordResult);
- };
- player.sendMessage(String.format(recordString, type));
- }
-
- /**
- * Triggers a loss for the player playing in this session
- */
+ @Override
public void triggerLoss() {
this.deaths++;
//Teleport the player back to the top
@@ -180,45 +98,26 @@ public class ParkourArenaSession implements ArenaSession {
this.entryState.setArenaState();
}
- /**
- * Triggers a quit for the player playing in this session
- */
- public void triggerQuit(boolean immediately) {
- // Stop this session
- stopSession();
- // Teleport the player out of the arena
- teleportToExit(immediately);
-
- player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage());
- }
-
- /**
- * Stops this session, and disables flight mode
- */
- private 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 arena this session is being played in
- *
- * @return The session's arena
- */
+ @Override
public @NotNull ParkourArena getArena() {
return this.arena;
}
- /**
- * Gets the player playing in this session
- *
- * @return This session's player
- */
- public @NotNull Player getPlayer() {
- return this.player;
+ @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());
+ if (!removedSession) {
+ MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " +
+ "This will have unintended consequences.");
+ }
+ }
+
+ @Override
+ protected String getGameModeString() {
+ return switch (this.gameMode) {
+ case DEFAULT -> "default";
+ };
}
}
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
index bd45a53..2bde421 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
@@ -1,10 +1,10 @@
package net.knarcraft.minigames.command.dropper;
import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArena;
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
-import net.knarcraft.minigames.arena.dropper.DropperArenaPlayerRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
import net.knarcraft.minigames.config.DropperConfiguration;
import net.knarcraft.minigames.config.Message;
@@ -87,7 +87,7 @@ public class JoinDropperArenaCommand implements CommandExecutor {
// Register the player's session
DropperArenaSession newSession = new DropperArenaSession(specifiedArena, player, gameMode);
- DropperArenaPlayerRegistry playerRegistry = MiniGames.getInstance().getDropperArenaPlayerRegistry();
+ ArenaPlayerRegistry playerRegistry = MiniGames.getInstance().getDropperArenaPlayerRegistry();
playerRegistry.registerPlayer(player.getUniqueId(), newSession);
// Try to teleport the player to the arena
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
index 7a02f16..2546ee3 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
@@ -1,10 +1,10 @@
package net.knarcraft.minigames.command.parkour;
import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
-import net.knarcraft.minigames.arena.parkour.ParkourArenaPlayerRegistry;
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
import net.knarcraft.minigames.config.Message;
import net.knarcraft.minigames.config.ParkourConfiguration;
@@ -79,7 +79,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
// Register the player's session
ParkourArenaSession newSession = new ParkourArenaSession(specifiedArena, player, gameMode);
- ParkourArenaPlayerRegistry playerRegistry = MiniGames.getInstance().getParkourArenaPlayerRegistry();
+ ArenaPlayerRegistry playerRegistry = MiniGames.getInstance().getParkourArenaPlayerRegistry();
playerRegistry.registerPlayer(player.getUniqueId(), newSession);
// Try to teleport the player to the arena
diff --git a/src/main/java/net/knarcraft/minigames/config/Message.java b/src/main/java/net/knarcraft/minigames/config/Message.java
index 8cf9654..e643172 100644
--- a/src/main/java/net/knarcraft/minigames/config/Message.java
+++ b/src/main/java/net/knarcraft/minigames/config/Message.java
@@ -50,6 +50,9 @@ public enum Message {
SUCCESS_PARKOUR_ARENAS_LIST("&aParkour arenas:&r"),
SUCCESS_CHECKPOINT_REACHED("&aCheckpoint reached!"),
SUCCESS_GROUP_STAGES("&a{group}'s stages:&r"),
+ SUCCESS_RECORD_ACHIEVED("&aYou just set a {recordInfo} on the {gameMode} game-mode!"),
+ RECORD_ACHIEVED_GLOBAL("new {recordType} record"),
+ RECORD_ACHIEVED_PERSONAL("personal {recordType} record"),
;
private final @NotNull String defaultMessage;
From 401490df58f45bd6b4c5965d96a7e00460027cae Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Wed, 26 Apr 2023 13:12:14 +0200
Subject: [PATCH 5/9] Greatly improves handling of un-exited sessions #25
---
.../net/knarcraft/minigames/MiniGames.java | 8 +-
.../arena/AbstractArenaPlayerRegistry.java | 51 ++++++++-
.../arena/AbstractPlayerEntryState.java | 108 ++++++++++++++++--
.../minigames/arena/ArenaPlayerRegistry.java | 8 ++
.../minigames/arena/PlayerEntryState.java | 20 +++-
.../dropper/DropperArenaPlayerRegistry.java | 6 +
.../dropper/DropperPlayerEntryState.java | 92 +++++++++++++--
.../parkour/ParkourArenaPlayerRegistry.java | 6 +
.../parkour/ParkourPlayerEntryState.java | 61 +++++++++-
.../listener/PlayerLeaveListener.java | 87 --------------
.../listener/PlayerStateChangeListener.java | 91 +++++++++++++++
.../minigames/util/ArenaStorageHelper.java | 52 ++++++++-
12 files changed, 473 insertions(+), 117 deletions(-)
delete mode 100644 src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java
create mode 100644 src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java
diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java
index cf7e3f6..c6ca215 100644
--- a/src/main/java/net/knarcraft/minigames/MiniGames.java
+++ b/src/main/java/net/knarcraft/minigames/MiniGames.java
@@ -9,6 +9,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
import net.knarcraft.minigames.arena.dropper.DropperArenaPlayerRegistry;
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
+import net.knarcraft.minigames.arena.dropper.DropperPlayerEntryState;
import net.knarcraft.minigames.arena.parkour.ParkourArena;
import net.knarcraft.minigames.arena.parkour.ParkourArenaData;
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
@@ -16,6 +17,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
import net.knarcraft.minigames.arena.parkour.ParkourArenaPlayerRegistry;
import net.knarcraft.minigames.arena.parkour.ParkourArenaRecordsRegistry;
+import net.knarcraft.minigames.arena.parkour.ParkourPlayerEntryState;
import net.knarcraft.minigames.arena.record.IntegerRecord;
import net.knarcraft.minigames.arena.record.LongRecord;
import net.knarcraft.minigames.command.LeaveArenaCommand;
@@ -50,7 +52,7 @@ import net.knarcraft.minigames.container.SerializableUUID;
import net.knarcraft.minigames.listener.CommandListener;
import net.knarcraft.minigames.listener.DamageListener;
import net.knarcraft.minigames.listener.MoveListener;
-import net.knarcraft.minigames.listener.PlayerLeaveListener;
+import net.knarcraft.minigames.listener.PlayerStateChangeListener;
import net.knarcraft.minigames.placeholder.DropperRecordExpansion;
import net.knarcraft.minigames.placeholder.ParkourRecordExpansion;
import org.bukkit.Bukkit;
@@ -217,6 +219,8 @@ public final class MiniGames extends JavaPlugin {
ConfigurationSerialization.registerClass(ParkourArenaData.class);
ConfigurationSerialization.registerClass(ParkourArenaGroup.class);
ConfigurationSerialization.registerClass(ParkourArenaGameMode.class);
+ ConfigurationSerialization.registerClass(DropperPlayerEntryState.class);
+ ConfigurationSerialization.registerClass(ParkourPlayerEntryState.class);
}
@Override
@@ -240,7 +244,7 @@ public final class MiniGames extends JavaPlugin {
PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new DamageListener(), this);
pluginManager.registerEvents(new MoveListener(this.dropperConfiguration, this.parkourConfiguration), this);
- pluginManager.registerEvents(new PlayerLeaveListener(), this);
+ pluginManager.registerEvents(new PlayerStateChangeListener(), this);
pluginManager.registerEvents(new CommandListener(), this);
registerCommand("miniGamesReload", new ReloadCommand(), null);
diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java
index 3ebbce7..0844f12 100644
--- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java
@@ -1,11 +1,16 @@
package net.knarcraft.minigames.arena;
+import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.util.ArenaStorageHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
+import java.util.logging.Level;
/**
* A player registry to keep track of currently playing players
@@ -17,18 +22,29 @@ public abstract class AbstractArenaPlayerRegistry implements Ar
private final Map arenaPlayers = new HashMap<>();
private final Map entryStates = new HashMap<>();
- //TODO: Save all entry states each time the map changes
- //TODO: If a player joins, and their entry state exists, restore the state
+ /**
+ * Instantiates a new arena player registry
+ */
+ public AbstractArenaPlayerRegistry() {
+ loadEntryStates();
+ }
+
+ @Override
+ public @Nullable PlayerEntryState getEntryState(@NotNull UUID playerId) {
+ return this.entryStates.get(playerId);
+ }
@Override
public void registerPlayer(@NotNull UUID playerId, @NotNull ArenaSession arenaSession) {
this.arenaPlayers.put(playerId, arenaSession);
this.entryStates.put(playerId, arenaSession.getEntryState());
+ this.saveEntryStates();
}
@Override
public boolean removePlayer(@NotNull UUID playerId) {
this.entryStates.remove(playerId);
+ this.saveEntryStates();
return this.arenaPlayers.remove(playerId) != null;
}
@@ -44,9 +60,38 @@ public abstract class AbstractArenaPlayerRegistry implements Ar
// Kick the player gracefully
entry.getValue().triggerQuit(immediately);
this.arenaPlayers.remove(entry.getKey());
- this.entryStates.remove(entry.getKey());
}
}
}
+ /**
+ * Gets a string key unique to this type of player registry
+ *
+ * @return A unique key used for entry state storage
+ */
+ protected abstract String getEntryStateStorageKey();
+
+ /**
+ * Saves all entry states to disk
+ */
+ private void saveEntryStates() {
+ ArenaStorageHelper.storeArenaPlayerEntryStates(getEntryStateStorageKey(), new HashSet<>(entryStates.values()));
+ }
+
+ /**
+ * Loads all entry states from disk
+ */
+ private void loadEntryStates() {
+ this.entryStates.clear();
+ Set entryStates = ArenaStorageHelper.getArenaPlayerEntryStates(getEntryStateStorageKey());
+ for (PlayerEntryState entryState : entryStates) {
+ this.entryStates.put(entryState.getPlayerId(), entryState);
+ }
+ 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 " +
+ "to fix the players' states.");
+ }
+ }
+
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java
index c5cdf04..4c29cce 100644
--- a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java
+++ b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java
@@ -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 Whether players should be made invisible while in the arena
*/
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 The id of the player whose state this should keep track of
+ * @param makePlayerInvisible Whether players should be made invisible while in the arena
+ * @param entryLocation The location the player entered from
+ * @param originalIsFlying Whether the player was flying before entering the arena
+ * @param originalGameMode The game-mode of the player before entering the arena
+ * @param originalAllowFlight Whether the player was allowed flight before entering the arena
+ * @param originalInvulnerable Whether the player was invulnerable before entering the arena
+ * @param originalIsSwimming Whether the player was swimming before entering the arena
+ * @param originalCollideAble Whether the player was collide-able before entering the arena
+ */
+ 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 The player to restore the state for
+ */
+ 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 The player, or null if not currently online
+ */
+ 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 serialize() {
+ Map 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;
+ }
+
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
index c3ff259..5588433 100644
--- a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java
@@ -12,6 +12,14 @@ import java.util.UUID;
*/
public interface ArenaPlayerRegistry {
+ /**
+ * Gets the current entry state for the given player
+ *
+ * @param playerId The id of the player to get an entry state for
+ * @return The entry state of the player, or null if not found
+ */
+ @Nullable PlayerEntryState getEntryState(@NotNull UUID playerId);
+
/**
* Registers that the given player has started playing the given 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 cfbc91f..16f8edf 100644
--- a/src/main/java/net/knarcraft/minigames/arena/PlayerEntryState.java
+++ b/src/main/java/net/knarcraft/minigames/arena/PlayerEntryState.java
@@ -1,11 +1,15 @@
package net.knarcraft.minigames.arena;
import org.bukkit.Location;
+import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.entity.Player;
+
+import java.util.UUID;
/**
* The stored state of a player
*/
-public interface PlayerEntryState {
+public interface PlayerEntryState extends ConfigurationSerializable {
/**
* Sets the state of the stored player to the state used by the arena
@@ -17,6 +21,20 @@ public interface PlayerEntryState {
*/
void restore();
+ /**
+ * Restores the stored state for the given player
+ *
+ * @param player A player object that's refers to the same player as the stored player
+ */
+ void restore(Player player);
+
+ /**
+ * Gets the id of the player this state belongs to
+ *
+ * @return The player the state belongs to
+ */
+ UUID getPlayerId();
+
/**
* Gets the location the player entered from
*
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
index e3cd768..8e82940 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaPlayerRegistry.java
@@ -6,4 +6,10 @@ import net.knarcraft.minigames.arena.AbstractArenaPlayerRegistry;
* A registry to keep track of which players are playing in which arenas
*/
public class DropperArenaPlayerRegistry extends AbstractArenaPlayerRegistry {
+
+ @Override
+ protected String getEntryStateStorageKey() {
+ return "dropper";
+ }
+
}
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 c72fedb..9385fdd 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java
@@ -1,10 +1,15 @@
package net.knarcraft.minigames.arena.dropper;
import net.knarcraft.minigames.arena.AbstractPlayerEntryState;
+import net.knarcraft.minigames.container.SerializableUUID;
import org.bukkit.GameMode;
+import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import java.util.Map;
+import java.util.UUID;
+
/**
* The state of a player before entering a dropper arena
*/
@@ -29,29 +34,100 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
this.horizontalVelocity = horizontalVelocity;
}
+ /**
+ * Instantiates a new parkour player entry state
+ *
+ * @param playerId The id of the player whose state this should keep track of
+ * @param makePlayerInvisible Whether players should be made invisible while in the arena
+ * @param entryLocation The location the player entered from
+ * @param originalIsFlying Whether the player was flying before entering the arena
+ * @param originalGameMode The game-mode of the player before entering the arena
+ * @param originalAllowFlight Whether the player was allowed flight before entering the arena
+ * @param originalInvulnerable Whether the player was invulnerable before entering the arena
+ * @param originalIsSwimming Whether the player was swimming before entering the arena
+ * @param originalCollideAble Whether the player was collide-able before entering the arena
+ */
+ public DropperPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation,
+ boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
+ boolean originalInvulnerable, boolean originalIsSwimming,
+ boolean originalCollideAble, float originalFlySpeed, boolean disableHitCollision,
+ float horizontalVelocity, DropperArenaGameMode arenaGameMode) {
+ super(playerId, makePlayerInvisible, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
+ originalInvulnerable, originalIsSwimming, originalCollideAble);
+ this.originalFlySpeed = originalFlySpeed;
+ this.disableHitCollision = disableHitCollision;
+ this.horizontalVelocity = horizontalVelocity;
+ this.arenaGameMode = arenaGameMode;
+ }
+
@Override
public void setArenaState() {
super.setArenaState();
- this.player.setAllowFlight(true);
- this.player.setFlying(true);
- this.player.setGameMode(GameMode.ADVENTURE);
- this.player.setSwimming(false);
+ Player player = getPlayer();
+ if (player == null) {
+ return;
+ }
+ player.setAllowFlight(true);
+ player.setFlying(true);
+ player.setGameMode(GameMode.ADVENTURE);
+ player.setSwimming(false);
if (this.disableHitCollision) {
- this.player.setCollidable(false);
+ player.setCollidable(false);
}
// If playing on the inverted game-mode, negate the horizontal velocity to swap the controls
if (this.arenaGameMode == DropperArenaGameMode.INVERTED) {
- this.player.setFlySpeed(-this.horizontalVelocity);
+ player.setFlySpeed(-this.horizontalVelocity);
} else {
- this.player.setFlySpeed(this.horizontalVelocity);
+ player.setFlySpeed(this.horizontalVelocity);
}
}
@Override
public void restore() {
super.restore();
- this.player.setFlySpeed(this.originalFlySpeed);
+ Player player = getPlayer();
+ if (player == null) {
+ return;
+ }
+ player.setFlySpeed(this.originalFlySpeed);
+ }
+
+ @NotNull
+ @Override
+ public Map serialize() {
+ Map data = super.serialize();
+ data.put("originalFlySpeed", this.originalFlySpeed);
+ data.put("disableHitCollision", this.disableHitCollision);
+ data.put("horizontalVelocity", this.horizontalVelocity);
+ data.put("arenaGameMode", this.arenaGameMode);
+ return data;
+ }
+
+ /**
+ * Deserializes a ParkourPlayerEntryState from the given data
+ *
+ * @return The data to deserialize
+ */
+ @SuppressWarnings("unused")
+ public static DropperPlayerEntryState deserialize(Map data) {
+ UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue();
+ boolean makePlayerInvisible = (boolean) data.get("makePlayerInvisible");
+ Location entryLocation = (Location) data.get("entryLocation");
+ boolean originalIsFlying = (boolean) data.get("originalIsFlying");
+ GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode"));
+ boolean originalAllowFlight = (boolean) data.get("originalAllowFlight");
+ boolean originalInvulnerable = (boolean) data.get("originalInvulnerable");
+ boolean originalIsSwimming = (boolean) data.get("originalIsSwimming");
+ boolean originalCollideAble = (boolean) data.get("originalCollideAble");
+ float originalFlySpeed = ((Number) data.get("originalFlySpeed")).floatValue();
+ boolean disableHitCollision = (boolean) data.get("disableHitCollision");
+ float horizontalVelocity = ((Number) data.get("horizontalVelocity")).floatValue();
+ DropperArenaGameMode arenaGameMode = (DropperArenaGameMode) data.get("arenaGameMode");
+
+ return new DropperPlayerEntryState(playerId, makePlayerInvisible, entryLocation, originalIsFlying,
+ originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble,
+ originalFlySpeed, disableHitCollision, horizontalVelocity, arenaGameMode);
}
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
index 5f86632..f863e18 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaPlayerRegistry.java
@@ -6,4 +6,10 @@ import net.knarcraft.minigames.arena.AbstractArenaPlayerRegistry;
* A registry to keep track of which players are playing in which arenas
*/
public class ParkourArenaPlayerRegistry extends AbstractArenaPlayerRegistry {
+
+ @Override
+ protected String getEntryStateStorageKey() {
+ return "parkour";
+ }
+
}
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java
index 74d95f2..10e229b 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java
@@ -1,10 +1,15 @@
package net.knarcraft.minigames.arena.parkour;
import net.knarcraft.minigames.arena.AbstractPlayerEntryState;
+import net.knarcraft.minigames.container.SerializableUUID;
import org.bukkit.GameMode;
+import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
+import java.util.Map;
+import java.util.UUID;
+
/**
* The state of a player before entering a parkour arena
*/
@@ -19,14 +24,60 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
super(player, makePlayerInvisible);
}
+ /**
+ * Instantiates a new parkour player entry state
+ *
+ * @param playerId The id of the player whose state this should keep track of
+ * @param makePlayerInvisible Whether players should be made invisible while in the arena
+ * @param entryLocation The location the player entered from
+ * @param originalIsFlying Whether the player was flying before entering the arena
+ * @param originalGameMode The game-mode of the player before entering the arena
+ * @param originalAllowFlight Whether the player was allowed flight before entering the arena
+ * @param originalInvulnerable Whether the player was invulnerable before entering the arena
+ * @param originalIsSwimming Whether the player was swimming before entering the arena
+ * @param originalCollideAble Whether the player was collide-able before entering the arena
+ */
+ public ParkourPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation,
+ boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
+ boolean originalInvulnerable, boolean originalIsSwimming,
+ boolean originalCollideAble) {
+ super(playerId, makePlayerInvisible, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
+ originalInvulnerable, originalIsSwimming, originalCollideAble);
+ }
+
@Override
public void setArenaState() {
super.setArenaState();
- this.player.setAllowFlight(false);
- this.player.setFlying(false);
- this.player.setGameMode(GameMode.ADVENTURE);
- this.player.setSwimming(false);
- this.player.setCollidable(false);
+ Player player = getPlayer();
+ if (player == null) {
+ return;
+ }
+ player.setAllowFlight(false);
+ player.setFlying(false);
+ player.setGameMode(GameMode.ADVENTURE);
+ player.setSwimming(false);
+ player.setCollidable(false);
+ }
+
+ /**
+ * Deserializes a ParkourPlayerEntryState from the given data
+ *
+ * @return The data to deserialize
+ */
+ @SuppressWarnings("unused")
+ public static ParkourPlayerEntryState deserialize(Map data) {
+ UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue();
+ boolean makePlayerInvisible = (boolean) data.get("makePlayerInvisible");
+ Location entryLocation = (Location) data.get("entryLocation");
+ boolean originalIsFlying = (boolean) data.get("originalIsFlying");
+ GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode"));
+ boolean originalAllowFlight = (boolean) data.get("originalAllowFlight");
+ boolean originalInvulnerable = (boolean) data.get("originalInvulnerable");
+ boolean originalIsSwimming = (boolean) data.get("originalIsSwimming");
+ boolean originalCollideAble = (boolean) data.get("originalCollideAble");
+
+ return new ParkourPlayerEntryState(playerId, makePlayerInvisible, entryLocation, originalIsFlying,
+ originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble);
}
}
diff --git a/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java b/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java
deleted file mode 100644
index 0bfaa5c..0000000
--- a/src/main/java/net/knarcraft/minigames/listener/PlayerLeaveListener.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package net.knarcraft.minigames.listener;
-
-import net.knarcraft.minigames.MiniGames;
-import net.knarcraft.minigames.arena.ArenaSession;
-import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.entity.Player;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.PlayerJoinEvent;
-import org.bukkit.event.player.PlayerQuitEvent;
-import org.bukkit.event.player.PlayerTeleportEvent;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.logging.Level;
-
-/**
- * A listener for players leaving the server or the arena
- */
-public class PlayerLeaveListener implements Listener {
-
- private final Map leftSessions = new HashMap<>();
-
- @EventHandler
- public void onPlayerLeave(PlayerQuitEvent event) {
- Player player = event.getPlayer();
-
- ArenaSession arenaSession = MiniGames.getInstance().getSession(event.getPlayer().getUniqueId());
- if (arenaSession == null) {
- return;
- }
-
- MiniGames.log(Level.WARNING, "Found player " + player.getUniqueId() +
- " leaving in the middle of a session!");
- leftSessions.put(player.getUniqueId(), arenaSession);
- }
-
- @EventHandler
- public void onPlayerJoin(PlayerJoinEvent event) {
- UUID playerId = event.getPlayer().getUniqueId();
- // Force the player to quit from the session once they re-join
- if (leftSessions.containsKey(playerId)) {
- MiniGames.log(Level.WARNING, "Found un-exited dropper session!");
- Bukkit.getScheduler().runTaskLater(MiniGames.getInstance(), () -> {
- leftSessions.get(playerId).triggerQuit(false);
- MiniGames.log(Level.WARNING, "Triggered a quit!");
- leftSessions.remove(playerId);
- }, 80);
- }
- }
-
- /**
- * Prevent the player from teleporting away from an arena for any reason
- *
- * @param event The triggered teleport event
- */
- @EventHandler(ignoreCancelled = true)
- public void onPlayerTeleport(PlayerTeleportEvent event) {
- Location targetLocation = event.getTo();
- if (targetLocation == null) {
- return;
- }
-
- // Ignore if not in an arena session
- ArenaSession arenaSession = MiniGames.getInstance().getSession(event.getPlayer().getUniqueId());
- if (arenaSession == null) {
- return;
- }
-
- // If teleported to the arena's spawn, it's fine
- if (targetLocation.equals(arenaSession.getArena().getSpawnLocation())) {
- return;
- }
-
- // If teleported to the arena's checkpoint, it's fine
- if (arenaSession instanceof ParkourArenaSession parkourArenaSession &&
- targetLocation.equals(parkourArenaSession.getRegisteredCheckpoint())) {
- return;
- }
-
- event.setCancelled(true);
- }
-
-}
diff --git a/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java b/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java
new file mode 100644
index 0000000..14987b0
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java
@@ -0,0 +1,91 @@
+package net.knarcraft.minigames.listener;
+
+import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
+import net.knarcraft.minigames.arena.ArenaSession;
+import net.knarcraft.minigames.arena.PlayerEntryState;
+import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.spigotmc.event.player.PlayerSpawnLocationEvent;
+
+import java.util.logging.Level;
+
+/**
+ * A listener for players leaving/joining the server, or leaving the server unexpectedly
+ */
+public class PlayerStateChangeListener implements Listener {
+
+ @EventHandler
+ public void onPlayerSpawn(PlayerSpawnLocationEvent event) {
+ Player player = event.getPlayer();
+
+ // Restore any lingering arena states
+ Location restoreLocation;
+ restoreLocation = restoreStateIfNecessary(player, MiniGames.getInstance().getDropperArenaPlayerRegistry());
+ if (restoreLocation != null) {
+ event.setSpawnLocation(restoreLocation);
+ }
+ restoreLocation = restoreStateIfNecessary(player, MiniGames.getInstance().getParkourArenaPlayerRegistry());
+ if (restoreLocation != null) {
+ event.setSpawnLocation(restoreLocation);
+ }
+ }
+
+ /**
+ * Prevent the player from teleporting away from an arena for any reason
+ *
+ * @param event The triggered teleport event
+ */
+ @EventHandler(ignoreCancelled = true)
+ public void onPlayerTeleport(PlayerTeleportEvent event) {
+ Location targetLocation = event.getTo();
+ if (targetLocation == null) {
+ return;
+ }
+
+ // Ignore if not in an arena session
+ ArenaSession arenaSession = MiniGames.getInstance().getSession(event.getPlayer().getUniqueId());
+ if (arenaSession == null) {
+ return;
+ }
+
+ // If teleported to the arena's spawn, it's fine
+ if (targetLocation.equals(arenaSession.getArena().getSpawnLocation())) {
+ return;
+ }
+
+ // If teleported to the arena's checkpoint, it's fine
+ if (arenaSession instanceof ParkourArenaSession parkourArenaSession &&
+ targetLocation.equals(parkourArenaSession.getRegisteredCheckpoint())) {
+ return;
+ }
+
+ event.setCancelled(true);
+ }
+
+ /**
+ * Restores the state of the given player if a lingering session is found in the given player registry
+ *
+ * @param player The player whose state should be checked
+ * @param playerRegistry The registry to check for a lingering state
+ * @return The location the player should spawn in, or null if not restored
+ */
+ private Location restoreStateIfNecessary(Player player, ArenaPlayerRegistry> playerRegistry) {
+ PlayerEntryState entryState = playerRegistry.getEntryState(player.getUniqueId());
+ 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());
+
+ entryState.restore(player);
+ return entryState.getEntryLocation();
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java b/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java
index c64ad1d..9abfd2d 100644
--- a/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java
+++ b/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java
@@ -1,18 +1,68 @@
package net.knarcraft.minigames.util;
import net.knarcraft.minigames.MiniGames;
+import net.knarcraft.minigames.arena.PlayerEntryState;
+import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
+/**
+ * A helper class for dealing with arena storage
+ */
public final class ArenaStorageHelper {
private ArenaStorageHelper() {
}
+ /**
+ * Stores the given entry states to disk
+ *
+ * @param key The key specifying the correct entry state file
+ * @param entryStates The entry states to save
+ */
+ public static void storeArenaPlayerEntryStates(String key, Set entryStates) {
+ YamlConfiguration configuration = new YamlConfiguration();
+ configuration.set(key, new ArrayList<>(entryStates));
+
+ try {
+ configuration.save(new File(MiniGames.getInstance().getDataFolder(), key + "EntryStates.yml"));
+ } catch (IOException e) {
+ MiniGames.log(Level.SEVERE, "Unable to save entry states to disk");
+ }
+ }
+
+ /**
+ * Gets saved entry states from disk
+ *
+ * @param key The key specifying the correct entry state file
+ * @return The previously saved entry states
+ */
+ public static Set getArenaPlayerEntryStates(String key) {
+ File entryStateFile = new File(MiniGames.getInstance().getDataFolder(), key + "EntryStates.yml");
+ if (!entryStateFile.exists()) {
+ return new HashSet<>();
+ }
+ YamlConfiguration configuration = YamlConfiguration.loadConfiguration(entryStateFile);
+ Set output = new HashSet<>();
+
+ List> entries = configuration.getList(key, new ArrayList<>());
+ for (Object entry : entries) {
+ if (entry instanceof PlayerEntryState entryState) {
+ output.add(entryState);
+ }
+ }
+ return output;
+ }
+
/**
* Gets the file used to store the given arena id's data
*
@@ -20,7 +70,7 @@ public final class ArenaStorageHelper {
* @param arenaId The id of the arena to get a data file for
* @return The file the arena's data is/should be stored in
*/
- static @NotNull File getArenaDataFile(File root, @NotNull UUID arenaId) {
+ public static @NotNull File getArenaDataFile(File root, @NotNull UUID arenaId) {
File arenaDataFile = new File(root, arenaId + ".yml");
if (!root.exists() && !root.mkdirs()) {
MiniGames.log(Level.SEVERE, "Unable to create the arena data directories");
From 206a85b23aed1a03d9aaa9ba13d617f942ff3827 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Wed, 26 Apr 2023 13:47:03 +0200
Subject: [PATCH 6/9] 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();
From 4a3329459eb731aee6cb4655aa68add7ffbffb6e Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Wed, 26 Apr 2023 13:53:29 +0200
Subject: [PATCH 7/9] Fixes joining not fixing non-location player options
---
.../minigames/listener/PlayerStateChangeListener.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java b/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java
index e3831fa..3c5e48f 100644
--- a/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java
+++ b/src/main/java/net/knarcraft/minigames/listener/PlayerStateChangeListener.java
@@ -5,6 +5,7 @@ import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.arena.PlayerEntryState;
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
+import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -81,7 +82,7 @@ public class PlayerStateChangeListener implements Listener {
". Attempting to restore the player's state.");
playerRegistry.removePlayer(player.getUniqueId(), false);
- entryState.restore(player);
+ Bukkit.getScheduler().runTaskLater(MiniGames.getInstance(), () -> entryState.restore(player), 1);
return entryState.getEntryLocation();
} else {
return null;
From 8d1b8416194900d19f019ebbe4863657c74dbb08 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Wed, 26 Apr 2023 14:41:54 +0200
Subject: [PATCH 8/9] Adds tab completions for arena properties
---
.../minigames/arena/EditablePropertyType.java | 43 ++++++
.../dropper/DropperArenaEditableProperty.java | 32 ++++-
.../parkour/ParkourArenaEditableProperty.java | 37 ++++--
.../dropper/EditDropperArenaTabCompleter.java | 9 +-
.../parkour/EditParkourArenaTabCompleter.java | 9 +-
.../minigames/util/TabCompleteHelper.java | 122 ++++++++++++++++++
6 files changed, 232 insertions(+), 20 deletions(-)
create mode 100644 src/main/java/net/knarcraft/minigames/arena/EditablePropertyType.java
diff --git a/src/main/java/net/knarcraft/minigames/arena/EditablePropertyType.java b/src/main/java/net/knarcraft/minigames/arena/EditablePropertyType.java
new file mode 100644
index 0000000..6f07e87
--- /dev/null
+++ b/src/main/java/net/knarcraft/minigames/arena/EditablePropertyType.java
@@ -0,0 +1,43 @@
+package net.knarcraft.minigames.arena;
+
+/**
+ * The type of one editable property
+ */
+public enum EditablePropertyType {
+
+ /**
+ * The property is a location
+ */
+ LOCATION,
+
+ /**
+ * The property is an arena name
+ */
+ ARENA_NAME,
+
+ /**
+ * The property is a horizontal velocity
+ */
+ HORIZONTAL_VELOCITY,
+
+ /**
+ * The property is a vertical velocity (fly speed)
+ */
+ VERTICAL_VELOCITY,
+
+ /**
+ * The property is a material that specifies a block
+ */
+ BLOCK_TYPE,
+
+ /**
+ * The property clears a checkpoint
+ */
+ CHECKPOINT_CLEAR,
+
+ /**
+ * The property is a comma-separated list of materials
+ */
+ MATERIAL_LIST
+
+}
diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaEditableProperty.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaEditableProperty.java
index 9e77748..8dc6b5e 100644
--- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaEditableProperty.java
+++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaEditableProperty.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames.arena.dropper;
+import net.knarcraft.minigames.arena.EditablePropertyType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,45 +14,62 @@ public enum DropperArenaEditableProperty {
/**
* The name of the arena
*/
- NAME("name", DropperArena::getArenaName),
+ NAME("name", DropperArena::getArenaName, EditablePropertyType.ARENA_NAME),
/**
* The arena's spawn location
*/
- SPAWN_LOCATION("spawnLocation", (arena) -> String.valueOf(arena.getSpawnLocation())),
+ SPAWN_LOCATION("spawnLocation", (arena) -> String.valueOf(arena.getSpawnLocation()),
+ EditablePropertyType.LOCATION),
/**
* The arena's exit location
*/
- EXIT_LOCATION("exitLocation", (arena) -> String.valueOf(arena.getExitLocation())),
+ EXIT_LOCATION("exitLocation", (arena) -> String.valueOf(arena.getExitLocation()),
+ EditablePropertyType.LOCATION),
/**
* The arena's vertical velocity
*/
- VERTICAL_VELOCITY("verticalVelocity", (arena) -> String.valueOf(arena.getPlayerVerticalVelocity())),
+ VERTICAL_VELOCITY("verticalVelocity", (arena) -> String.valueOf(arena.getPlayerVerticalVelocity()),
+ EditablePropertyType.VERTICAL_VELOCITY),
/**
* The arena's horizontal velocity
*/
- HORIZONTAL_VELOCITY("horizontalVelocity", (arena) -> String.valueOf(arena.getPlayerHorizontalVelocity())),
+ HORIZONTAL_VELOCITY("horizontalVelocity", (arena) -> String.valueOf(arena.getPlayerHorizontalVelocity()),
+ EditablePropertyType.HORIZONTAL_VELOCITY),
/**
* The arena's win block type
*/
- WIN_BLOCK_TYPE("winBlockType", (arena) -> arena.getWinBlockType().toString()),
+ WIN_BLOCK_TYPE("winBlockType", (arena) -> arena.getWinBlockType().toString(),
+ EditablePropertyType.BLOCK_TYPE),
;
private final @NotNull String argumentString;
private final Function currentValueProvider;
+ private final EditablePropertyType propertyType;
/**
* Instantiates a new arena editable property
*
* @param argumentString The argument string used to specify this property
*/
- DropperArenaEditableProperty(@NotNull String argumentString, Function currentValueProvider) {
+ DropperArenaEditableProperty(@NotNull String argumentString, Function currentValueProvider,
+ EditablePropertyType propertyType) {
this.argumentString = argumentString;
this.currentValueProvider = currentValueProvider;
+ this.propertyType = propertyType;
+ }
+
+ /**
+ * Gets the type of property this editable property represents
+ *
+ * @return The type of this property
+ */
+ public EditablePropertyType getPropertyType() {
+ return this.propertyType;
}
/**
diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaEditableProperty.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaEditableProperty.java
index 06672c1..8e90c93 100644
--- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaEditableProperty.java
+++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaEditableProperty.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames.arena.parkour;
+import net.knarcraft.minigames.arena.EditablePropertyType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -13,22 +14,25 @@ public enum ParkourArenaEditableProperty {
/**
* The name of the arena
*/
- NAME("name", ParkourArena::getArenaName),
+ NAME("name", ParkourArena::getArenaName, EditablePropertyType.ARENA_NAME),
/**
* The arena's spawn location
*/
- SPAWN_LOCATION("spawnLocation", (arena) -> String.valueOf(arena.getSpawnLocation())),
+ SPAWN_LOCATION("spawnLocation", (arena) -> String.valueOf(arena.getSpawnLocation()),
+ EditablePropertyType.LOCATION),
/**
* The arena's exit location
*/
- EXIT_LOCATION("exitLocation", (arena) -> String.valueOf(arena.getExitLocation())),
+ EXIT_LOCATION("exitLocation", (arena) -> String.valueOf(arena.getExitLocation()),
+ EditablePropertyType.LOCATION),
/**
* The arena's win block type
*/
- WIN_BLOCK_TYPE("winBlockType", (arena) -> arena.getWinBlockType().toString()),
+ WIN_BLOCK_TYPE("winBlockType", (arena) -> arena.getWinBlockType().toString(),
+ EditablePropertyType.BLOCK_TYPE),
/**
* The arena's win location (overrides the win block type)
@@ -39,35 +43,50 @@ public enum ParkourArenaEditableProperty {
} else {
return "null";
}
- }),
+ }, EditablePropertyType.LOCATION),
/**
* The arena's check points. Specifically used for adding.
*/
- CHECKPOINT_ADD("checkpointAdd", (arena) -> String.valueOf(arena.getCheckpoints())),
+ CHECKPOINT_ADD("checkpointAdd", (arena) -> String.valueOf(arena.getCheckpoints()),
+ EditablePropertyType.LOCATION),
/**
* The arena's check points. Specifically used for clearing.
*/
- CHECKPOINT_CLEAR("checkpointClear", (arena) -> String.valueOf(arena.getCheckpoints())),
+ CHECKPOINT_CLEAR("checkpointClear", (arena) -> String.valueOf(arena.getCheckpoints()),
+ EditablePropertyType.CHECKPOINT_CLEAR),
/**
* The blocks constituting the arena's lethal blocks
*/
- KILL_PLANE_BLOCKS("killPlaneBlocks", (arena) -> String.valueOf(arena.getKillPlaneBlockNames())),
+ KILL_PLANE_BLOCKS("killPlaneBlocks", (arena) -> String.valueOf(arena.getKillPlaneBlockNames()),
+ EditablePropertyType.MATERIAL_LIST),
;
private final @NotNull String argumentString;
private final Function currentValueProvider;
+ private final EditablePropertyType propertyType;
/**
* Instantiates a new arena editable property
*
* @param argumentString The argument string used to specify this property
*/
- ParkourArenaEditableProperty(@NotNull String argumentString, Function currentValueProvider) {
+ ParkourArenaEditableProperty(@NotNull String argumentString, Function currentValueProvider,
+ EditablePropertyType propertyType) {
this.argumentString = argumentString;
this.currentValueProvider = currentValueProvider;
+ this.propertyType = propertyType;
+ }
+
+ /**
+ * Gets the type of property this editable property represents
+ *
+ * @return The type of this property
+ */
+ public EditablePropertyType getPropertyType() {
+ return this.propertyType;
}
/**
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java
index af5161b..2488606 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames.command.dropper;
+import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
import net.knarcraft.minigames.util.TabCompleteHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -25,8 +26,12 @@ public class EditDropperArenaTabCompleter implements TabCompleter {
} else if (arguments.length == 2) {
return filterMatchingContains(TabCompleteHelper.getDropperArenaProperties(), arguments[1]);
} else if (arguments.length == 3) {
- //TODO: Tab-complete possible values for the given property
- return null;
+ DropperArenaEditableProperty property = DropperArenaEditableProperty.getFromArgumentString(arguments[1]);
+ if (property == null) {
+ return new ArrayList<>();
+ }
+ return filterMatchingContains(TabCompleteHelper.getTabCompleteSuggestions(property.getPropertyType()),
+ arguments[2]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java
index a6f5593..3a0a7f0 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java
@@ -1,5 +1,6 @@
package net.knarcraft.minigames.command.parkour;
+import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty;
import net.knarcraft.minigames.util.TabCompleteHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -25,8 +26,12 @@ public class EditParkourArenaTabCompleter implements TabCompleter {
} else if (arguments.length == 2) {
return filterMatchingContains(TabCompleteHelper.getParkourArenaProperties(), arguments[1]);
} else if (arguments.length == 3) {
- //TODO: Tab-complete possible values for the given property
- return null;
+ ParkourArenaEditableProperty property = ParkourArenaEditableProperty.getFromArgumentString(arguments[1]);
+ if (property == null) {
+ return new ArrayList<>();
+ }
+ return filterMatchingContains(TabCompleteHelper.getTabCompleteSuggestions(property.getPropertyType()),
+ arguments[2]);
} else {
return new ArrayList<>();
}
diff --git a/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java b/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java
index 65749d4..fee509a 100644
--- a/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java
+++ b/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java
@@ -3,18 +3,24 @@ package net.knarcraft.minigames.util;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.Arena;
import net.knarcraft.minigames.arena.ArenaHandler;
+import net.knarcraft.minigames.arena.EditablePropertyType;
import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty;
+import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* A helper-class for common tab-completions
*/
public final class TabCompleteHelper {
+ private static Map> tabCompleteSuggestions;
+
private TabCompleteHelper() {
}
@@ -93,4 +99,120 @@ public final class TabCompleteHelper {
return configValues;
}
+ /**
+ * Gets tab-complete suggestions for the given property type
+ *
+ * @param propertyType The property type to get suggestions for
+ * @return The suggestions produced
+ */
+ public static List getTabCompleteSuggestions(EditablePropertyType propertyType) {
+ if (tabCompleteSuggestions == null) {
+ tabCompleteSuggestions = new HashMap<>();
+ tabCompleteSuggestions.put(EditablePropertyType.LOCATION, getLocationSuggestions());
+ tabCompleteSuggestions.put(EditablePropertyType.ARENA_NAME, getNameSuggestions());
+ tabCompleteSuggestions.put(EditablePropertyType.HORIZONTAL_VELOCITY, getHorizontalVelocitySuggestions());
+ tabCompleteSuggestions.put(EditablePropertyType.VERTICAL_VELOCITY, getVerticalVelocitySuggestions());
+ tabCompleteSuggestions.put(EditablePropertyType.BLOCK_TYPE, getBlockTypeSuggestions());
+ tabCompleteSuggestions.put(EditablePropertyType.CHECKPOINT_CLEAR, getCheckpointClearSuggestions());
+ tabCompleteSuggestions.put(EditablePropertyType.MATERIAL_LIST, getMaterialListSuggestions());
+ }
+
+ return tabCompleteSuggestions.get(propertyType);
+ }
+
+ /**
+ * Gets suggestions for a list of materials
+ *
+ * @return A list of suggestions
+ */
+ private static List getMaterialListSuggestions() {
+ List suggestions = new ArrayList<>();
+ suggestions.add("LAVA,MAGMA_BLOCK");
+ suggestions.add("WATER,MAGMA_BLOCK,LAVA,+BUTTONS,+CORALS");
+ return suggestions;
+ }
+
+ /**
+ * Gets suggestions for checkpointClear
+ *
+ * @return A list of suggestions
+ */
+ private static List getCheckpointClearSuggestions() {
+ List suggestions = new ArrayList<>();
+ suggestions.add("true");
+ return suggestions;
+ }
+
+ /**
+ * Gets suggestions for a block material
+ *
+ * @return A list of suggestions
+ */
+ private static List getBlockTypeSuggestions() {
+ List materials = new ArrayList<>();
+ for (Material material : Material.values()) {
+ if (material.isBlock()) {
+ materials.add(material.name());
+ }
+ }
+ return materials;
+ }
+
+ /**
+ * Gets suggestions for a vertical velocity
+ *
+ * @return A list of suggestions
+ */
+ private static List getVerticalVelocitySuggestions() {
+ List velocities = new ArrayList<>();
+ velocities.add("0.01");
+ velocities.add("0.5");
+ velocities.add("1");
+ velocities.add("3");
+ velocities.add("10");
+ velocities.add("30");
+ velocities.add("75");
+ return velocities;
+ }
+
+ /**
+ * Gets suggestions for a horizontal velocity
+ *
+ * @return A list of suggestions
+ */
+ private static List getHorizontalVelocitySuggestions() {
+ List velocities = new ArrayList<>();
+ velocities.add("0.01");
+ velocities.add("0.1");
+ velocities.add("0.5");
+ velocities.add("1");
+ return velocities;
+ }
+
+ /**
+ * Gets suggestions for an arena name
+ *
+ * @return A list of suggestions
+ */
+ private static List getNameSuggestions() {
+ List locations = new ArrayList<>();
+ locations.add("DropperArena1");
+ locations.add("DropperArena2");
+ locations.add("ParkourArena1");
+ locations.add("ParkourArena2");
+ return locations;
+ }
+
+ /**
+ * Gets suggestions for a location
+ *
+ * @return A list of suggestions
+ */
+ private static List getLocationSuggestions() {
+ List locations = new ArrayList<>();
+ locations.add("here");
+ locations.add("x,y,z");
+ return locations;
+ }
+
}
From 078a8ed00725bf4e52c1a1b7689a21c0e9ce2929 Mon Sep 17 00:00:00 2001
From: EpicKnarvik97
Date: Wed, 26 Apr 2023 17:42:06 +0200
Subject: [PATCH 9/9] Adds a message when a player joins an arena
---
.../minigames/arena/AbstractArenaSession.java | 2 +-
.../dropper/JoinDropperArenaCommand.java | 1 +
.../parkour/JoinParkourArenaCommand.java | 1 +
.../knarcraft/minigames/config/Message.java | 186 ++++++++++++++++++
4 files changed, 189 insertions(+), 1 deletion(-)
diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java
index e95e41a..79cff03 100644
--- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java
+++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java
@@ -61,7 +61,7 @@ public abstract class AbstractArenaSession implements ArenaSession {
case PERSONAL_BEST -> Message.RECORD_ACHIEVED_PERSONAL;
default -> throw new IllegalStateException("Unexpected value: " + recordResult);
};
- String recordInfo = recordInfoMessage.getMessage("{recordType}", type);
+ String recordInfo = recordInfoMessage.getPartialMessage("{recordType}", type);
PlaceholderContainer placeholderContainer = new PlaceholderContainer().add("{gameMode}", gameModeString);
placeholderContainer.add("{recordInfo}", recordInfo);
diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
index 2bde421..a5c4b6e 100644
--- a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java
@@ -99,6 +99,7 @@ public class JoinDropperArenaCommand implements CommandExecutor {
} else {
// Make sure to update the state again in the air to remove a potential swimming state
newSession.getEntryState().setArenaState();
+ player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage());
return true;
}
}
diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
index 2546ee3..0067375 100644
--- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
+++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java
@@ -91,6 +91,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
} else {
// Make sure to update the state again in the air to remove a potential swimming state
newSession.getEntryState().setArenaState();
+ player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage());
return true;
}
}
diff --git a/src/main/java/net/knarcraft/minigames/config/Message.java b/src/main/java/net/knarcraft/minigames/config/Message.java
index e643172..d9cebf9 100644
--- a/src/main/java/net/knarcraft/minigames/config/Message.java
+++ b/src/main/java/net/knarcraft/minigames/config/Message.java
@@ -12,47 +12,222 @@ import java.util.Map;
*/
public enum Message {
+ /* ************** *
+ * Error messages *
+ * ************** */
+
+ /**
+ * The message displayed if saving arena groups fails
+ */
ERROR_CANNOT_SAVE_ARENA_GROUPS("&cUnable to save current arena groups! Data loss can occur!"),
+
+ /**
+ * The message displayed if an un-parse-able message is given by a user
+ */
ERROR_MATERIAL_NOT_PARSE_ABLE("&cUnable to parse material: {material}"),
+
+ /**
+ * The message displayed if a player tries to be teleported to/from an arena with a passenger
+ */
ERROR_TELEPORT_WITH_PASSENGER("&cYou cannot be teleported with a passenger!"),
+
+ /**
+ * The message displayed if a player tries to be teleported to/from an arena with a vehicle
+ */
ERROR_TELEPORT_IN_VEHICLE("&cYou cannot be teleported while in a vehicle"),
+
+ /**
+ * The message displayed if an arena cannot be loaded
+ */
ERROR_ARENA_NOT_LOADED("&cCould not load the arena at configuration section {section}. Please check " +
"the {file} storage file for issues."),
+
+ /**
+ * The message displayed if an arena's data cannot be loaded
+ */
ERROR_ARENA_DATA_NOT_LOADED("&cUnable to load arena data for dropper arena: {arena}"),
+
+ /**
+ * The message displayed if the user specifies an unrecognized arena
+ */
ERROR_ARENA_NOT_FOUND("&cUnable to find the specified arena."),
+
+ /**
+ * The message displayed if the user specifies an unrecognized group
+ */
ERROR_GROUP_NOT_FOUND("&cUnable to find the specified group!"),
+
+ /**
+ * The message displayed if the console tries to execute a player-only command
+ */
ERROR_PLAYER_ONLY("&cThis command must be used by a player"),
+
+ /**
+ * The message displayed if the name of an arena is duplicated
+ */
ERROR_ARENA_NAME_COLLISION("&cThere already exists an arena with that name!"),
+
+ /**
+ * The message displayed if the player is required to win on the default difficulty first
+ */
ERROR_NORMAL_MODE_REQUIRED("&cYou must complete this arena in normal mode first!"),
+
+ /**
+ * The message displayed if the player is required to win on the default difficulty for all arenas in the group first
+ */
ERROR_GROUP_NORMAL_MODE_REQUIRED("&cYou have not yet beaten the default game-mode for all arenas in this group!"),
+
+ /**
+ * The message displayed if the player is required to beat the previous arena in the group
+ */
ERROR_PREVIOUS_ARENA_REQUIRED("&cYou have not yet beaten the previous arena!"),
+
+ /**
+ * The message displayed if player teleportation failed for some reason
+ */
ERROR_ARENA_TELEPORT_FAILED("&cUnable to teleport you to the arena."),
+
+ /**
+ * The message displayed if the player tries to quit the arena while not in an arena
+ */
ERROR_NOT_IN_ARENA("&cYou are not in a mini-games arena!"),
+
+ /**
+ * The message displayed if the player tries to join an arena while already playing
+ *
+ * This should in theory be impossible, as players cannot use any commands except /miniGamesLeave while playing
+ * in an arena.
+ */
ERROR_ALREADY_PLAYING("&cYou are already playing a mini-game!"),
+
+ /**
+ * The message displayed if a player tries to join an arena with a passenger or riding a vehicle
+ */
ERROR_JOIN_IN_VEHICLE_OR_PASSENGER("&cYou cannot join an arena while inside a vehicle or carrying a passenger."),
+
+ /**
+ * The message displayed if the player tries to change an unrecognized arena property
+ */
ERROR_UNKNOWN_PROPERTY("&cUnknown property specified."),
+
+ /**
+ * The message displayed if the given input to /dEdit or /pEdit's value is invalid
+ */
ERROR_PROPERTY_INPUT_INVALID("&cUnable to change the property. Make sure your input is valid!"),
+
+ /**
+ * The message displayed if the first arena specified in /dgSwap or /pgSwap is invalid
+ */
ERROR_ARENA_1_NOT_FOUND("&cUnable to find the first specified arena."),
+
+ /**
+ * The message displayed if the second arena specified in /dgSwap or /pgSwap is invalid
+ */
ERROR_ARENA_2_NOT_FOUND("&cUnable to find the second specified dropper arena."),
+
+ /**
+ * The message displayed if the two groups specified for /dgSwap or /pgSwap are in different arenas
+ */
ERROR_SWAP_DIFFERENT_GROUPS("&cYou cannot swap arenas in different groups!"),
+
+ /**
+ * The message displayed if a player tries to use any command other than /mLeave while in an arena
+ */
ERROR_ILLEGAL_COMMAND("&cYou cannot use that command while in an arena!"),
+
+ /* **************** *
+ * Success messages *
+ * **************** */
+
+ /**
+ * The message displayed if an arena's group has been changed
+ */
SUCCESS_ARENA_GROUP_UPDATED("&aThe arena's group has been updated"),
+
+ /**
+ * The message displayed if the MiniGames plugin is reloaded
+ */
SUCCESS_PLUGIN_RELOADED("&aPlugin reloaded!"),
+
+ /**
+ * The message displayed if a new arena has been created
+ */
SUCCESS_ARENA_CREATED("&aThe arena was successfully created!"),
+
+ /**
+ * The message displayed if a player clears/wins an arena for the first time
+ */
SUCCESS_ARENA_FIRST_CLEAR("&aYou cleared the arena!"),
+
+ /**
+ * The message displayed when a player wins an arena
+ */
SUCCESS_ARENA_WIN("&aYou won!"),
+
+ /**
+ * The message displayed when a player quits an arena
+ */
SUCCESS_ARENA_QUIT("&aYou quit the arena!"),
+
+ /**
+ * The message used to display the current value of an arena property
+ */
SUCCESS_CURRENT_VALUE("&aCurrent value of {property} is: {value}"),
+
+ /**
+ * The message used to announce that an arena property has been changed
+ */
SUCCESS_PROPERTY_CHANGED("&aProperty {property} successfully changed"),
+
+ /**
+ * The message displayed when two arenas' order in a group have been swapped
+ */
SUCCESS_ARENAS_SWAPPED("&aThe arenas have been swapped!"),
+
+ /**
+ * The message displayed when an arena has been removed
+ */
SUCCESS_ARENA_REMOVED("&aThe specified arena has been successfully removed"),
+
+ /**
+ * The header displayed before listing all dropper arenas
+ */
SUCCESS_DROPPER_ARENAS_LIST("&aDropper arenas:&r"),
+
+ /**
+ * The header displayed before listing all parkour arenas
+ */
SUCCESS_PARKOUR_ARENAS_LIST("&aParkour arenas:&r"),
+
+ /**
+ * The message displayed when a player reaches a new checkpoint in a parkour arena
+ */
SUCCESS_CHECKPOINT_REACHED("&aCheckpoint reached!"),
+
+ /**
+ * The header displayed before listing all arenas (stages) in a group
+ */
SUCCESS_GROUP_STAGES("&a{group}'s stages:&r"),
+
+ /**
+ * The message displayed when a new record has been achieved
+ */
SUCCESS_RECORD_ACHIEVED("&aYou just set a {recordInfo} on the {gameMode} game-mode!"),
+
+ /**
+ * The partial message used to describe that the player achieved a world record
+ */
RECORD_ACHIEVED_GLOBAL("new {recordType} record"),
+
+ /**
+ * The partial message used to describe that the player achieved a personal best record
+ */
RECORD_ACHIEVED_PERSONAL("personal {recordType} record"),
+
+ /**
+ * The message displayed when a player joins an arena
+ */
+ SUCCESS_ARENA_JOINED("&aYou joined the arena."),
;
private final @NotNull String defaultMessage;
@@ -86,6 +261,17 @@ public enum Message {
return formatMessage(this.defaultMessage.replace(placeholder, replacement));
}
+ /**
+ * Gets the message this enum represents, intended for display within another message
+ *
+ * @param placeholder The placeholder to replace
+ * @param replacement The replacement to use
+ * @return The formatted message
+ */
+ public @NotNull String getPartialMessage(@NotNull String placeholder, @NotNull String replacement) {
+ return ColorHelper.translateAllColorCodes(this.defaultMessage.replace(placeholder, replacement));
+ }
+
/**
* Gets the message this enum represents
*