Newer
Older
ChallengeSystem / Lobby / src / main / java / de / fanta / lobby / Lobby.java
@fanta fanta on 20 Jun 2024 19 KB components :,)
package de.fanta.lobby;

import de.cubeside.nmsutils.NMSUtils;
import de.fanta.challengeutils.Color;
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.InfoPiglinCommand;
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.utils.ComponentUtil;
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 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.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 class Lobby extends JavaPlugin {

    private TextComponent prefixComponent;
    private Component ADVENTUREGUIPREFIX;
    private Component CHALLENGEGUIPREFIX;

    private static Lobby plugin;
    private final Map<String, JoinEntityData> entityData;
    private final Map<UUID, String> entityServerMapping;
    private final Set<String> 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<UUID> eventServerPlayerList;

    private Path challengeSavePath;
    private Path adventureSavePath;
    private Path aventureMapsPath;
    private Path serverJarsPath;
    private Path serverFolderPath;

    private ComponentUtil componentUtil;


    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 onLoad() {
        plugin = this;
        File oldPluginFolder = new File("plugins/ChallengesJoinEntities");
        if (oldPluginFolder.isDirectory()) {
            if (!oldPluginFolder.renameTo(new File("plugins/Lobby"))) {
                getLogger().severe("ChallengesJoinEntities Ordner konnte nicht in Lobby umgenannt werden!");
                plugin.getServer().shutdown();
            }
        }
    }

    @Override
    public void onEnable() {
        this.componentUtil = new ComponentUtil();
        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);
        }

        prefixComponent = Component.text("[").color(Color.BLUE).append(Component.text("Lobby").color(Color.GREEN)).append(Component.text("] ").color(Color.BLUE));
        ADVENTUREGUIPREFIX = Component.text("Adventure", Color.GREEN);
        CHALLENGEGUIPREFIX = Component.text("Challenge", Color.GREEN);

        this.globalDataHelper = new ChallengesGlobalDataHelper(this);
        this.config = new Config(this);
        loadCategoriesAndMaps();

        if (Bukkit.getPluginManager().getPlugin("Challenge") != 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 InfoPiglinCommand(this), "info");
            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(this, 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() {
        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;
        }
        Component customName = data.createCustomEntityName();
        entity.customName(customName);
    }

    public void updatePiglinBehaviour(String serverName) {
        getLogger().info("Update Server: " + 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<String, JoinEntityData> getEntityData() {
        return entityData;
    }

    public Set<String> getAvailableServers() {
        return availableServers;
    }

    public CubesideStatisticsAPI getCubesideStatistics() {
        return cubesideStatistics;
    }

    public Statistics getStatistics() {
        return statistics;
    }

    /*public SignManager getSignManager() {
        return signManager;
    }*/

    public List<UUID> getEventServerPlayerList() {
        return eventServerPlayerList;
    }

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

    public TextComponent getPrefixComponent() {
        return prefixComponent;
    }

    public Component getADVENTUREGUIPREFIX() {
        return ADVENTUREGUIPREFIX;
    }

    public Component getCHALLENGEGUIPREFIX() {
        return CHALLENGEGUIPREFIX;
    }

    public ComponentUtil getComponentUtil() {
        return componentUtil;
    }
}