diff --git a/Lobby/pom.xml b/Lobby/pom.xml
index 6480654..f074606 100644
--- a/Lobby/pom.xml
+++ b/Lobby/pom.xml
@@ -11,6 +11,17 @@
0.0.1-SNAPSHOT
../pom.xml
+
+
+ codemc-repo
+ https://repo.codemc.org/repository/maven-public/
+ default
+
+
+ viaversion-repo
+ https://repo.viaversion.com
+
+
de.iani.cubeside
@@ -18,6 +29,24 @@
1.0.0-SNAPSHOT
provided
+
+ de.tr7zw
+ item-nbt-api-plugin
+ 2.10.0-SNAPSHOT
+ provided
+
+
+ com.viaversion
+ viaversion-api
+ 4.7.1-SNAPSHOT
+ provided
+
+
+ de.fanta
+ Challenge
+ 0.0.1-SNAPSHOT
+ provided
+
diff --git a/Lobby/src/main/java/de/fanta/lobby/ChallengesGlobalDataHelper.java b/Lobby/src/main/java/de/fanta/lobby/ChallengesGlobalDataHelper.java
new file mode 100644
index 0000000..10ebc48
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/ChallengesGlobalDataHelper.java
@@ -0,0 +1,164 @@
+package de.fanta.lobby;
+
+import de.cubeside.connection.GlobalServer;
+import de.cubeside.connection.event.GlobalServerConnectedEvent;
+import de.cubeside.connection.event.GlobalServerDisconnectedEvent;
+import de.fanta.challenge.Challenge;
+import de.fanta.lobby.ChallengesGlobalDataHelper.ChallengeMessageType;
+import de.iani.cubesideutils.bukkit.plugin.api.GlobalDataHelperBukkit;
+import de.speedy64.globalport.GlobalApi;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.UUID;
+
+public class ChallengesGlobalDataHelper extends GlobalDataHelperBukkit implements Listener {
+
+ public static final String CHANNEL = "ChallengesJoinEntities";
+
+ private final Lobby plugin;
+
+ public ChallengesGlobalDataHelper(Lobby plugin) {
+ super(ChallengeMessageType.class, CHANNEL, plugin);
+ this.plugin = plugin;
+ }
+
+ @Override
+ protected void handleMessage(ChallengeMessageType challengeMessageType, GlobalServer globalServer, DataInputStream data) throws IOException {
+ String serverName = data.readUTF();
+ switch (challengeMessageType) {
+ case TIMER -> {
+ boolean running = data.readBoolean();
+ plugin.updateTimerStatus(serverName, running);
+ }
+ case EVENT -> {
+ boolean event = data.readBoolean();
+ plugin.updateEventStatus(serverName, event);
+ }
+ case SERVER_STATUS -> {
+ boolean online = data.readBoolean();
+ plugin.updateServerStatus(serverName, online);
+ }
+ case PLAYER_COUNT -> {
+ int count = data.readInt();
+ int maxPlayers = data.readInt();
+ plugin.updatePlayerCount(serverName, count, maxPlayers);
+ }
+ case INITIAL_DATA_REQUEST -> {
+ if (Bukkit.getPluginManager().getPlugin("Challenges") != null) {
+ Challenge challenges = (Challenge) Bukkit.getPluginManager().getPlugin("Challenge");
+ boolean timerRunning = challenges.getTimer().isRunning();
+ int playerCount = Bukkit.getOnlinePlayers().size();
+ int maxPlayers = Bukkit.getMaxPlayers();
+
+ sendInitialData(serverName, timerRunning, playerCount, maxPlayers);
+ }
+ }
+ case INITIAL_DATA -> {
+ boolean timerRunning = data.readBoolean();
+ int playerCount = data.readInt();
+ int maxPlayers = data.readInt();
+ plugin.updateTimerStatus(serverName, timerRunning);
+ plugin.updatePlayerCount(serverName, playerCount, maxPlayers);
+ }
+ default -> throw new UnsupportedOperationException();
+ }
+ }
+
+ public void sendTimerUpdate(boolean running) {
+ sendData(ChallengeMessageType.TIMER, getThisServerName(), running);
+ }
+
+ public void sendEventUpdate(boolean event) {
+ sendData(ChallengeMessageType.EVENT, getThisServerName(), event);
+ }
+
+ public void sendServerStatusUpdate(boolean online) {
+ sendData(ChallengeMessageType.SERVER_STATUS, getThisServerName(), online);
+ }
+
+ public void sendPlayerCountUpdate(int count) {
+ sendData(ChallengeMessageType.PLAYER_COUNT, getThisServerName(), count, Bukkit.getMaxPlayers());
+ }
+
+ public void requestInitialData(String fromServer) {
+ sendData(getServer(fromServer), ChallengeMessageType.INITIAL_DATA_REQUEST, getThisServerName());
+ }
+
+ public void sendInitialData(String toServer, boolean timerRunning, int playerCount, int maxPlayers) {
+ sendData(getServer(toServer), ChallengeMessageType.INITIAL_DATA, getThisServerName(), timerRunning, playerCount, maxPlayers);
+ }
+
+ @EventHandler
+ public void onGlobalServerConnected(GlobalServerConnectedEvent event) {
+ plugin.getScheduler().runGlobalDelayed(() -> {
+ if (plugin.getEntityData(event.getServer().getName()) != null) {
+ plugin.updateServerStatus(event.getServer().getName(), true);
+ this.requestInitialData(event.getServer().getName());
+ }
+
+ for (Server server : plugin.getPluginConfig().getChallengeServers()) {
+ if (server.getName().equals(event.getServer().getName())) {
+ UUID uuid = Server.serverPlayers.get(server);
+ if (uuid != null) {
+ Player p = Bukkit.getPlayer(uuid);
+ if (p != null) {
+ server.spawnPiglin(p);
+ GlobalApi.portOnlinePlayerToLocation(p.getName(), server.getGPLocation());
+ }
+ }
+ break;
+ }
+ }
+
+ for (Server server : plugin.getPluginConfig().getAdventureServers()) {
+ if (server.getName().equals(event.getServer().getName())) {
+ UUID uuid = Server.serverPlayers.get(server);
+ Player p = Bukkit.getPlayer(uuid);
+ if (p != null) {
+ server.spawnPiglin(p);
+ //server.spawnNPC(p);
+ GlobalApi.portOnlinePlayerToLocation(p.getName(), server.getGPLocation());
+ }
+ break;
+ }
+ }
+ }, 200L);
+ }
+
+ @EventHandler
+ public void onGlobalServerDisconnected(GlobalServerDisconnectedEvent event) {
+ if (plugin.getEntityData(event.getServer().getName()) != null) {
+ plugin.updateServerStatus(event.getServer().getName(), false);
+ }
+
+ for (Server server : plugin.getPluginConfig().getChallengeServers()) {
+ if (server.getName().equals(event.getServer().getName())) {
+ server.setOnline(false);
+ Server.serverPlayers.remove(server);
+ server.despawnPiglin();
+ break;
+ }
+ }
+
+ for (Server server : plugin.getPluginConfig().getAdventureServers()) {
+ if (server.getName().equals(event.getServer().getName())) {
+ server.setOnline(false);
+ Server.serverPlayers.remove(server);
+ //server.despawnNPC();
+ server.despawnPiglin();
+ break;
+ }
+ }
+
+ plugin.getAvailableServers().remove(event.getServer().getName());
+ }
+
+ public enum ChallengeMessageType {
+ TIMER, SERVER_STATUS, PLAYER_COUNT, INITIAL_DATA_REQUEST, INITIAL_DATA, EVENT
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/ChatUtil.java b/Lobby/src/main/java/de/fanta/lobby/ChatUtil.java
new file mode 100644
index 0000000..ef08e35
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/ChatUtil.java
@@ -0,0 +1,51 @@
+package de.fanta.lobby;
+
+import de.iani.cubesideutils.bukkit.ChatUtilBukkit;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class ChatUtil {
+
+ public static final ChatColor GREEN = ChatColor.of("#52ff9d");
+ public static final ChatColor ORANGE = ChatColor.of("#ffac4d");
+ public static final ChatColor RED = ChatColor.of("#ff6b6b");
+ public static final ChatColor BLUE = ChatColor.of("#87f7ea");
+ public static final ChatColor PINK = ChatColor.of("#FF04F7");
+
+ private ChatUtil() {
+ // prevent instances
+ }
+
+ public static void sendMessage(CommandSender sender, String colors, Object... messageParts) {
+ ChatUtilBukkit.sendMessage(sender, Lobby.PREFIX, colors, messageParts);
+ }
+
+ public static void sendNormalMessage(CommandSender sender, Object... messageParts) {
+ sendMessage(sender, GREEN.toString(), messageParts);
+ }
+
+ public static void sendWarningMessage(CommandSender sender, Object... messageParts) {
+ sendMessage(sender, ORANGE.toString(), messageParts);
+ }
+
+ public static void sendErrorMessage(CommandSender sender, Object... messageParts) {
+ sendMessage(sender, RED.toString(), messageParts);
+ }
+
+ public static void sendDebugMessage(CommandSender sender, Object... messageParts) {
+ if (sender.hasPermission("fanta.debug")) {
+ if (sender != null) {
+ sendMessage(sender, PINK.toString(), messageParts);
+ }
+ }
+ }
+
+ public static void sendBrodcastMessage(Object... messageParts) {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ sendMessage(player, GREEN.toString(), messageParts);
+ }
+ }
+}
+
diff --git a/Lobby/src/main/java/de/fanta/lobby/Config.java b/Lobby/src/main/java/de/fanta/lobby/Config.java
new file mode 100644
index 0000000..6950239
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/Config.java
@@ -0,0 +1,132 @@
+package de.fanta.lobby;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+
+public class Config {
+
+ private static Lobby plugin;
+ private static Set challengeServers;
+ private static Set adventureServers;
+
+ public Config(Lobby plugin) {
+ Config.plugin = plugin;
+ challengeServers = new HashSet<>();
+ adventureServers = new HashSet<>();
+
+ if (Bukkit.getPluginManager().getPlugin("Challenges") == null) {
+ plugin.saveDefaultConfig();
+ reloadConfig();
+ }
+ }
+
+ public static void reloadConfig() {
+ plugin.reloadConfig();
+ FileConfiguration config = plugin.getConfig();
+
+ ConfigurationSection piglinsSection = config.getConfigurationSection("piglins");
+ if (piglinsSection != null) {
+ for (String serverName : piglinsSection.getKeys(false)) {
+ ConfigurationSection piglin = piglinsSection.getConfigurationSection(serverName);
+ plugin.addPiglin(UUID.fromString(piglin.getString("uuid")), serverName, piglin.getString("gpLocation"), piglin.getString("displayName"), false);
+ plugin.getGlobalDataHelper().requestInitialData(serverName);
+ }
+ }
+
+ ConfigurationSection filaPathSection = config.getConfigurationSection("fileLocations");
+ if (filaPathSection != null) {
+ plugin.setChallengeSavePath(new File(filaPathSection.getString("challengeSaves")).toPath());
+ plugin.setAdventureSavePath(new File(filaPathSection.getString("adventureSaves")).toPath());
+ plugin.setAventureMapsPath(new File(filaPathSection.getString("adventureMaps")).toPath());
+ plugin.setServerJarsPath(new File(filaPathSection.getString("serverJars")).toPath());
+ plugin.setServerFolderPath(new File(filaPathSection.getString("serverFolder")).toPath());
+ }
+
+ ConfigurationSection challengeServerSection = config.getConfigurationSection("challenge");
+ if (challengeServerSection != null) {
+ for (String serverName : challengeServerSection.getKeys(false)) {
+ ConfigurationSection server = challengeServerSection.getConfigurationSection(serverName);
+
+ ConfigurationSection locSection = server.getConfigurationSection("location");
+ World world = Bukkit.getWorld(locSection.getString("world"));
+ double x = locSection.getDouble("x");
+ double y = locSection.getDouble("y");
+ double z = locSection.getDouble("z");
+ float yaw = (float) locSection.getDouble("yaw");
+ Location location = new Location(world, x, y, z, yaw, 0.0F);
+
+ challengeServers.add(new Server(serverName, null, server.getString("gpLocation"), server.getString("dir"), ServerType.CHALLENGES, plugin, location));
+ }
+ }
+
+ ConfigurationSection adventureServerSection = config.getConfigurationSection("adventure");
+ if (adventureServerSection != null) {
+ for (String serverName : adventureServerSection.getKeys(false)) {
+ ConfigurationSection server = adventureServerSection.getConfigurationSection(serverName);
+
+ ConfigurationSection locSection = server.getConfigurationSection("location");
+ World world = Bukkit.getWorld(locSection.getString("world"));
+ double x = locSection.getDouble("x");
+ double y = locSection.getDouble("y");
+ double z = locSection.getDouble("z");
+ float yaw = (float) locSection.getDouble("yaw");
+ Location location = new Location(world, x, y, z, yaw, 0.0F);
+
+ adventureServers.add(new Server(serverName, null, server.getString("gpLocation"), server.getString("dir"), ServerType.ADVENTURE, plugin, location));
+ }
+ }
+
+ }
+
+ public void savePiglin(JoinEntityData data) {
+ FileConfiguration config = plugin.getConfig();
+ ConfigurationSection piglinsSection = config.getConfigurationSection("piglins");
+
+ if (piglinsSection == null) {
+ config.createSection("piglins");
+ piglinsSection = config.getConfigurationSection("piglins");
+ }
+
+ ConfigurationSection piglin = piglinsSection.createSection(data.getServerName());
+ piglin.set("uuid", data.getEntityUUID().toString());
+ piglin.set("gpLocation", data.getGlobalPortLocationName());
+ piglin.set("displayName", data.getServerDisplayName());
+
+ plugin.saveConfig();
+ }
+
+ public void removePiglin(String serverName) {
+ FileConfiguration config = plugin.getConfig();
+ ConfigurationSection piglinsSection = config.getConfigurationSection("piglins");
+
+ piglinsSection.set(serverName, null);
+
+ plugin.saveConfig();
+ }
+
+ public Set getChallengeServers() {
+ return challengeServers;
+ }
+
+ public Set getAdventureServers() {
+ return adventureServers;
+ }
+
+ public Optional getOnlineChanllengeServer() {
+ return challengeServers.stream().filter(server -> !server.isOnline()).findFirst();
+ }
+
+ public Optional getOnlineAdventureServer() {
+ return adventureServers.stream().filter(server -> !server.isOnline()).findFirst();
+ }
+}
+
diff --git a/Lobby/src/main/java/de/fanta/lobby/JoinEntityData.java b/Lobby/src/main/java/de/fanta/lobby/JoinEntityData.java
new file mode 100644
index 0000000..6fbfca2
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/JoinEntityData.java
@@ -0,0 +1,101 @@
+package de.fanta.lobby;
+
+import net.md_5.bungee.api.ChatColor;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+public class JoinEntityData {
+
+ private final String serverName;
+ private final UUID entityUUID;
+ private final String globalPortLocationName;
+ private final String serverDisplayName;
+ private ServerStatus serverStatus;
+ private EventStatus eventStatus;
+ private int playerCount;
+ private int maxPlayers;
+
+ private final int mapVersion;
+
+ public JoinEntityData(String serverName, @Nullable Integer mapVersion, UUID entityUUID, String globalPortLocationName, String serverDisplayName, ServerStatus serverStatus, EventStatus eventStatus, int playerCount, int maxPlayers) {
+ this.serverName = serverName;
+ this.mapVersion = mapVersion == null ? 0 : mapVersion;
+ this.entityUUID = entityUUID;
+ this.globalPortLocationName = globalPortLocationName;
+ this.serverDisplayName = serverDisplayName;
+ this.serverStatus = serverStatus;
+ this.eventStatus = eventStatus;
+ this.playerCount = playerCount;
+ this.maxPlayers = maxPlayers;
+ }
+
+ public String getServerName() {
+ return serverName;
+ }
+
+ public UUID getEntityUUID() {
+ return entityUUID;
+ }
+
+ public String getGlobalPortLocationName() {
+ return globalPortLocationName;
+ }
+
+ public String getServerDisplayName() {
+ return serverDisplayName;
+ }
+
+ public ServerStatus getServerStatus() {
+ return serverStatus;
+ }
+
+ public void setServerStatus(ServerStatus serverStatus) {
+ this.serverStatus = serverStatus;
+ }
+
+ public void setEventStatus(EventStatus eventStatus) {
+ this.eventStatus = eventStatus;
+ }
+
+ public EventStatus getEventStatus() {
+ return eventStatus;
+ }
+
+ public int getPlayerCount() {
+ return playerCount;
+ }
+
+ public void setPlayerCount(int playerCount) {
+ this.playerCount = playerCount;
+ }
+
+ public int getMaxPlayers() {
+ return maxPlayers;
+ }
+
+ public void setMaxPlayers(int maxPlayers) {
+ this.maxPlayers = maxPlayers;
+ }
+
+ public int getMapVersion() {
+ return mapVersion;
+ }
+
+ public String createCustomEntityName() {
+ String statusString = serverStatus == ServerStatus.ONLINE ? ChatUtil.GREEN + "ONLINE" : serverStatus == ServerStatus.OFFLINE ? ChatUtil.RED + "OFFLINE" : serverStatus == ServerStatus.RUNNING ? ChatUtil.ORANGE + "RUNNING" : "";
+ String playerCountString = ChatUtil.BLUE + "(" + playerCount + "/" + maxPlayers + ")";
+ if (eventStatus == EventStatus.EVENT) {
+ return ChatUtil.RED + "" + ChatColor.BOLD + "Event" + " " + statusString + (serverStatus != ServerStatus.OFFLINE ? (" " + playerCountString) : " ");
+ }
+ return ChatUtil.BLUE + serverDisplayName + " " + statusString + (serverStatus != ServerStatus.OFFLINE ? (" " + playerCountString) : "");
+ }
+
+ public enum ServerStatus {
+ ONLINE, RUNNING, OFFLINE
+ }
+
+ public enum EventStatus {
+ EVENT, NORMAL
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/Lobby.java b/Lobby/src/main/java/de/fanta/lobby/Lobby.java
index c767c10..4816649 100644
--- a/Lobby/src/main/java/de/fanta/lobby/Lobby.java
+++ b/Lobby/src/main/java/de/fanta/lobby/Lobby.java
@@ -1,36 +1,490 @@
-package de.fanta.adventure;
+package de.fanta.lobby;
+import de.cubeside.nmsutils.NMSUtils;
+import de.fanta.lobby.adventure.AdventureMapsConfig;
+import de.fanta.lobby.adventure.CategoriesConfig;
+import de.fanta.lobby.commands.AdventureCommand.AdventureAddCategoryCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureAddMapCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureClearSavesCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureConvertMapCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureLoadCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureLoadMapIconsCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureMapsCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureStartEventServerCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureTempCommand;
+import de.fanta.lobby.commands.AdventureCommand.AdventureTestMapCommand;
+import de.fanta.lobby.commands.AdventureCommand.ChallengesRemovePlayerServer;
+import de.fanta.lobby.commands.ChallengesCommand.ChallengeClearSavesCommand;
+import de.fanta.lobby.commands.ChallengesCommand.ChallengeListUserStatsCommand;
+import de.fanta.lobby.commands.ChallengesCommand.ChallengeLoadCommand;
+import de.fanta.lobby.commands.ChallengesCommand.ChallengeSetStatsCommand;
+import de.fanta.lobby.commands.ChallengesCommand.ChallengesStatsCommand;
+import de.fanta.lobby.commands.PiglinCommand.AddEntityCommand;
+import de.fanta.lobby.commands.PiglinCommand.Entitytphere;
+import de.fanta.lobby.commands.PiglinCommand.ListPiglinCommand;
+import de.fanta.lobby.commands.PiglinCommand.RemoveEntityCommand;
+import de.fanta.lobby.commands.PiglinCommand.SetEntitySpawnLocationCommand;
+import de.fanta.lobby.commands.PiglinCommand.ToggleArenaCommand;
+import de.fanta.lobby.listeners.ChallengesEventListener;
+import de.fanta.lobby.listeners.EntityListener;
+import de.fanta.lobby.listeners.PlayerListener;
+import de.fanta.lobby.schedular.BukkitScheduler;
+import de.fanta.lobby.schedular.Scheduler;
+import de.fanta.lobby.utils.Statistics;
+import de.iani.cubesidestats.api.CubesideStatisticsAPI;
+import de.iani.cubesideutils.bukkit.commands.CommandRouter;
+import de.iani.playerUUIDCache.PlayerUUIDCache;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.format.TextColor;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Piglin;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.Nullable;
-import java.io.File;
-import java.util.logging.Logger;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.logging.Level;
-public final class Lobby extends JavaPlugin {
+public class Lobby extends JavaPlugin {
- private Lobby plugin;
- private Logger LOGGER;
+ public static final String PREFIX = ChatUtil.BLUE + "[" + ChatUtil.GREEN + "Lobby" + ChatUtil.BLUE + "]";
+ public static final String ADVENTUREGUIPREFIX = ChatColor.of("#2d8745") + "Adventure";
+ public static final String CHALLENGEGUIPREFIX = ChatColor.of("#2d8745") + "Challenge";
- @Override
- public void onLoad() {
- plugin = this;
- LOGGER = getLogger();
- File oldPluginFolder = new File("plugins/Challenges");
- if (oldPluginFolder.isDirectory()) {
- if (!oldPluginFolder.renameTo(new File("plugins/Adventure"))) {
- LOGGER.severe("Challenges Ordner konnte nicht in Adventure umgenannt werden!");
- plugin.getServer().shutdown();
- }
- }
+ private static final TextColor BRACKETS = TextColor.fromHexString("#87f7ea");
+
+ public static final TextComponent PREFIX_COMPONENT = Component.text("[", BRACKETS).append(Component.text("Lobby", TextColor.fromHexString("#52ff9d"))).append(Component.text("] ", BRACKETS));
+
+ private static Lobby plugin;
+ private final Map entityData;
+ private final Map entityServerMapping;
+ private final Set availableServers;
+ public NMSUtils nmsUtils;
+ private Config config;
+ private ChallengesGlobalDataHelper globalDataHelper;
+ private CategoriesConfig categoriesConfig;
+ private AdventureMapsConfig adventureMapsConfig;
+ private PlayerUUIDCache playerUUIDCache;
+
+ private CubesideStatisticsAPI cubesideStatistics;
+ private Statistics statistics;
+ //private static SignManager signManager;
+ private final List eventServerPlayerList;
+
+ private Scheduler scheduler;
+
+ private Path challengeSavePath;
+ private Path adventureSavePath;
+ private Path aventureMapsPath;
+ private Path serverJarsPath;
+ private Path serverFolderPath;
+
+
+ public Lobby() {
+ this.entityData = new HashMap<>();
+ this.entityServerMapping = new HashMap<>();
+ this.availableServers = new HashSet<>();
+ this.eventServerPlayerList = new ArrayList<>();
+ }
+
+ public static Lobby getPlugin() {
+ return plugin;
}
@Override
public void onEnable() {
- // Plugin startup logic
+ plugin = this;
+ playerUUIDCache = (PlayerUUIDCache) getServer().getPluginManager().getPlugin("PlayerUUIDCache");
+ nmsUtils = getServer().getServicesManager().load(NMSUtils.class);
+ if (getServer().getPluginManager().isPluginEnabled("CubesideStatistics")) {
+ cubesideStatistics = getServer().getServicesManager().load(CubesideStatisticsAPI.class);
+ statistics = new Statistics(this);
+ }
+
+ /*if (getServer().getPluginManager().isPluginEnabled("SignGUI")) {
+ signManager = new SignManager(this);
+ signManager.init();
+ }*/
+
+ /*try {
+ Class.forName("io.papermc.paper.threadedregions.scheduler.ScheduledTask");
+ getLogger().log(Level.INFO, "Folia found. Use Folia Scheduler");
+ scheduler = new FoliaScheduler(this);
+ } catch (Throwable ignored) {
+ getLogger().log(Level.INFO, "Bukkit found. Use Bukkit Scheduler");
+ scheduler = new BukkitScheduler(this);
+ }*/
+ getLogger().log(Level.INFO, "Bukkit found. Use Bukkit Scheduler");
+ scheduler = new BukkitScheduler(this);
+
+
+ this.globalDataHelper = new ChallengesGlobalDataHelper(this);
+ this.config = new Config(this);
+ loadCategoriesAndMaps();
+
+ if (Bukkit.getPluginManager().getPlugin("Challenges") != null) { // Challenge server -> listen on Challenge events
+ Bukkit.getPluginManager().registerEvents(new ChallengesEventListener(this), this);
+ } else { // Lobby server -> register commands
+ CommandRouter router = new CommandRouter(getCommand("piglins"));
+ router.addCommandMapping(new AddEntityCommand(this), "spawn");
+ router.addCommandMapping(new RemoveEntityCommand(this), "remove");
+ router.addCommandMapping(new Entitytphere(this), "tphere");
+ router.addCommandMapping(new ListPiglinCommand(this), "list");
+ router.addCommandMapping(new SetEntitySpawnLocationCommand(this), "setlocation");
+ router.addCommandMapping(new ToggleArenaCommand(this, true), "enable");
+ router.addCommandMapping(new ToggleArenaCommand(this, false), "disable");
+
+ CommandRouter challengesrouter = new CommandRouter(getCommand("challenges"));
+ challengesrouter.addCommandMapping(new ChallengeLoadCommand(this), "load");
+ challengesrouter.addCommandMapping(new ChallengesStatsCommand(plugin.getStatistics()), "stats");
+ challengesrouter.addCommandMapping(new ChallengeSetStatsCommand(plugin), "setstats");
+ challengesrouter.addCommandMapping(new ChallengeClearSavesCommand(plugin), "clearoldsaves");
+ challengesrouter.addCommandMapping(new ChallengeListUserStatsCommand(plugin), "listuserstats");
+
+ CommandRouter adventurerouter = new CommandRouter(getCommand("adventure"));
+ adventurerouter.addCommandMapping(new AdventureLoadCommand(this), "load");
+ adventurerouter.addCommandMapping(new AdventureAddCategoryCommand(this), "addcategory");
+ adventurerouter.addCommandMapping(new AdventureAddMapCommand(this), "addmap");
+ adventurerouter.addCommandMapping(new AdventureMapsCommand(this), "maps");
+ adventurerouter.addCommandMapping(new AdventureTestMapCommand(this), "testmap");
+ adventurerouter.addCommandMapping(new ChallengesRemovePlayerServer(this), "removeplayerfromserver");
+ adventurerouter.addCommandMapping(new AdventureConvertMapCommand(this), "convertmap");
+ adventurerouter.addCommandMapping(new AdventureLoadMapIconsCommand(this), "loadmapicons");
+ adventurerouter.addCommandMapping(new AdventureClearSavesCommand(plugin), "clearoldsaves");
+ adventurerouter.addCommandMapping(new AdventureTempCommand(this), "temp");
+ adventurerouter.addCommandMapping(new AdventureStartEventServerCommand(this), "starteventserver");
+
+ Bukkit.getPluginManager().registerEvents(new EntityListener(this), this);
+ Bukkit.getPluginManager().registerEvents(new PlayerListener(this), this);
+ }
+
+ Bukkit.getPluginManager().registerEvents(globalDataHelper, this);
}
@Override
public void onDisable() {
- // Plugin shutdown logic
+ saveCategoriesAndMaps();
+ getPluginConfig().getChallengeServers().forEach(Server::despawnPiglin);
+ getPluginConfig().getAdventureServers().forEach(Server::despawnPiglin);
+ }
+
+ public void spawnPiglin(Location location, String serverName, @Nullable Integer serverVersion, String gpLocationName, String serverDisplayName) {
+ spawnPiglin(location, serverName, serverVersion, gpLocationName, serverDisplayName, true);
+ }
+
+ public void spawnPiglin(Location location, String serverName, @Nullable Integer serverVersion, String gpLocationName, String serverDisplayName, boolean saveToConfig) {
+ if (entityData.containsKey(serverName)) {
+ despawnPiglin(entityData.get(serverName).getEntityUUID(), serverName);
+ }
+ Piglin piglin = (Piglin) location.getWorld().spawnEntity(location, EntityType.PIGLIN, CreatureSpawnEvent.SpawnReason.CUSTOM, t -> ((Piglin) t).getEquipment().clear());
+ piglin.setAI(false);
+ piglin.setSilent(true);
+ piglin.setRemoveWhenFarAway(false);
+ piglin.setPersistent(true);
+ piglin.setCustomNameVisible(true);
+ addPiglin(piglin.getUniqueId(), serverName, serverVersion, gpLocationName, serverDisplayName, saveToConfig);
+
+ globalDataHelper.requestInitialData(serverName);
+ }
+
+ public void despawnPiglin(UUID piglinUUID, String serverName) {
+ Entity piglin = Bukkit.getEntity(piglinUUID);
+ if (piglin != null) {
+ piglin.remove();
+ removePiglin(serverName);
+ }
+ }
+
+ public void despawnPiglin(String serverName) {
+ if (entityData.get(serverName) != null) {
+ despawnPiglin(entityData.get(serverName).getEntityUUID(), serverName);
+ }
+ }
+
+ public void spawnNPC(Location location, String serverName, String gpLocationName, String serverDisplayName, boolean saveToConfig) {
+ if (entityData.containsKey(serverName)) {
+ despawnNPC(entityData.get(serverName).getEntityUUID(), serverDisplayName);
+ }
+ if (plugin.getServer().getPluginManager().getPlugin("CubesideNPCs") == null) {
+ return;
+ }
+ //addPiglin(CubesideNPCs.getPlugin().spawnNPC(serverDisplayName, location), serverName, gpLocationName, serverDisplayName, saveToConfig);
+
+ globalDataHelper.requestInitialData(serverName);
+ }
+
+ public void despawnNPC(String serverName) {
+ if (entityData.get(serverName) != null) {
+ despawnNPC(entityData.get(serverName).getEntityUUID(), serverName);
+ }
+ }
+
+ public void despawnNPC(UUID piglinUUID, String serverName) {
+ if (plugin.getServer().getPluginManager().getPlugin("CubesideNPCs") == null) {
+ return;
+ }
+ //CubesideNPCs.getPlugin().removeNPC(piglinUUID);
+ removePiglin(serverName);
+ }
+
+ public void addPiglin(UUID piglinUUID, String serverName, String gpLocationName, String serverDisplayName, boolean saveToConfig) {
+ addPiglin(piglinUUID, serverName, null, gpLocationName, serverDisplayName, saveToConfig);
+ }
+
+ public void addPiglin(UUID piglinUUID, String serverName, @Nullable Integer mapVersion, String gpLocationName, String serverDisplayName, boolean saveToConfig) {
+ JoinEntityData entityData = new JoinEntityData(serverName, mapVersion, piglinUUID, gpLocationName, serverDisplayName, JoinEntityData.ServerStatus.OFFLINE, JoinEntityData.EventStatus.NORMAL, 0, 0);
+ this.entityData.put(serverName, entityData);
+ this.entityServerMapping.put(piglinUUID, serverName);
+
+ if (saveToConfig) {
+ this.config.savePiglin(entityData);
+ }
+ }
+
+ public void removePiglin(String serverName) {
+ JoinEntityData data = this.entityData.remove(serverName);
+ if (data != null) {
+ this.entityServerMapping.remove(data.getEntityUUID());
+ }
+
+ this.config.removePiglin(serverName);
+ }
+
+ public void updateTimerStatus(String serverName, boolean running) {
+ JoinEntityData data = entityData.get(serverName);
+ if (data != null) {
+ data.setServerStatus(running ? JoinEntityData.ServerStatus.RUNNING : JoinEntityData.ServerStatus.ONLINE);
+ updatePiglinCustomName(serverName);
+ updatePiglinBehaviour(serverName);
+ }
+ }
+
+ public void updateEventStatus(String serverName, boolean event) {
+ JoinEntityData data = entityData.get(serverName);
+ if (data != null) {
+ data.setEventStatus(event ? JoinEntityData.EventStatus.EVENT : JoinEntityData.EventStatus.NORMAL);
+ updatePiglinCustomName(serverName);
+ updatePiglinBehaviour(serverName);
+ }
+ }
+
+ public void updateServerStatus(String serverName, boolean online) {
+ JoinEntityData data = entityData.get(serverName);
+
+ if (data != null) {
+ data.setServerStatus(online ? JoinEntityData.ServerStatus.ONLINE : JoinEntityData.ServerStatus.OFFLINE);
+
+ updatePiglinCustomName(serverName);
+ updatePiglinBehaviour(serverName);
+ }
+ }
+
+ public void updatePlayerCount(String serverName, int count, int maxPlayers) {
+ JoinEntityData data = entityData.get(serverName);
+
+ if (data != null) {
+ data.setPlayerCount(count);
+ data.setMaxPlayers(maxPlayers);
+
+ updatePiglinCustomName(serverName);
+ updatePiglinBehaviour(serverName);
+ }
+ }
+
+ public Piglin getPiglinForServerName(String serverName) {
+ JoinEntityData data = entityData.get(serverName);
+ if (data != null) {
+ Entity piglin = Bukkit.getEntity(data.getEntityUUID());
+
+ if (piglin instanceof Piglin) {
+ return (Piglin) piglin;
+ }
+ }
+ return null;
+ }
+
+ public void updatePiglinCustomName(String serverName) {
+ Entity entity = getPiglinForServerName(serverName);
+ JoinEntityData data = entityData.get(serverName);
+
+ if (entity == null) {
+ return;
+ }
+
+ if (data == null) {
+ return;
+ }
+ String customName = data.createCustomEntityName();
+ entity.setCustomName(customName);
+ }
+
+ public void updatePiglinBehaviour(String serverName) {
+ Piglin piglin = getPiglinForServerName(serverName);
+ JoinEntityData data = entityData.get(serverName);
+
+ if (piglin != null && data != null) {
+ if (data.getPlayerCount() < data.getMaxPlayers()) {
+ switch (data.getServerStatus()) {
+ case ONLINE -> {
+ piglin.getEquipment().clear();
+ if (nmsUtils != null) {
+ nmsUtils.getEntityUtils().setPiglinDancing(piglin, true);
+ }
+ }
+ case OFFLINE -> {
+ if (nmsUtils != null) {
+ nmsUtils.getEntityUtils().setPiglinDancing(piglin, false);
+ }
+
+ piglin.getEquipment().setItemInOffHand(new ItemStack(Material.GOLD_INGOT));
+ }
+ case RUNNING -> {
+ piglin.getEquipment().clear();
+ if (nmsUtils != null) {
+ nmsUtils.getEntityUtils().setPiglinDancing(piglin, false);
+ }
+ }
+ }
+ } else { // server is full
+ piglin.getEquipment().clear();
+ if (nmsUtils != null) {
+ nmsUtils.getEntityUtils().setPiglinDancing(piglin, false);
+ }
+ }
+ }
+ }
+
+ public void saveCategoriesAndMaps() {
+ this.adventureMapsConfig.save();
+ this.categoriesConfig.save();
+ }
+
+ public void loadCategoriesAndMaps() {
+ this.categoriesConfig = new CategoriesConfig(this);
+ this.adventureMapsConfig = new AdventureMapsConfig(this);
+ this.adventureMapsConfig.load();
+ this.categoriesConfig.load();
+ }
+
+ public void reloadCategoriesAndMaps() {
+ getLogger().log(Level.INFO, "Maps werden gespeichert und neu geladen.");
+ saveCategoriesAndMaps();
+ loadCategoriesAndMaps();
+ getLogger().log(Level.INFO, "Maps wurden neu geladen.");
+ }
+
+ public PlayerUUIDCache getPlayerUUIDCache() {
+ return playerUUIDCache;
+ }
+
+ public AdventureMapsConfig getAdventureMapsConfig() {
+ return this.adventureMapsConfig;
+ }
+
+ public CategoriesConfig getCategoriesConfig() {
+ return this.categoriesConfig;
+ }
+
+ public Config getPluginConfig() {
+ return config;
+ }
+
+ public ChallengesGlobalDataHelper getGlobalDataHelper() {
+ return globalDataHelper;
+ }
+
+ public boolean isJoinEntity(Entity entity) {
+ return entityServerMapping.containsKey(entity.getUniqueId());
+ }
+
+ public JoinEntityData getEntityData(String serverName) {
+ return entityData.get(serverName);
+ }
+
+ public String getServerNameForEntity(UUID entityUUID) {
+ return entityServerMapping.get(entityUUID);
+ }
+
+ public Map getEntityData() {
+ return entityData;
+ }
+
+ public Set getAvailableServers() {
+ return availableServers;
+ }
+
+ public CubesideStatisticsAPI getCubesideStatistics() {
+ return cubesideStatistics;
+ }
+
+ public Statistics getStatistics() {
+ return statistics;
+ }
+
+ /*public SignManager getSignManager() {
+ return signManager;
+ }*/
+
+ public List getEventServerPlayerList() {
+ return eventServerPlayerList;
+ }
+
+ public Scheduler getScheduler() {
+ return scheduler;
+ }
+
+ public Path getChallengeSavePath() {
+ return challengeSavePath;
+ }
+
+ public void setChallengeSavePath(Path challengeSavePath) {
+ this.challengeSavePath = challengeSavePath;
+ }
+
+ public Path getAdventureSavePath() {
+ return adventureSavePath;
+ }
+
+ public void setAdventureSavePath(Path adventureSavePath) {
+ this.adventureSavePath = adventureSavePath;
+ }
+
+ public Path getAdventureMapsPath() {
+ return aventureMapsPath;
+ }
+
+ public void setAventureMapsPath(Path aventureMapsPath) {
+ this.aventureMapsPath = aventureMapsPath;
+ }
+
+ public Path getServerJarsPath() {
+ return serverJarsPath;
+ }
+
+ public void setServerJarsPath(Path serverJarsPath) {
+ this.serverJarsPath = serverJarsPath;
+ }
+
+ public Path getServerFolderPath() {
+ return serverFolderPath;
+ }
+
+ public void setServerFolderPath(Path serverFolderPath) {
+ this.serverFolderPath = serverFolderPath;
}
}
diff --git a/Lobby/src/main/java/de/fanta/lobby/SaveSlot.java b/Lobby/src/main/java/de/fanta/lobby/SaveSlot.java
new file mode 100644
index 0000000..863cb67
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/SaveSlot.java
@@ -0,0 +1,25 @@
+package de.fanta.lobby;
+
+public enum SaveSlot {
+
+ SLOT_1("1", "challenge.save.slot1"),
+ SLOT_2("2", "challenge.save.slot2"),
+ SLOT_3("3", "challenge.save.slot3"),
+ SLOT_AUTO("autosave", "challenge.save.slotauto");
+
+ private final String slot;
+ private final String permission;
+
+ SaveSlot(String prefix, String permission) {
+ this.slot = prefix;
+ this.permission = permission;
+ }
+
+ public String getSlot() {
+ return slot;
+ }
+
+ public String getPermission() {
+ return permission;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/Server.java b/Lobby/src/main/java/de/fanta/lobby/Server.java
new file mode 100644
index 0000000..7f83c81
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/Server.java
@@ -0,0 +1,318 @@
+package de.fanta.lobby;
+
+import com.viaversion.viaversion.api.Via;
+import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
+import org.apache.commons.io.FileUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class Server {
+ public static HashMap serverPlayers = new HashMap<>();
+
+ private final Lobby plugin;
+
+ private final String name;
+
+ private int serverVersion;
+
+ private final String gPLocation;
+
+ private final String dir;
+
+ private final ServerType serverType;
+
+ private final Location piglinLocation;
+
+ private boolean online;
+
+ public Server(String name, @Nullable Integer serverVersion, String gPLocation, String dir, ServerType serverType, Lobby plugin, Location piglinLocation) {
+ this.name = name;
+ this.serverVersion = serverVersion == null ? 0 : serverVersion;
+ this.gPLocation = gPLocation;
+ this.dir = dir;
+ this.serverType = serverType;
+ this.plugin = plugin;
+ this.online = (plugin.getGlobalDataHelper().getServer(name) != null);
+ this.piglinLocation = piglinLocation;
+ }
+
+ public static Server getServerfromPlayer(Player p) {
+ Server server = null;
+ if (serverPlayers.containsValue(p.getUniqueId()))
+ for (Map.Entry entry : serverPlayers.entrySet()) {
+ if (entry.getValue().equals(p.getUniqueId()))
+ server = entry.getKey();
+ }
+ return server;
+ }
+
+ public boolean isOnline() {
+ return this.online;
+ }
+
+ public void setOnline(boolean online) {
+ this.online = online;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getGPLocation() {
+ return this.gPLocation;
+ }
+
+ public void setServerVersion(int serverVersion) {
+ this.serverVersion = serverVersion;
+ }
+
+ public void loadSaved(Player p, UUID playerID, String slot) {
+ this.online = true;
+ serverPlayers.put(this, p.getUniqueId());
+ File dir;
+ //dir = new File("/home/minecraft/" + this.serverType.getDir() + "/" + playerID + "/" + slot);
+ if (serverType == ServerType.CHALLENGES) {
+ dir = new File(plugin.getChallengeSavePath().toFile(), "/" + playerID + "/" + slot);
+ } else {
+ dir = new File(plugin.getAdventureSavePath().toFile(), "/" + playerID + "/" + slot);
+ }
+
+ String path = playerID + "/" + slot;
+
+
+ if (!dir.isDirectory()) {
+ ChatUtil.sendErrorMessage(p, "Map " + path + " nicht gefunden!");
+ this.online = false;
+ serverPlayers.remove(this);
+ return;
+ }
+ load(p, this.serverType.getDir(), path, getMapVersion(new File(dir + "/Challenges/serverconfig.yml")));
+ }
+
+ public void loadNewAdventure(Player player, String category, String map, String mapVersion) {
+ int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId());
+ int mapProtocolVersion = ProtocolVersion.getClosest(mapVersion).getVersion();
+ if (playerVersion >= mapProtocolVersion) {
+ this.online = true;
+ serverPlayers.put(this, player.getUniqueId());
+ //File dir = new File("/home/storagebox/Adventure-Maps", category + "/" + map);
+ File dir = new File(plugin.getAdventureMapsPath().toFile(), category + "/" + map);
+ if (!dir.isDirectory()) {
+ ChatUtil.sendErrorMessage(player, "Map " + map + " nicht gefunden!");
+ this.online = false;
+ serverPlayers.remove(this);
+ return;
+ }
+
+ load(player, "Adventure-Maps", category + "/" + map, getMapVersion(new File(dir + "/Challenges/serverconfig.yml")));
+ } else {
+ ChatUtil.sendErrorMessage(player, "Du brauchst mindestens die Version " + ChatUtil.BLUE + mapVersion + ChatUtil.RED + " um die Map zu starten!");
+ }
+ }
+
+ public void load(Player p, String serverTypeDir, String targetDir, String ServerVersion) {
+ plugin.getScheduler().runAsync(() -> {
+ File serverFolder = new File(plugin.getServerFolderPath().toFile(), this.dir);
+ File configs = new File(serverFolder, "/plugins/Challenges");
+ File end = new File(serverFolder, "/world_the_end");
+ File nether = new File(serverFolder, "/world_nether");
+ File world = new File(serverFolder, "/world");
+ File mlgworld = new File(serverFolder, "/mlg_challenge");
+ File serverJar = new File(serverFolder, "/paper.jar");
+ File saveServerJar = new File(plugin.getServerJarsPath().toFile(), ServerVersion + "/paper.jar");
+ File saveend;
+ File savenether;
+ File saveworld;
+ File saveconfigs;
+
+
+ if (!serverTypeDir.equals("Adventure-Maps")) {
+ saveend = new File(plugin.getChallengeSavePath().toFile(), targetDir + "/world_the_end");
+ savenether = new File(plugin.getChallengeSavePath().toFile(), targetDir + "/world_nether");
+ saveworld = new File(plugin.getChallengeSavePath().toFile(), targetDir + "/world");
+ saveconfigs = new File(plugin.getChallengeSavePath().toFile(), targetDir + "/Challenges");
+ } else {
+ saveend = new File(plugin.getAdventureMapsPath().toFile(), targetDir + "/world_the_end");
+ savenether = new File(plugin.getAdventureMapsPath().toFile(), targetDir + "/world_nether");
+ saveworld = new File(plugin.getAdventureMapsPath().toFile(), targetDir + "/world");
+ saveconfigs = new File(plugin.getAdventureMapsPath().toFile(), targetDir + "/Challenges");
+ }
+
+ ChatUtil.sendNormalMessage(p, "Versuche Map zu laden!");
+ try {
+ if (world.isDirectory()) {
+ FileUtils.deleteDirectory(world);
+ FileUtils.deleteDirectory(end);
+ FileUtils.deleteDirectory(nether);
+ }
+ if (mlgworld.isDirectory()) {
+ FileUtils.deleteDirectory(mlgworld);
+ }
+ if (serverJar.exists()) {
+ FileUtils.delete(serverJar);
+ }
+ if (configs.isDirectory()) {
+ FileUtils.deleteDirectory(configs);
+ }
+
+ HashMap copyMap = new HashMap<>();
+ copyMap.put(saveServerJar, serverJar);
+ copyMap.put(saveconfigs, configs);
+ copyMap.put(saveworld, world);
+ copyMap.put(savenether, nether);
+ copyMap.put(saveend, end);
+ moveFolderWithProgress(copyMap, p);
+
+
+ File serverConfigFile = new File(plugin.getServerFolderPath().toFile(), this.dir + "/plugins/Challenges/serverconfig.yml");
+ YamlConfiguration serverConfig = new YamlConfiguration();
+ serverConfig.load(serverConfigFile);
+
+ String tempServerType = serverConfig.getString("servertype");
+ if (tempServerType == null || tempServerType.equals("CHALLENGE")) {
+ serverConfig.set("servertype", "CHALLENGE_LOAD");
+ serverConfig.save(serverConfigFile);
+ Bukkit.getLogger().info(serverConfigFile.getAbsolutePath());
+ }
+
+ if (tempServerType != null && serverConfig.getString("servertype").equals("ADVENTURE")) {
+ setServerVersion(ProtocolVersion.getClosest(serverConfig.getString("serverversion")).getVersion());
+ }
+
+ } catch (IOException | InvalidConfigurationException e) {
+ e.printStackTrace();
+ ChatUtil.sendErrorMessage(p, "Map konnte nicht geladen werden!");
+ this.online = false;
+ serverPlayers.remove(this);
+ return;
+ }
+ ChatUtil.sendNormalMessage(p, "Map wurde geladen! Server wird nun gestartet!");
+ start(p);
+ });
+ }
+
+ public static void moveFolderWithProgress(HashMap copyMap, Player player) throws IOException {
+ final long[] totalBytes = {0};
+ final long[] copiedBytes = {0};
+ AtomicReference progress = new AtomicReference<>(0.0);
+
+ for (File sourceFolder : copyMap.keySet()) {
+ Files.walk(sourceFolder.toPath()).forEach(source -> {
+ if (!Files.isDirectory(source)) {
+ totalBytes[0] += source.toFile().length();
+ }
+ });
+ }
+
+ for (File sourceFolder : copyMap.keySet()) {
+ Files.walk(sourceFolder.toPath()).forEach(source -> {
+ try {
+ File target = new File(copyMap.get(sourceFolder).toPath().resolve(sourceFolder.toPath().relativize(source)).toString());
+ if (Files.isDirectory(source)) {
+ target.mkdir();
+ } else {
+ Files.copy(source, target.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ copiedBytes[0] += source.toFile().length();
+ progress.set((double) copiedBytes[0] / totalBytes[0] * 100);
+ player.sendActionBar(ChatUtil.GREEN + "Kopiere Welt: " + getProgressBar(progress.get()));
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+ }
+
+ public static String getProgressBar(double value) {
+ int progress = (int) (value / 100 * 40);
+
+ StringBuilder progressBar = new StringBuilder();
+ progressBar.append(ChatUtil.RED + "[");
+ for (int i = 0; i < 40; i++) {
+ if (i < progress) {
+ progressBar.append(ChatUtil.PINK + "|");
+ } else {
+ progressBar.append(ChatUtil.GREEN + "|");
+ }
+ }
+ progressBar.append(ChatUtil.RED + "] " + ChatUtil.PINK + String.format("%.2f", value) + "%");
+
+ return progressBar.toString();
+ }
+
+ public void start(Player player) {
+ ProcessBuilder processBuilder = new ProcessBuilder();
+ boolean eventServer = false;
+ if (this.serverType == ServerType.ADVENTURE && plugin.getEventServerPlayerList().contains(player.getUniqueId())) {
+ //processBuilder.command("screen", "-AmdS", player.getName(), "./event.sh").directory(new File("/home/minecraft/Server/" + this.dir));
+ processBuilder.command("screen", "-AmdS", player.getName(), "./event.sh").directory(new File(plugin.getServerFolderPath().toFile(), this.dir));
+ plugin.getEventServerPlayerList().remove(player.getUniqueId());
+ eventServer = true;
+ } else {
+ //processBuilder.command("screen", "-AmdS", player.getName(), "./start.sh").directory(new File("/home/minecraft/Server/" + this.dir));
+ processBuilder.command("screen", "-AmdS", player.getName(), "./start.sh").directory(new File(plugin.getServerFolderPath().toFile(), this.dir));
+ }
+
+ try {
+ processBuilder.start();
+ Bukkit.getLogger().info(this.serverType.toString().toLowerCase() + (eventServer ? " Event Server: " : " Server: ") + getServerfromPlayer(player).gPLocation + " wurde von " + player.getName() + " gestartet!");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void spawnPiglin(Player player) {
+ this.plugin.spawnPiglin(this.piglinLocation, this.name, this.serverVersion, this.gPLocation, player.getName(), false);
+ }
+
+ public void despawnPiglin() {
+ this.plugin.despawnPiglin(this.name);
+ }
+
+ public void spawnNPC(Player player) {
+ this.plugin.spawnNPC(this.piglinLocation, this.name, this.gPLocation, player.getName(), false);
+ }
+
+ public void despawnNPC() {
+ this.plugin.despawnNPC(this.name);
+ }
+
+ public String getMapVersion(File config) {
+ String serverVersion;
+ YamlConfiguration serverConfiguration = new YamlConfiguration();
+ if (!config.exists()) {
+ serverVersion = "latest";
+ return serverVersion;
+ }
+ try {
+ serverConfiguration.load(config);
+ } catch (IOException | InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+ String configServerVersion = serverConfiguration.getString("serverversion");
+ if (configServerVersion != null) {
+ File serverversionfolder = new File(plugin.getServerJarsPath().toFile(), configServerVersion);
+ if (serverversionfolder.isDirectory()) {
+ serverVersion = configServerVersion;
+ } else {
+ serverVersion = "latest";
+ }
+ } else {
+ serverVersion = "latest";
+ }
+ return serverVersion;
+ }
+}
\ No newline at end of file
diff --git a/Lobby/src/main/java/de/fanta/lobby/ServerType.java b/Lobby/src/main/java/de/fanta/lobby/ServerType.java
new file mode 100644
index 0000000..a3241c9
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/ServerType.java
@@ -0,0 +1,17 @@
+package de.fanta.lobby;
+
+public enum ServerType {
+
+ ADVENTURE("Adventure-saves"),
+ CHALLENGES("saves");
+
+ private final String dir;
+
+ ServerType(String dir) {
+ this.dir = dir;
+ }
+
+ public String getDir() {
+ return dir;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/AdventureMap.java b/Lobby/src/main/java/de/fanta/lobby/adventure/AdventureMap.java
new file mode 100644
index 0000000..7cdf56a
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/AdventureMap.java
@@ -0,0 +1,76 @@
+package de.fanta.lobby.adventure;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class AdventureMap {
+ private final Lobby plugin;
+
+ private final String name;
+ private final String version;
+
+ private final ItemStack item;
+
+ private final String creator;
+
+ private final String webLink;
+
+ public AdventureMap(Lobby plugin, String name, String version, Material material, String creator, String webLink) {
+ this.name = name;
+ this.version = version;
+ this.creator = creator;
+ this.webLink = webLink;
+ this.plugin = plugin;
+ this.item = new ItemStack((material != null) ? material : Material.STONE);
+ ItemMeta meta = this.item.getItemMeta();
+ meta.setDisplayName("" + ChatUtil.ORANGE + ChatColor.BOLD + getName().replace("_", " "));
+ List lore = new ArrayList<>();
+ lore.add("");
+ lore.add(ChatUtil.GREEN + "Erbauer: " + ChatUtil.BLUE + creator);
+ lore.add(ChatUtil.GREEN + "Version: " + ChatUtil.BLUE + version);
+ lore.add(ChatUtil.GREEN + "MapLink: " + ChatUtil.BLUE + "Rechts Klick");
+ lore.add(ChatUtil.GREEN + "Map laden: " + ChatUtil.BLUE + "Links Klick");
+ meta.setLore(lore);
+ this.item.setItemMeta(meta);
+ }
+
+ public AdventureMap(Lobby plugin, String name, ConfigurationSection section) {
+ this(plugin, name, section.getString("version"), Material.matchMaterial(Objects.requireNonNull(section.getString("item"))), section.getString("creator"), section.getString("web_link"));
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public ItemStack getItem() {
+ return this.item;
+ }
+
+ public String getCreator() {
+ return this.creator;
+ }
+
+ public String getWebLink() {
+ return this.webLink;
+ }
+
+ public void save(ConfigurationSection section) {
+ section.set("item", this.item.getType().getKey().toString());
+ section.set("creator", this.creator);
+ section.set("web_link", this.webLink);
+ section.set("version", this.version);
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/AdventureMapsConfig.java b/Lobby/src/main/java/de/fanta/lobby/adventure/AdventureMapsConfig.java
new file mode 100644
index 0000000..e284273
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/AdventureMapsConfig.java
@@ -0,0 +1,87 @@
+package de.fanta.lobby.adventure;
+
+import com.google.common.collect.ImmutableMap;
+import de.fanta.lobby.Lobby;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AdventureMapsConfig {
+ private final Lobby plugin;
+
+ private final Map maps = new HashMap<>();
+
+ private static File file;
+
+ private static YamlConfiguration config;
+
+ public AdventureMapsConfig(Lobby plugin) {
+ this.plugin = plugin;
+ file = new File(plugin.getDataFolder(), "adventure_maps.yml");
+ config = new YamlConfiguration();
+ }
+
+ private boolean fileExists() throws IOException {
+ if (!file.exists())
+ return file.createNewFile();
+ return true;
+ }
+
+ public void load() {
+ try {
+ if (fileExists()) {
+ config.load(file);
+ config.getKeys(false).forEach(key -> {
+ ConfigurationSection section = config.getConfigurationSection(key);
+ if (section != null) {
+ AdventureMap map = new AdventureMap(this.plugin, key, section);
+ if (!this.maps.containsKey(key)) {
+ this.maps.put(key, map);
+ }
+ }
+ });
+ }
+ } catch (IOException | org.bukkit.configuration.InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void save() {
+ this.maps.forEach((key, map) -> map.save(config.createSection(key)));
+ try {
+ config.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean addMap(AdventureMap map) {
+ if (!this.maps.containsKey(map.getName())) {
+ this.maps.put(map.getName(), map);
+ return true;
+ }
+ return false;
+ }
+
+ public Map getMaps() {
+ return ImmutableMap.copyOf(this.maps);
+ }
+
+ @Nullable
+ public AdventureMap getMap(String name) {
+ return this.maps.get(name);
+ }
+
+ public static YamlConfiguration getConfig() {
+ return config;
+ }
+
+ public static File getFile() {
+ return file;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/CategoriesConfig.java b/Lobby/src/main/java/de/fanta/lobby/adventure/CategoriesConfig.java
new file mode 100644
index 0000000..886daea
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/CategoriesConfig.java
@@ -0,0 +1,98 @@
+package de.fanta.lobby.adventure;
+
+import com.google.common.collect.ImmutableMap;
+import de.fanta.lobby.Lobby;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class CategoriesConfig {
+ private final Lobby plugin;
+
+ private final Map categories = new HashMap<>();
+
+ private static File file;
+
+ private static YamlConfiguration config;
+
+ public CategoriesConfig(Lobby plugin) {
+ this.plugin = plugin;
+ file = new File(plugin.getDataFolder(), "categories.yml");
+ config = new YamlConfiguration();
+ }
+
+ private boolean fileExists() throws IOException {
+ if (!file.exists())
+ return file.createNewFile();
+ return true;
+ }
+
+ public void load() {
+ try {
+ if (fileExists()) {
+ config.load(file);
+ config.getKeys(false).forEach(key -> {
+ ConfigurationSection section = config.getConfigurationSection(key);
+ if (section != null) {
+ Category category = new Category(this.plugin, key, section);
+ if (!this.categories.containsKey(key))
+ this.categories.put(key, category);
+ }
+ });
+ }
+ } catch (IOException | org.bukkit.configuration.InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void save() {
+ this.categories.forEach((key, category) -> category.save(config.createSection(key)));
+ try {
+ config.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean addCategory(Category category) {
+ if (!this.categories.containsKey(category.getName())) {
+ this.categories.put(category.getName(), category);
+ return true;
+ }
+ return false;
+ }
+
+ public Map getCategories() {
+ return ImmutableMap.copyOf(this.categories);
+ }
+
+ @Nullable
+ public Category getCategory(String name) {
+ return this.categories.get(name);
+ }
+
+ public Category getCategorybyMap(AdventureMap adventureMap) {
+ for (Category category : plugin.getCategoriesConfig().getCategories().values()) {
+ for (AdventureMap adventureMapTemp : category.getMaps()) {
+ if (Objects.equals(adventureMap.getName(), adventureMapTemp.getName())) {
+ return category;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static File getFile() {
+ return file;
+ }
+
+ public static YamlConfiguration getConfig() {
+ return config;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/Category.java b/Lobby/src/main/java/de/fanta/lobby/adventure/Category.java
new file mode 100644
index 0000000..19733cd
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/Category.java
@@ -0,0 +1,74 @@
+package de.fanta.lobby.adventure;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class Category {
+ private final String name;
+
+ private final ItemStack item;
+
+ private final Set maps;
+
+ private final Lobby plugin = Lobby.getPlugin();
+
+ public Category(String name, Material material) {
+ this(name, material, new HashSet<>());
+ }
+
+ public Category(Lobby plugin, String name, ConfigurationSection section) {
+ this(name, Material.matchMaterial(Objects.requireNonNull(section.getString("item"))), section.getStringList("maps").stream().map(mapName -> {
+ AdventureMap map = plugin.getAdventureMapsConfig().getMap(mapName);
+ if (map == null)
+ plugin.getLogger().warning("Die map \"" + mapName + "\" existiert nicht!");
+ return map;
+ }).filter(Objects::nonNull).collect(Collectors.toSet()));
+ }
+
+ public Category(String name, Material material, Set maps) {
+ this.name = name;
+ this.maps = maps;
+ this.item = new ItemStack((material != null) ? material : Material.STONE);
+ ItemMeta meta = this.item.getItemMeta();
+ meta.setDisplayName("" + ChatUtil.ORANGE + ChatColor.BOLD + getName().replace("_", " "));
+ List lore = new ArrayList<>();
+ lore.add("");
+ lore.add(ChatUtil.GREEN + "Maps: " + ChatUtil.BLUE + maps.size());
+ meta.setLore(lore);
+ this.item.setItemMeta(meta);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public ItemStack getItem() {
+ return this.item;
+ }
+
+ public Set getMaps() {
+ return this.maps;
+ }
+
+ public void addMap(AdventureMap map) {
+ this.maps.add(map);
+ plugin.reloadCategoriesAndMaps();
+ }
+
+ public void save(ConfigurationSection section) {
+ section.set("item", this.item.getType().getKey().toString());
+ section.set("maps", this.maps.stream().map(AdventureMap::getName).collect(Collectors.toList()));
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/ui/AdventureMapsUI.java b/Lobby/src/main/java/de/fanta/lobby/adventure/ui/AdventureMapsUI.java
new file mode 100644
index 0000000..dade396
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/ui/AdventureMapsUI.java
@@ -0,0 +1,156 @@
+package de.fanta.lobby.adventure.ui;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.Server;
+import de.fanta.lobby.adventure.AdventureMap;
+import de.fanta.lobby.adventure.Category;
+import de.iani.cubesideutils.bukkit.inventory.AbstractWindow;
+import de.iani.cubesideutils.bukkit.items.CustomHeads;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.event.ClickEvent;
+import net.kyori.adventure.text.format.TextColor;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Color;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+public class AdventureMapsUI extends AbstractWindow {
+ private final Lobby plugin;
+ private final Category category;
+ private static final int NUM_OF_COLUMNS = 9;
+ private static final int NUM_OF_ITEM_COLUMNS = NUM_OF_COLUMNS - 1;
+ private static final int NUM_OF_ROWS = 6;
+ private static final int WINDOW_SIZE = NUM_OF_COLUMNS * NUM_OF_ROWS;
+ private static final int END_OF_FIRST_ROW_INDEX = NUM_OF_COLUMNS - 1;
+ private static final int END_OF_LAST_ROW_INDEX = WINDOW_SIZE - 1;
+
+ private final List maps;
+ private final int numOfItemRows;
+ private int scrollAmount;
+
+ public AdventureMapsUI(Lobby plugin, Category category, Player player) {
+ super(player, Bukkit.createInventory(player, WINDOW_SIZE, ChatUtil.RED + category.getName().replace("_", " ") + " Map's"));
+ this.category = category;
+ this.plugin = plugin;
+
+ List maps = this.category.getMaps().stream().sorted(Comparator.comparing(AdventureMap::getName)).toList();
+ this.maps = new ArrayList<>(maps.size());
+ this.maps.addAll(maps);
+
+ this.numOfItemRows = (int) (Math.ceil(this.maps.size() / (double) NUM_OF_ITEM_COLUMNS));
+ this.scrollAmount = 0;
+ }
+
+ protected void rebuildInventory() {
+ ItemStack[] content = new ItemStack[WINDOW_SIZE];
+
+ // build scroll buttons
+ ItemStack scrollUpHead = this.scrollAmount <= 0 ? CustomHeads.RAINBOW_BLANK.getHead() : CustomHeads.RAINBOW_ARROW_UP.getHead();
+ ItemMeta scrollUpMeta = scrollUpHead.getItemMeta();
+ scrollUpMeta.setDisplayName((this.scrollAmount <= 0 ? ChatColor.GRAY : ChatColor.WHITE) + "Nach oben scrollen");
+ scrollUpHead.setItemMeta(scrollUpMeta);
+ content[NUM_OF_COLUMNS - 1] = scrollUpHead;
+
+ ItemStack scrollDownHead = this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS ? CustomHeads.RAINBOW_BLANK.getHead() : CustomHeads.RAINBOW_ARROW_DOWN.getHead();
+ ItemMeta scrollDownMeta = scrollDownHead.getItemMeta();
+ scrollDownMeta.setDisplayName((this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS ? ChatColor.GRAY : ChatColor.WHITE) + "Nach unten scrollen");
+ scrollDownHead.setItemMeta(scrollDownMeta);
+ content[WINDOW_SIZE - 1] = scrollDownHead;
+
+ // build scrollbar
+ for (int i = 1; i < NUM_OF_ROWS - 1; i++) {
+ content[(i + 1) * NUM_OF_COLUMNS - 1] = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
+ }
+ int numOfScrollbarRows = NUM_OF_ROWS - 2;
+ int currentScrollbarRow =
+ (int) Math.round(this.scrollAmount * numOfScrollbarRows / (double) this.numOfItemRows);
+ content[(currentScrollbarRow + 2) * NUM_OF_COLUMNS - 1] = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
+
+ // fill in items
+ int index = this.scrollAmount * NUM_OF_ITEM_COLUMNS;
+ for (int row = 0; row < NUM_OF_ROWS && index < this.maps.size(); row++) {
+ for (int column = 0; column < NUM_OF_ITEM_COLUMNS && index < this.maps.size(); column++) {
+ AdventureMap adventureMap = this.maps.get(index++);
+ content[row * NUM_OF_COLUMNS + column] = adventureMap == null ? null : adventureMap.getItem();
+ }
+ }
+
+ getInventory().setContents(content);
+ }
+
+ public void onItemClicked(InventoryClickEvent event) {
+ if (!mayAffectThisInventory(event)) {
+ return;
+ }
+
+ event.setCancelled(true);
+
+ if (!getInventory().equals(event.getClickedInventory())) {
+ return;
+ }
+
+ int slot = event.getSlot();
+ if (slot == END_OF_FIRST_ROW_INDEX) {
+ attempScrollUp();
+ return;
+ } else if (slot == END_OF_LAST_ROW_INDEX) {
+ attempScrollDown();
+ return;
+ }
+
+ if ((slot + 1) % NUM_OF_COLUMNS == 0) {
+ int numOfScrollbarRows = NUM_OF_ROWS - 2;
+ int selectedScrollBarRow = (slot + 1) / NUM_OF_COLUMNS - 2;
+ int targetScrollAmount = Math.round(selectedScrollBarRow * this.numOfItemRows / numOfScrollbarRows);
+ this.scrollAmount = Math.min(targetScrollAmount, this.numOfItemRows - NUM_OF_ROWS);
+ this.scrollAmount = Math.max(this.scrollAmount, 0);
+ rebuildInventory();
+ return;
+ }
+
+ int shopItemIndex = (slot - (slot / NUM_OF_COLUMNS)) + this.scrollAmount * NUM_OF_ITEM_COLUMNS;
+ if (shopItemIndex >= this.maps.size()) {
+ return;
+ }
+
+ AdventureMap map = this.maps.get(shopItemIndex);
+ Player p = getPlayer();
+
+ if (map != null) {
+ if (event.isRightClick()) {
+ getPlayer().sendMessage(Lobby.PREFIX_COMPONENT.append(Component.text("MapLink: klick mich :)", TextColor.color(Color.YELLOW.asRGB())).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, map.getWebLink()))));
+ } else if (!Server.serverPlayers.containsValue(p.getUniqueId())) {
+ getPlayer().closeInventory();
+ this.plugin.getPluginConfig().getOnlineAdventureServer().ifPresentOrElse(server -> server.loadNewAdventure(p, category.getName(), map.getName(), map.getVersion()), () -> ChatUtil.sendErrorMessage(p, "Aktuell ist kein Server Frei!"));
+ } else {
+ ChatUtil.sendErrorMessage(p, "Du kannst nur einen Server starten!");
+ }
+ getPlayer().closeInventory();
+ }
+ }
+
+ private void attempScrollUp() {
+ if (this.scrollAmount <= 0) {
+ return;
+ }
+ this.scrollAmount--;
+ rebuildInventory();
+ }
+
+ private void attempScrollDown() {
+ if (this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS) {
+ return;
+ }
+ this.scrollAmount++;
+ rebuildInventory();
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/ui/AdventureSearchGUI.java b/Lobby/src/main/java/de/fanta/lobby/adventure/ui/AdventureSearchGUI.java
new file mode 100644
index 0000000..7a19dcf
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/ui/AdventureSearchGUI.java
@@ -0,0 +1,172 @@
+package de.fanta.lobby.adventure.ui;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.Server;
+import de.fanta.lobby.adventure.AdventureMap;
+import de.fanta.lobby.adventure.Category;
+import de.iani.cubesideutils.bukkit.inventory.AbstractWindow;
+import de.iani.cubesideutils.bukkit.items.CustomHeads;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.event.ClickEvent;
+import net.kyori.adventure.text.format.TextColor;
+import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Color;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.UUID;
+
+public class AdventureSearchGUI extends AbstractWindow {
+ private final Lobby plugin;
+ private static final int NUM_OF_COLUMNS = 9;
+ private static final int NUM_OF_ITEM_COLUMNS = NUM_OF_COLUMNS - 1;
+ private static final int NUM_OF_ROWS = 6;
+ private static final int WINDOW_SIZE = NUM_OF_COLUMNS * NUM_OF_ROWS;
+ private static final int END_OF_FIRST_ROW_INDEX = NUM_OF_COLUMNS - 1;
+ private static final int END_OF_LAST_ROW_INDEX = WINDOW_SIZE - 1;
+
+ private static final int BACK_INDEX = 0;
+
+ private static final HashMap> mapsByPlayer = new HashMap<>();
+ private final int numOfItemRows;
+ private int scrollAmount;
+
+ public AdventureSearchGUI(Lobby plugin, TreeMap mapList, String seachEntry, Player player) {
+ super(player, Bukkit.createInventory(player, WINDOW_SIZE, ChatUtil.GREEN + "Suche: " + ChatUtil.BLUE + seachEntry));
+ this.plugin = plugin;
+
+ HashMap maps = new HashMap<>(mapList);
+ mapsByPlayer.put(player.getUniqueId(), maps);
+ this.numOfItemRows = (int) (Math.ceil(maps.size() / (double) NUM_OF_ITEM_COLUMNS));
+ this.scrollAmount = 0;
+ }
+
+ protected void rebuildInventory() {
+ ItemStack[] content = new ItemStack[WINDOW_SIZE];
+
+ // build scroll buttons
+ ItemStack scrollUpHead = this.scrollAmount <= 0 ? CustomHeads.RAINBOW_BLANK.getHead() : CustomHeads.RAINBOW_ARROW_UP.getHead();
+ ItemMeta scrollUpMeta = scrollUpHead.getItemMeta();
+ scrollUpMeta.setDisplayName((this.scrollAmount <= 0 ? ChatColor.GRAY : ChatColor.WHITE) + "Nach oben scrollen");
+ scrollUpHead.setItemMeta(scrollUpMeta);
+ content[NUM_OF_COLUMNS - 1] = scrollUpHead;
+
+ ItemStack scrollDownHead = this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS ? CustomHeads.RAINBOW_BLANK.getHead() : CustomHeads.RAINBOW_ARROW_DOWN.getHead();
+ ItemMeta scrollDownMeta = scrollDownHead.getItemMeta();
+ scrollDownMeta.setDisplayName((this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS ? ChatColor.GRAY : ChatColor.WHITE) + "Nach unten scrollen");
+ scrollDownHead.setItemMeta(scrollDownMeta);
+ content[WINDOW_SIZE - 1] = scrollDownHead;
+
+ // build scrollbar
+ for (int i = 1; i < NUM_OF_ROWS - 1; i++) {
+ content[(i + 1) * NUM_OF_COLUMNS - 1] = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
+ }
+ int numOfScrollbarRows = NUM_OF_ROWS - 2;
+ int currentScrollbarRow =
+ (int) Math.round(this.scrollAmount * numOfScrollbarRows / (double) this.numOfItemRows);
+ content[(currentScrollbarRow + 2) * NUM_OF_COLUMNS - 1] = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
+
+ // fill in items
+ int index = this.scrollAmount * NUM_OF_ITEM_COLUMNS;
+ HashMap maps = mapsByPlayer.get(getPlayer().getUniqueId());
+ for (int row = 1; row < NUM_OF_ROWS && index < maps.size(); row++) {
+ for (int column = 0; column < NUM_OF_ITEM_COLUMNS && index < maps.size(); column++) {
+ AdventureMap adventureMap = new ArrayList<>(maps.values()).get(index++);
+ ItemStack stack = adventureMap.getItem().clone();
+ ItemMeta meta = stack.getItemMeta();
+ List lore = meta.getLore();
+ lore.add(ChatUtil.GREEN + "Kategorie: " + ChatUtil.BLUE + plugin.getCategoriesConfig().getCategorybyMap(adventureMap).getName());
+ meta.setLore(lore);
+ stack.setItemMeta(meta);
+ content[row * NUM_OF_COLUMNS + column] = adventureMap == null ? null : stack;
+ }
+ }
+
+ content[BACK_INDEX] = CustomHeads.RAINBOW_ARROW_BACKWARD_II.getHead(ChatUtil.GREEN + "Zurück");
+ getInventory().setContents(content);
+ }
+
+ public void onItemClicked(InventoryClickEvent event) {
+ if (!mayAffectThisInventory(event)) {
+ return;
+ }
+
+ event.setCancelled(true);
+
+ if (!getInventory().equals(event.getClickedInventory())) {
+ return;
+ }
+
+ int slot = event.getSlot();
+
+ if (slot == BACK_INDEX) {
+ new CategoryUI(this.plugin, this.plugin.getCategoriesConfig(), getPlayer()).open();
+ return;
+ }
+
+ if (slot == END_OF_FIRST_ROW_INDEX) {
+ attempScrollUp();
+ return;
+ } else if (slot == END_OF_LAST_ROW_INDEX) {
+ attempScrollDown();
+ return;
+ }
+
+ if ((slot + 1) % NUM_OF_COLUMNS == 0) {
+ int numOfScrollbarRows = NUM_OF_ROWS - 2;
+ int selectedScrollBarRow = (slot + 1) / NUM_OF_COLUMNS - 2;
+ int targetScrollAmount = Math.round(selectedScrollBarRow * this.numOfItemRows / numOfScrollbarRows);
+ this.scrollAmount = Math.min(targetScrollAmount, this.numOfItemRows - NUM_OF_ROWS);
+ this.scrollAmount = Math.max(this.scrollAmount, 0);
+ rebuildInventory();
+ return;
+ }
+
+ int adventureMapIndex = ((slot - (slot / NUM_OF_COLUMNS)) + this.scrollAmount * NUM_OF_ITEM_COLUMNS) - NUM_OF_COLUMNS + 1;
+ HashMap maps = mapsByPlayer.get(getPlayer().getUniqueId());
+ if (adventureMapIndex >= maps.size()) {
+ return;
+ }
+
+ AdventureMap map = new ArrayList<>(maps.values()).get(adventureMapIndex);
+ Player p = getPlayer();
+
+ if (map != null) {
+ Category category = plugin.getCategoriesConfig().getCategorybyMap(map);
+ if (event.isRightClick()) {
+ getPlayer().sendMessage(Lobby.PREFIX_COMPONENT.append(Component.text("MapLink: klick mich :)", TextColor.color(Color.YELLOW.asRGB())).clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, map.getWebLink()))));
+ } else if (!Server.serverPlayers.containsValue(p.getUniqueId())) {
+ getPlayer().closeInventory();
+ this.plugin.getPluginConfig().getOnlineAdventureServer().ifPresentOrElse(server -> server.loadNewAdventure(p, category.getName(), map.getName(), map.getVersion()), () -> ChatUtil.sendErrorMessage(p, "Aktuell ist kein Server Frei!"));
+ } else {
+ ChatUtil.sendErrorMessage(p, "Du kannst nur einen Server starten!");
+ }
+ getPlayer().closeInventory();
+ }
+ }
+
+ private void attempScrollUp() {
+ if (this.scrollAmount <= 0) {
+ return;
+ }
+ this.scrollAmount--;
+ rebuildInventory();
+ }
+
+ private void attempScrollDown() {
+ if (this.scrollAmount >= this.numOfItemRows - NUM_OF_ROWS) {
+ return;
+ }
+ this.scrollAmount++;
+ rebuildInventory();
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/adventure/ui/CategoryUI.java b/Lobby/src/main/java/de/fanta/lobby/adventure/ui/CategoryUI.java
new file mode 100644
index 0000000..4ad3529
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/adventure/ui/CategoryUI.java
@@ -0,0 +1,113 @@
+package de.fanta.lobby.adventure.ui;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.adventure.CategoriesConfig;
+import de.fanta.lobby.adventure.Category;
+import de.fanta.lobby.utils.ItemUtil;
+import de.iani.cubesideutils.bukkit.inventory.AbstractWindow;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CategoryUI extends AbstractWindow {
+ private final Lobby plugin;
+
+ private final CategoriesConfig config;
+
+ private final Map categoryPerSlot = new HashMap<>();
+
+ private final int SEARCH_INDEX = 0;
+
+ public CategoryUI(Lobby plugin, CategoriesConfig config, Player player) {
+ super(player, Bukkit.createInventory(player, 9 * (config.getCategories().size() / 7 + ((config.getCategories().size() % 7 > 0) ? 1 : 0)) + 18, ChatUtil.BLUE + "Adventure Map Kategorien"));
+ this.config = config;
+ this.plugin = plugin;
+ }
+
+ protected void rebuildInventory() {
+ Map categories = this.config.getCategories();
+ List sortedValues = categories.values().stream().sorted(Comparator.comparing(Category::getName)).toList();
+ int row = 0;
+ int cat = 0;
+ for (Category category : sortedValues) {
+ int slot = row * 9 + cat + 10;
+ getInventory().setItem(slot, category.getItem());
+ this.categoryPerSlot.put(slot, category);
+ if (cat < 6) {
+ cat++;
+ continue;
+ }
+ row++;
+ cat = 0;
+ }
+
+ ItemStack searchItem = new ItemStack(Material.DARK_OAK_SIGN);
+ ItemMeta itemMeta = searchItem.getItemMeta();
+ itemMeta.setDisplayName(ChatUtil.GREEN + "Suche");
+ String[] lore = {ChatUtil.GREEN + "Suche nach Adventure Maps"};
+ itemMeta.setLore(Arrays.stream(lore).toList());
+ searchItem.setItemMeta(itemMeta);
+
+ getInventory().setItem(SEARCH_INDEX, searchItem);
+
+ for (int i1 = 0; i1 < getInventory().getSize(); i1++) {
+ ItemStack item = getInventory().getItem(i1);
+ if (item == null) {
+ getInventory().setItem(i1, ItemUtil.EMPTY_ICON);
+ }
+ }
+ }
+
+ public void onItemClicked(InventoryClickEvent event) {
+ super.onItemClicked(event);
+ int slot = event.getSlot();
+
+ if (slot == SEARCH_INDEX) {
+ /*SignGUI gui = new SignGUI(plugin.getSignManager(), signEvent -> new BukkitRunnable() {
+ @Override
+ public void run() {
+ String line1 = signEvent.getLines()[0];
+ if (line1 != null && !line1.equals("")) {
+ HashMap maps = new HashMap<>();
+ for (Category category : plugin.getCategoriesConfig().getCategories().values()) {
+ for (AdventureMap adventureMap : category.getMaps()) {
+ if (adventureMap.getName().toLowerCase().replace("_" , " ").contains(line1.toLowerCase())) {
+ maps.put(adventureMap.getName(), adventureMap);
+ }
+ }
+ }
+
+ if (maps.isEmpty()) {
+ ChatUtil.sendErrorMessage(signEvent.getPlayer(), "Kein Ergebnis mit deinem Suchbegriff.");
+ } else {
+ TreeMap sortedMaps = new TreeMap<>(maps);
+ new AdventureSearchGUI(plugin, sortedMaps, line1, getPlayer()).open();
+ }
+
+ } else {
+ ChatUtil.sendErrorMessage(signEvent.getPlayer(), "Kein Ergebnis mit deinem Suchbegriff.");
+ }
+ }
+ }.runTaskLater(plugin, 1));
+ String[] lines = {"", "^^^^^^^^^^^^^^^", "Suche nach", "Adventure Maps"};
+ gui.withLines(lines);
+ gui.open(getPlayer());*/
+ return;
+ }
+
+ Category category = this.categoryPerSlot.get(slot);
+ if (category != null) {
+ new AdventureMapsUI(this.plugin, category, getPlayer()).open();
+ }
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureAddCategoryCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureAddCategoryCommand.java
new file mode 100644
index 0000000..1b2b235
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureAddCategoryCommand.java
@@ -0,0 +1,48 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.adventure.CategoriesConfig;
+import de.fanta.lobby.adventure.Category;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.Material;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class AdventureAddCategoryCommand extends SubCommand {
+ private final CategoriesConfig config;
+
+ public AdventureAddCategoryCommand(Lobby plugin) {
+ this.config = plugin.getCategoriesConfig();
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+ if (!p.hasPermission("challenges.createcategorie")) {
+ ChatUtil.sendErrorMessage(sender, "Keine Rechte!");
+ return true;
+ }
+ Material item = p.getInventory().getItemInMainHand().getType();
+ if (item == Material.AIR) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Item in der Hand haben!");
+ return true;
+ }
+ if (args.hasNext()) {
+ String name = args.getNext();
+ Category category = new Category(name, item);
+ if (!this.config.addCategory(category)) {
+ ChatUtil.sendErrorMessage(sender, "Die category " + name + " existiert bereits!");
+ return true;
+ }
+ ChatUtil.sendNormalMessage(sender, "Die category " + name + " wurde erfolgreich hinzugefügt!");
+ this.config.save();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureAddMapCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureAddMapCommand.java
new file mode 100644
index 0000000..4c8c7e6
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureAddMapCommand.java
@@ -0,0 +1,74 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.adventure.AdventureMap;
+import de.fanta.lobby.adventure.AdventureMapsConfig;
+import de.fanta.lobby.adventure.Category;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.Material;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class AdventureAddMapCommand extends SubCommand {
+ private final Lobby plugin;
+
+ private final AdventureMapsConfig config;
+
+ public AdventureAddMapCommand(Lobby plugin) {
+ this.plugin = plugin;
+ this.config = plugin.getAdventureMapsConfig();
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+ if (!p.hasPermission("challenges.createadventuremap")) {
+ ChatUtil.sendErrorMessage(sender, "Keine Rechte!");
+ return true;
+ }
+ Material item = p.getInventory().getItemInMainHand().getType();
+ if (item == Material.AIR) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Item in der Hand haben!");
+ return true;
+ }
+ if (args.hasNext()) {
+ String name = args.getNext();
+ if (args.hasNext()) {
+ String categoryName = args.getNext();
+ Category category = this.plugin.getCategoriesConfig().getCategory(categoryName);
+ if (category == null) {
+ ChatUtil.sendErrorMessage(sender, "Die Kategorie " + categoryName + " existiert nicht!");
+ return true;
+ }
+ if (args.hasNext()) {
+ String webLink = args.getNext();
+ webLink = webLink.equalsIgnoreCase("null") ? "" : webLink;
+ if (args.hasNext()) {
+ String version = args.getNext();
+ if (args.hasNext()) {
+ String creator = args.getAll(null);
+ if (creator != null) {
+ AdventureMap map = new AdventureMap(this.plugin, name, version, item, creator, webLink);
+ if (!this.config.addMap(map)) {
+ ChatUtil.sendErrorMessage(sender, "Die map " + name + " existiert bereits!");
+ return true;
+ }
+ category.addMap(map);
+ ChatUtil.sendNormalMessage(sender, "Die map " + name + " wurde erfolgreich hinzugefügt!");
+ return true;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ ChatUtil.sendWarningMessage(p, "/adventure addmap ");
+ return true;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureClearSavesCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureClearSavesCommand.java
new file mode 100644
index 0000000..359263f
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureClearSavesCommand.java
@@ -0,0 +1,78 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.iani.cubesideutils.StringUtil;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.apache.commons.io.FileUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.util.Objects;
+import java.util.logging.Level;
+
+public class AdventureClearSavesCommand extends SubCommand {
+
+ private final Lobby plugin;
+
+ public AdventureClearSavesCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+
+ ChatUtil.sendNormalMessage(p, "Gespeicherte Adventure-Maps die älter als 120 Tage sind werden gelöscht. Dies kann einige Minuten dauern.");
+ plugin.getScheduler().runAsync(() -> {
+ File adventureSaveFolder = plugin.getAdventureSavePath().toFile(); //DELETE OLD AdventureMaps
+ if (adventureSaveFolder.isDirectory()) {
+ File[] playerFolders;
+ playerFolders = adventureSaveFolder.listFiles();
+ if (playerFolders != null) {
+ int deletecounter = 0;
+ long starttime = System.currentTimeMillis();
+ for (File playerFolder : playerFolders) {
+ File[] saveFolders;
+ saveFolders = playerFolder.listFiles();
+ if (saveFolders != null) {
+ try {
+ for (File map : saveFolders) {
+ BasicFileAttributes attr = Files.readAttributes(map.toPath(), BasicFileAttributes.class);
+ FileTime fileTime = attr.creationTime();
+ if (10368000000L + fileTime.toMillis() <= System.currentTimeMillis()) { //120 Tage
+ FileUtils.deleteDirectory(map);
+ deletecounter++;
+ ChatUtil.sendNormalMessage(p, "Welt " + playerFolder.getName() + "/" + map.getName() + " gelöscht. (" + deletecounter + ")");
+ }
+ }
+ if (Objects.requireNonNull(playerFolder.listFiles()).length == 0) {
+ FileUtils.deleteDirectory(playerFolder);
+ }
+ } catch (IOException ex) {
+ Bukkit.getLogger().log(Level.SEVERE, "Fehler beim löschen einer Map", ex);
+ }
+ }
+ }
+ ChatUtil.sendNormalMessage(p, "Es wurden: " + deletecounter + " maps in " + StringUtil.formatTimespan(System.currentTimeMillis() - starttime) + " gelöscht");
+ }
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public String getRequiredPermission() {
+ return "challenges.clearsaves";
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureConvertMapCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureConvertMapCommand.java
new file mode 100644
index 0000000..5fabbc8
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureConvertMapCommand.java
@@ -0,0 +1,266 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import net.md_5.bungee.api.chat.ClickEvent;
+import net.md_5.bungee.api.chat.TextComponent;
+import org.apache.commons.io.FileUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class AdventureConvertMapCommand extends SubCommand {
+ private static FileConfiguration ServerConfig;
+ private static File ServerConfigFile;
+ private static Lobby plugin;
+
+ public AdventureConvertMapCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String s, String s1, ArgsParser args) {
+ String urlString;
+ String versioString;
+
+ if (!(sender instanceof Player player)) {
+ ChatUtil.sendErrorMessage(sender, "You are not a Player");
+ return true;
+ }
+
+ if (!player.hasPermission("adventure.convertmap")) {
+ ChatUtil.sendErrorMessage(player, "Keine Rechte!");
+ return true;
+ }
+
+ if (args.hasNext()) {
+ urlString = args.getNext();
+ if (args.hasNext()) {
+ versioString = args.getNext();
+ } else {
+ ChatUtil.sendErrorMessage(player, "/convertmap ");
+ return true;
+ }
+
+ File folder = new File(Bukkit.getPluginsFolder().getPath() + "/Challenges/MapConverter");
+
+ if (!folder.exists()) {
+ folder.mkdir();
+ }
+
+ String finalUrlString = urlString;
+ String finalVersioString = versioString;
+ plugin.getScheduler().runAsync(() -> downloadMap(finalUrlString, finalVersioString, folder, player));
+ } else {
+ ChatUtil.sendErrorMessage(sender, "/convertmap ");
+ return true;
+ }
+ return true;
+ }
+
+ private static void downloadMap(String finalUrlString, String versioString, File folder, Player player) {
+ Path zipPath = Path.of(folder + "/world.zip");
+ try {
+ InputStream in = new URL(finalUrlString).openStream();
+ Files.copy(in, zipPath, StandardCopyOption.REPLACE_EXISTING);
+ ChatUtil.sendNormalMessage(player, "Map heruntergeladen.");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ unZip(folder, zipPath, versioString, player);
+ }
+
+
+ private static void unZip(File folder, Path zipPath, String versioString, Player player) {
+ File worldFolder = new File(folder.getPath() + "/" + UUID.randomUUID());
+ try {
+ unzipFolder(zipPath, worldFolder.toPath());
+ ChatUtil.sendNormalMessage(player, "UnZip Done " + worldFolder.getName());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ searchRegionFile(worldFolder, versioString, player);
+ }
+
+ private static void searchRegionFile(File file, String versioString, Player player) {
+ File[] files;
+ files = file.listFiles();
+ if (files != null) {
+ for (File filefile : files) {
+ if (filefile.getName().equals("region")) {
+ ChatUtil.sendNormalMessage(player, "region folder found");
+ convertToSpigotMap(filefile.getAbsoluteFile(), versioString, player);
+ return;
+ }
+
+ if (filefile.isDirectory()) {
+ searchRegionFile(filefile, versioString, player);
+ }
+ }
+ }
+ }
+
+ private static void convertToSpigotMap(File file, String versioString, Player player) {
+ if (file != null) {
+ File mapFolder = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - 7));
+ File worldFolder = new File(mapFolder.getAbsoluteFile() + "/world");
+ File netherFolder = new File(mapFolder.getAbsoluteFile() + "/world_nether");
+ File endFolder = new File(mapFolder.getAbsoluteFile() + "/world_the_end");
+
+ try {
+ FileUtils.forceMkdir(worldFolder);
+ FileUtils.forceMkdir(netherFolder);
+ FileUtils.forceMkdir(endFolder);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ File[] files;
+ files = mapFolder.listFiles();
+ if (files != null) {
+ for (File tempFiles : files) {
+ try {
+ if (!tempFiles.getName().equals("DIM1") && !tempFiles.getName().equals("DIM-1") && !tempFiles.getName().equals("world") && !tempFiles.getName().equals("world_nether") && !tempFiles.getName().equals("world_the_end")) {
+ if (tempFiles.isDirectory()) {
+ FileUtils.moveDirectory(tempFiles, new File(worldFolder + "/" + tempFiles.getName()));
+ } else {
+ FileUtils.moveFile(tempFiles, new File(worldFolder + "/" + tempFiles.getName()));
+ }
+ }
+
+ if (tempFiles.getName().equals("DIM1")) {
+ FileUtils.moveDirectory(tempFiles, new File(endFolder + "/" + tempFiles.getName()));
+ }
+
+ if (tempFiles.getName().equals("DIM-1")) {
+ FileUtils.moveDirectory(tempFiles, new File(netherFolder + "/" + tempFiles.getName()));
+ }
+ } catch (IOException e) {
+ plugin.getLogger().log(Level.SEVERE, "Can't Copy File", e);
+ }
+ }
+
+ File challengesFolder = new File(mapFolder.getAbsoluteFile() + "/Challenges");
+
+ try {
+ FileUtils.forceMkdir(challengesFolder);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ createServerConfig(challengesFolder);
+
+
+ try {
+ getServerConfig().set("servertype", "ADVENTURE");
+ ServerConfig.save(ServerConfigFile);
+ getServerConfig().set("serverversion", versioString);
+ ServerConfig.save(ServerConfigFile);
+ } catch (IOException e) {
+ Bukkit.getLogger().log(Level.SEVERE, "Can't Save Config", e);
+ }
+
+ String oldFolderName = mapFolder.getName();
+ String newFolderName = mapFolder.getName().replace(" ", "_");
+ File newFolderFile = new File(mapFolder.getPath().replace(oldFolderName, newFolderName));
+
+ mapFolder.renameTo(newFolderFile);
+
+ ChatUtil.sendNormalMessage(player, "Konvertierung fertig.");
+
+ File destFolder = new File(plugin.getAdventureMapsPath().toFile(), "test/" + newFolderName);
+
+ try {
+ FileUtils.moveDirectory(newFolderFile, destFolder);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ ChatUtil.sendNormalMessage(player, "Map wurde zum testen in das test Verzeichnis verschoben.");
+
+ TextComponent component = new TextComponent(TextComponent.fromLegacyText(Lobby.PREFIX + ChatUtil.GREEN + " Klicke hier um die Map zu testen."));
+ component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/a testmap test " + newFolderName));
+ player.sendMessage(component);
+
+ } else {
+ ChatUtil.sendErrorMessage(player, "Keine datei gefunden.");
+ }
+
+ } else {
+ ChatUtil.sendErrorMessage(player, "Keine datei gefunden.");
+ }
+ }
+
+ public static FileConfiguration getServerConfig() {
+ return ServerConfig;
+ }
+
+ private static void createServerConfig(File folder) {
+ ServerConfigFile = new File(folder.getPath() + "/serverconfig.yml");
+ if (!ServerConfigFile.exists()) {
+ try {
+ FileUtils.forceMkdirParent(ServerConfigFile);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ ServerConfig = new YamlConfiguration();
+ }
+
+ public static void unzipFolder(Path source, Path target) throws IOException {
+ try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source.toFile()))) {
+ ZipEntry zipEntry = zis.getNextEntry();
+
+ while (zipEntry != null) {
+
+ boolean isDirectory = zipEntry.getName().endsWith(File.separator);
+
+ Path newPath = zipSlipProtect(zipEntry, target);
+
+ if (isDirectory) {
+ Files.createDirectories(newPath);
+ } else {
+ if (newPath.getParent() != null) {
+ if (Files.notExists(newPath.getParent())) {
+ Files.createDirectories(newPath.getParent());
+ }
+ }
+ Files.copy(zis, newPath, StandardCopyOption.REPLACE_EXISTING);
+ }
+ zipEntry = zis.getNextEntry();
+ }
+ zis.closeEntry();
+ }
+ }
+
+ public static Path zipSlipProtect(ZipEntry zipEntry, Path targetDir) throws IOException {
+ Path targetDirResolved = targetDir.resolve(zipEntry.getName());
+ Path normalizePath = targetDirResolved.normalize();
+
+ if (!normalizePath.startsWith(targetDir)) {
+ throw new IOException("Bad zip entry: " + zipEntry.getName());
+ }
+
+ return normalizePath;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureLoadCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureLoadCommand.java
new file mode 100644
index 0000000..b9bd278
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureLoadCommand.java
@@ -0,0 +1,45 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.loadgui.AdventureLoadGUI;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import de.iani.playerUUIDCache.CachedPlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class AdventureLoadCommand extends SubCommand {
+ private final Lobby plugin;
+
+ public AdventureLoadCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+
+ CachedPlayer savePlayer;
+ if (args.hasNext()) {
+ if (!p.hasPermission("challenges.load.admin")) {
+ ChatUtil.sendErrorMessage(p, "Keine Rechte! (Du kannst nur eigene maps Laden)");
+ return true;
+ }
+ String savePlayerName = args.getNext();
+ savePlayer = plugin.getPlayerUUIDCache().getPlayer(savePlayerName);
+ } else {
+ savePlayer = plugin.getPlayerUUIDCache().getPlayer(p.getUniqueId());
+ }
+
+ if (savePlayer != null) {
+ new AdventureLoadGUI(p, savePlayer).open();
+ } else {
+ ChatUtil.sendErrorMessage(p, "Spieler nicht gefunden!");
+ }
+ return true;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureLoadMapIconsCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureLoadMapIconsCommand.java
new file mode 100644
index 0000000..5be0cc8
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureLoadMapIconsCommand.java
@@ -0,0 +1,65 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.adventure.AdventureMap;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.ItemStack;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+
+public class AdventureLoadMapIconsCommand extends SubCommand {
+ private final Lobby plugin;
+
+ public AdventureLoadMapIconsCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ //File adventureCategories = new File("/home/storagebox/Adventure-Maps/");
+ File adventureCategories = plugin.getAdventureMapsPath().toFile();
+ File[] categories = adventureCategories.listFiles();
+ if (categories != null) {
+ for (File mapFolder : categories) {
+ ChatUtil.sendNormalMessage(sender, "- " + mapFolder.getName());
+ File[] maps = mapFolder.listFiles();
+ if (maps != null) {
+ for (File map : maps) {
+ ChatUtil.sendDebugMessage(sender, " - " + map.getName());
+ AdventureMap adventureMap = plugin.getAdventureMapsConfig().getMap(map.getName());
+ if (adventureMap != null) {
+ File mapConfig = new File(map, "/Challenges/serverconfig.yml");
+ ItemStack stack = adventureMap.getItem();
+ ChatUtil.sendWarningMessage(sender, " " + adventureMap.getItem().getType());
+ try {
+ YamlConfiguration serverConfig = new YamlConfiguration();
+ serverConfig.load(mapConfig);
+ serverConfig.set("displayItem.item", stack.getType().toString());
+ serverConfig.set("displayItem.name", stack.getItemMeta().getDisplayName());
+ serverConfig.save(mapConfig);
+ } catch (IOException | InvalidConfigurationException ex) {
+ plugin.getLogger().log(Level.SEVERE, "Fehler beim ändern der Config", ex);
+ ChatUtil.sendErrorMessage(sender, " --- Map " + map.getName() + ": Fehler beim ändern der Config! ---");
+ }
+ } else {
+ ChatUtil.sendErrorMessage(sender, "Map " + map.getName() + " nicht gefunden!");
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getRequiredPermission() {
+ return "challenge.command.loadmapicons";
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureMapsCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureMapsCommand.java
new file mode 100644
index 0000000..adf0650
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureMapsCommand.java
@@ -0,0 +1,27 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.adventure.ui.CategoryUI;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class AdventureMapsCommand extends SubCommand {
+ private final Lobby plugin;
+
+ public AdventureMapsCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+ (new CategoryUI(this.plugin, this.plugin.getCategoriesConfig(), p)).open();
+ return true;
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureStartEventServerCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureStartEventServerCommand.java
new file mode 100644
index 0000000..8424301
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureStartEventServerCommand.java
@@ -0,0 +1,33 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public class AdventureStartEventServerCommand extends SubCommand {
+ private final Lobby plugin;
+
+ public AdventureStartEventServerCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+
+ plugin.getEventServerPlayerList().add(p.getUniqueId());
+ ChatUtil.sendNormalMessage(p, "Der nächste Adventure Server, denn du startest, wird als Event Server gestartet und hat somit mehr Leistung.");
+ return true;
+ }
+
+ @Override
+ public String getRequiredPermission() {
+ return "challenges.event";
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureTempCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureTempCommand.java
new file mode 100644
index 0000000..c97bd0d
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureTempCommand.java
@@ -0,0 +1,111 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import de.tr7zw.nbtapi.NBTCompound;
+import de.tr7zw.nbtapi.NBTFile;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+
+import java.io.File;
+import java.io.IOException;
+
+public class AdventureTempCommand extends SubCommand {
+ private final Lobby plugin;
+
+ public AdventureTempCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ /*public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ FileConfiguration config = AdventureMapsConfig.getConfig();
+ FileConfiguration catConfig = CategoriesConfig.getConfig();
+
+ //File adventureCategories = new File("/home/storagebox/Adventure-Maps/");
+ File adventureCategories = plugin.getAdventureMapsPath().toFile();
+ File[] categories = adventureCategories.listFiles();
+ if (categories != null) {
+ for (File mapFolder : categories) {
+ ChatUtil.sendNormalMessage(sender, "- " + mapFolder.getName());
+ File[] maps = mapFolder.listFiles();
+ if (maps != null) {
+ for (File map : maps) {
+ if (config.getKeys(false).contains(map.getName())) {
+ try {
+ File mapConfig = new File(map, "/Challenges/serverconfig.yml");
+ YamlConfiguration serverConfig = new YamlConfiguration();
+ serverConfig.load(mapConfig);
+ config.set(map.getName() + "." + "version", serverConfig.get("serverversion"));
+ config.save(AdventureMapsConfig.getFile());
+
+ List catList = catConfig.getStringList(mapFolder.getName() + "." + "maps");
+ if (!catList.contains(map.getName())) {
+ catList.add(map.getName());
+ catConfig.set(mapFolder.getName() + "." + "maps", catList);
+ catConfig.save(CategoriesConfig.getFile());
+ }
+
+ } catch (IOException | InvalidConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }*/
+
+
+
+
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+
+ File adventureSaves = plugin.getChallengeSavePath().toFile();
+ Bukkit.getLogger().info(adventureSaves.getAbsolutePath());
+ File[] players = adventureSaves.listFiles();
+ if (players != null) {
+ Bukkit.getLogger().info("Players");
+ for (File player : players) {
+ ChatUtil.sendNormalMessage(sender, "- " + player.getName());
+
+ File[] maps = player.listFiles();
+ if (maps != null) {
+ for (File map : maps) {
+ ChatUtil.sendDebugMessage(sender, " - " + map.getName());
+ try {
+ NBTFile file = new NBTFile(new File(map, "/world/level.dat"));
+ NBTCompound data = file.getCompound("Data");
+ NBTCompound dataPacks = data.getCompound("DataPacks");
+
+ dataPacks.getStringList("Enabled").add("update_1_21");
+ dataPacks.getStringList("Disabled").add("bundle");
+ dataPacks.getStringList("Disabled").add("trade_rebalance");
+
+ data.getStringList("enabled_features").add("minecraft:update_1_21");
+ data.getStringList("enabled_features").add("minecraft:vanilla");
+
+
+ file.save();
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getRequiredPermission() {
+ return "challenge.command.temp";
+ }
+}
diff --git a/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureTestMapCommand.java b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureTestMapCommand.java
new file mode 100644
index 0000000..9cb8114
--- /dev/null
+++ b/Lobby/src/main/java/de/fanta/lobby/commands/AdventureCommand/AdventureTestMapCommand.java
@@ -0,0 +1,112 @@
+package de.fanta.lobby.commands.AdventureCommand;
+
+import de.fanta.lobby.Lobby;
+import de.fanta.lobby.ChatUtil;
+import de.fanta.lobby.Server;
+import de.iani.cubesideutils.bukkit.commands.SubCommand;
+import de.iani.cubesideutils.commands.ArgsParser;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+public class AdventureTestMapCommand extends SubCommand {
+ private final Lobby plugin;
+
+ public AdventureTestMapCommand(Lobby plugin) {
+ this.plugin = plugin;
+ }
+
+ public boolean onCommand(CommandSender sender, Command command, String alias, String commandString, ArgsParser args) {
+ if (!(sender instanceof Player p)) {
+ ChatUtil.sendErrorMessage(sender, "Du musst ein Spieler sein!");
+ return true;
+ }
+ if (sender.hasPermission("challenges.starttestmap")) {
+ if (args.hasNext()) {
+ String category = args.getNext();
+ if (args.hasNext()) {
+ String map = args.getNext();
+ if (args.hasNext()) {
+ String version = args.getNext();
+ if (!Server.serverPlayers.containsValue(p.getUniqueId())) {
+ this.plugin.getPluginConfig().getOnlineAdventureServer().ifPresentOrElse(server -> server.loadNewAdventure(p, category, map, version), () -> ChatUtil.sendErrorMessage(p, "Aktuell ist kein Server Frei!"));
+ } else {
+ ChatUtil.sendErrorMessage(p, "Du kannst nur einen Server starten!");
+ }
+ } else {
+ ChatUtil.sendWarningMessage(p, "/adventure testmap