package de.fanta.challenges;
import com.destroystokyo.paper.profile.PlayerProfile;
import de.cubeside.nmsutils.NMSUtils;
import de.fanta.challenges.challenges.AllItemsChallenge;
import de.fanta.challenges.challenges.MLGChallenge;
import de.fanta.challenges.challenges.RandomDropsChallenge;
import de.fanta.challenges.commands.CommandRegistration;
import de.fanta.challenges.events.ChallengeEventStatusChangedEvent;
import de.fanta.challenges.events.EventStatusChangedEvent;
import de.fanta.challenges.events.PlayerCountChangedEvent;
import de.fanta.challenges.events.ServerStatusChangedEvent;
import de.fanta.challenges.events.TimerChangedEvent;
import de.fanta.challenges.guis.BackpackGui;
import de.fanta.challenges.listeners.EventRegistration;
import de.fanta.challenges.schedular.BukkitScheduler;
import de.fanta.challenges.schedular.CancellableTask;
import de.fanta.challenges.schedular.Scheduler;
import de.fanta.challenges.scoreboard.BukkitScoreBoardManager;
import de.fanta.challenges.scoreboard.ScoreBoardMananger;
import de.fanta.challenges.scoreboard.ScoreManager;
import de.fanta.challenges.utils.ChatUtil;
import de.fanta.challenges.utils.ColorUtils;
import de.fanta.challenges.utils.Config;
import de.fanta.challenges.utils.Statistics;
import de.fanta.challenges.utils.VanishUtils;
import de.fanta.challenges.waypoints.WaypointManager;
import de.iani.cubesidestats.api.CubesideStatisticsAPI;
import de.iani.playerUUIDCache.PlayerUUIDCache;
import de.speedy64.globalport.GlobalApi;
import io.papermc.paper.ban.BanListType;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import org.apache.commons.io.FileUtils;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.Difficulty;
import org.bukkit.GameRule;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.advancement.Advancement;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class Challenges extends JavaPlugin {
public static Logger LOGGER;
private static Challenges plugin;
public File RndDropsConfigFile;
public FileConfiguration RndDropsConfig;
public FileConfiguration AllItemsConfig;
public FileConfiguration ServerConfig;
public RandomDropsChallenge rndDrops;
public NMSUtils nmsUtils;
public PlayerUUIDCache playerUUIDCache;
public String texturepacklink = null;
public CancellableTask resetTask;
public boolean reset = false;
private TextComponent prefixComponent;
private TextComponent guiPrefix;
private File backpackConfigFile;
private FileConfiguration BackpackConfig;
private File AllItemsConfigFile;
private Timer timer;
private VanishUtils vanish;
private BackpackGui backpack;
private ScoreBoardMananger sbManager;
private ScoreManager scoreManager;
private Player currentEditor;
private OfflinePlayer firstEditor;
private boolean waitingForShutdown;
private ServerType serverType;
public FileConfiguration ItemConfig;
public File ItemConfigFile;
private static final ArrayList<Material> not_available_materials = new ArrayList<>();
private static final ArrayList<Material> materials = new ArrayList<>();
private static final ArrayList<Advancement> advancements = new ArrayList<>();
private CubesideStatisticsAPI cubesideStatistics;
private Statistics statistics;
private static final ArrayList<UUID> statisticPlayers = new ArrayList<>();
private static final ArrayList<UUID> bannedPlayers = new ArrayList<>();
public boolean resetwithseed;
private static final String CubesideMod_ModChannel = "cubesidemod:data";
private Scheduler scheduler;
private ColorUtils colorUtils;
private final Path challengeSavePath = new File("/home/storagebox/Challenge-saves").toPath();
private final Path adventureSavePath = new File("/home/storagebox/Adventure-saves/").toPath();
private WaypointManager waypointMananger;
public static Challenges getPlugin() {
return plugin;
}
@Override
public void onEnable() {
LOGGER = getLogger();
plugin = this;
nmsUtils = getServer().getServicesManager().load(NMSUtils.class);
playerUUIDCache = (PlayerUUIDCache) Bukkit.getPluginManager().getPlugin("PlayerUUIDCache");
try {
cubesideStatistics = getServer().getServicesManager().load(CubesideStatisticsAPI.class);
} catch (NoClassDefFoundError ex) {
cubesideStatistics = null;
}
if (isCubesideStatisticsInstalled()) {
statistics = new Statistics(this);
}
getLogger().log(Level.INFO, "Bukkit found. Use Bukkit Scheduler");
scheduler = new BukkitScheduler(this);
colorUtils = new ColorUtils(this);
this.timer = new Timer(this);
this.rndDrops = new RandomDropsChallenge();
this.scoreManager = new ScoreManager(this);
this.vanish = new VanishUtils(this);
saveDefaultConfig();
reloadConfig();
createServerConfig();
createItemConfig();
serverType = ServerType.valueOf(getServerConfig().getString("servertype"));
String prefix = serverType.getPrefix();
prefixComponent = Component.text("[").color(ChatUtil.BLUE).append(Component.text(prefix).color(ChatUtil.GREEN)).append(Component.text("] ").color(ChatUtil.BLUE));
guiPrefix = Component.text(prefix).color(ChatUtil.GREEN);
createRndDropsConfig();
createAllItemsConfig();
createBackpackConfig();
this.backpack = new BackpackGui(Config.getInt("backpack_size") * 9);
new CommandRegistration(this).registerCommands();
new EventRegistration(this).registerEvents();
this.backpack.loadInventoryFromConfig();
this.sbManager = new BukkitScoreBoardManager(this);
getScheduler().runGlobalDelayed(() -> {
plugin.setDayLightCircle(false);
MLGChallenge.checkMLGWorld();
setPvP(Config.getBoolean("pvp"));
if (plugin.getServerType() != ServerType.ADVENTURE) {
plugin.getSBManager().initScoreboard();
}
}, 1L);
resetwithseed = Config.getBoolean("resetwithseed");
if (Config.getBoolean("World_Reset") && (serverType == ServerType.CHALLENGE || serverType == ServerType.CHALLENGE_EVENT)) {
if (!Config.getBoolean("firsttimerstart")) {
timer.setTime(0);
}
File config = new File(plugin.getDataFolder(), "config.yml");
config.delete();
reloadConfig();
saveConfig();
this.backpack.clearConfig();
this.rndDrops.shuffleItems();
this.rndDrops.saveItems();
this.rndDrops.loadItems();
} else {
this.getBackpack().resize(Config.getInt("backpack_size") * 9);
this.rndDrops.loadItems();
this.backpack.loadInventoryFromConfig();
timer.setTime(getConfig().getInt("timertime"));
}
waypointMananger = new WaypointManager(this);
if (plugin.getServerType() == ServerType.ADVENTURE) {
File texturepack = new File("world/resources.zip");
if (texturepack.exists()) {
File mapConfigFile = new File("plugins/Challenges/serverconfig.yml");
YamlConfiguration mapConfig = YamlConfiguration.loadConfiguration(mapConfigFile);
String texturepackname = mapConfig.getString("displayItem.name");
String textureID = texturepackname != null ? texturepackname.replace("ยง", "").replace(" ", "_") : UUID.randomUUID().toString();
File texturepackdownload = new File("/home/web/fanta/AdventureMap-TexturePacks/" + textureID + "/");
File temp = new File(textureID);
try {
if (!texturepackdownload.isDirectory()) {
FileUtils.forceMkdir(temp);
FileUtils.copyFileToDirectory(texturepack, temp, false);
File renameTP = new File(textureID + "/" + "resources.zip");
File renamedTP = new File(textureID + "/" + textureID + ".zip");
renameTP.renameTo(renamedTP);
if (temp.isDirectory()) {
FileUtils.moveDirectory(temp, texturepackdownload);
} else {
Challenges.getPlugin().getLogger().info("Ordner nicht da!");
}
}
texturepacklink = "https://fantacs.de/AdventureMap-TexturePacks/" + textureID + "/" + textureID + ".zip";
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Error while move directory", e);
}
}
getConfig().set("showtimer", false);
} else {
getConfig().set("showtimer", true);
}
for (String string : getItemConfig().getStringList("items")) {
try {
Material material = Material.valueOf(string);
not_available_materials.add(material);
} catch (IllegalArgumentException ex) {
Challenges.getPlugin().getLogger().log(Level.INFO, "Some items could not be loaded into the ItemGroup");
}
}
for (Material material : Material.values()) {
if (material.isItem() && !material.isAir()) {
materials.add(material);
}
}
if (getConfig().getBoolean("allitems")) {
AllItemsChallenge.start();
}
if (serverType != ServerType.ADVENTURE) {
for (@NotNull Iterator<Advancement> it = Bukkit.advancementIterator(); it.hasNext(); ) {
Advancement advancement = it.next();
if (advancement.getDisplay() != null) {
advancements.add(advancement);
}
}
}
if (getServerType() == ServerType.CHALLENGE) {
if (resetwithseed) {
Config.setValue("editsettings", true);
}
} else {
Config.setValue("editsettings", true);
}
for (String UUIDString : Config.getStringList("bannedPlayers")) {
addBannedPlayer(UUID.fromString(UUIDString), false);
}
if (plugin.getServerType() == ServerType.ADVENTURE || plugin.getServerType() == ServerType.CHALLENGE_LOAD) {
startResetTask();
}
getServer().getMessenger().registerOutgoingPluginChannel(this, CubesideMod_ModChannel);
plugin.getScheduler().runGlobalDelayed(() -> {
EventRegistration.pM.callEvent(new ServerStatusChangedEvent(true));
EventRegistration.pM.callEvent(new TimerChangedEvent(timer.isRunning()));
EventRegistration.pM.callEvent(new PlayerCountChangedEvent(Bukkit.getOnlinePlayers().size() - plugin.getVanish().countVanishPlayers()));
}, 200L);
getLogger().info("Plugin loaded!");
}
@Override
public void onDisable() {
BanList<PlayerProfile> banList = Bukkit.getBanList(BanListType.PROFILE);
banList.getEntries().forEach(banEntry -> banList.pardon((PlayerProfile) banEntry));
if (!getConfig().getBoolean("World_Reset")) {
this.backpack.saveInventoryToConfig();
Config.setValue("backpack_size", backpack.getSize() / 9);
} else if (serverType == ServerType.CHALLENGE || serverType == ServerType.CHALLENGE_EVENT) {
this.backpack.clearConfig();
}
try {
this.RndDropsConfig.save(this.RndDropsConfigFile);
this.AllItemsConfig.save(this.getAllItemsConfigFile());
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Error while saving configs", e);
}
Config.setValue("timertime", timer.getTime());
if (getConfig().getBoolean("event.enabled")) {
Config.setValue("event.enabled", false);
Bukkit.getPluginManager().callEvent(new EventStatusChangedEvent(false));
Bukkit.getPluginManager().callEvent(new ChallengeEventStatusChangedEvent(false));
getScoreManager().saveScores(null);
}
saveConfig();
getLogger().info("Plugin unloaded");
}
public RandomDropsChallenge getRandomDropsManager() {
return this.rndDrops;
}
public FileConfiguration getBackpackConfig() {
return this.BackpackConfig;
}
private void createBackpackConfig() {
this.backpackConfigFile = new File(getDataFolder(), "backpack.yml");
if (!this.backpackConfigFile.exists()) {
this.backpackConfigFile.getParentFile().mkdirs();
saveResource("backpack.yml", false);
}
this.BackpackConfig = new YamlConfiguration();
try {
this.BackpackConfig.load(this.backpackConfigFile);
} catch (InvalidConfigurationException | IOException e) {
plugin.getLogger().log(Level.SEVERE, "Error while loading Backpack", e);
}
}
public FileConfiguration getRndDropsConfig() {
return this.RndDropsConfig;
}
private void createRndDropsConfig() {
this.RndDropsConfigFile = new File(getDataFolder(), "rnddrops.yml");
if (!this.RndDropsConfigFile.exists()) {
this.RndDropsConfigFile.getParentFile().mkdirs();
saveResource("rnddrops.yml", false);
}
this.RndDropsConfig = new YamlConfiguration();
try {
this.RndDropsConfig.load(this.RndDropsConfigFile);
} catch (IOException | org.bukkit.configuration.InvalidConfigurationException e) {
plugin.getLogger().log(Level.SEVERE, "Error while load RandomDrops Config", e);
}
}
public FileConfiguration getAllItemsConfig() {
return this.AllItemsConfig;
}
private void createAllItemsConfig() {
this.AllItemsConfigFile = new File(getDataFolder(), "allitems.yml");
if (!AllItemsConfigFile.exists() || ((serverType == ServerType.CHALLENGE || serverType == ServerType.CHALLENGE_EVENT) && Config.getBoolean("World_Reset"))) {
this.getAllItemsConfigFile().getParentFile().mkdirs();
saveResource("allitems.yml", true);
}
this.AllItemsConfig = new YamlConfiguration();
try {
this.AllItemsConfig.load(this.AllItemsConfigFile);
} catch (IOException | org.bukkit.configuration.InvalidConfigurationException e) {
plugin.getLogger().log(Level.SEVERE, "Error while loading AllItems Config", e);
}
}
public FileConfiguration getServerConfig() {
return ServerConfig;
}
private void createServerConfig() {
File serverConfigFile = new File(getDataFolder(), "serverconfig.yml");
if (!serverConfigFile.exists()) {
serverConfigFile.getParentFile().mkdirs();
saveResource("serverconfig.yml", false);
}
this.ServerConfig = new YamlConfiguration();
try {
ServerConfig.load(serverConfigFile);
} catch (IOException | InvalidConfigurationException e) {
plugin.getLogger().log(Level.SEVERE, "Error while loading Server Config", e);
}
}
public FileConfiguration getItemConfig() {
return ItemConfig;
}
private void createItemConfig() {
ItemConfigFile = new File(getDataFolder(), "items.yml");
ItemConfigFile.getParentFile().mkdirs();
saveResource("items.yml", true);
this.ItemConfig = new YamlConfiguration();
try {
ItemConfig.load(ItemConfigFile);
} catch (IOException | InvalidConfigurationException e) {
plugin.getLogger().log(Level.SEVERE, "Error while loading Item Config", e);
}
}
public ScoreBoardMananger getSBManager() {
return this.sbManager;
}
public Player getCurrentEditor() {
return currentEditor;
}
public void setCurrentEditor(Player currentEditor) {
this.currentEditor = currentEditor;
plugin.setFirstEditor(currentEditor);
if (currentEditor != null) {
ChatUtil.sendNormalMessage(currentEditor, "Du bist nun der Editor dieser Lobby!");
ChatUtil.sendNormalMessage(currentEditor, "Alle Befehle und Funktionen vom Challenge Plugin findest du in unserem Wiki.");
ChatUtil.sendNormalMessage(currentEditor, "Hier Klicken --> https://wiki.cubeside.de/Challenge");
ChatUtil.sendBrodCastMessage(Component.text(currentEditor.getName(), ChatUtil.BLUE).append(Component.text(" ist nun der Editor dieser Lobby!", ChatUtil.GREEN)));
}
}
public OfflinePlayer getFirstEditor() {
return firstEditor;
}
public void setFirstEditor(Player firstEditor) {
if (this.firstEditor == null) {
this.firstEditor = firstEditor;
}
}
public void updateEditor() {
Random random = new Random();
Player randomPlayer = null;
Player oldEditor = plugin.getCurrentEditor();
List<Player> onlinePlayersWithPermission = Bukkit.getOnlinePlayers().stream().filter(p -> p.hasPermission("Challenges.editor")).distinct().collect(Collectors.toList());
onlinePlayersWithPermission.remove(oldEditor);
if (!onlinePlayersWithPermission.isEmpty()) {
int rnd = random.nextInt(onlinePlayersWithPermission.size());
randomPlayer = onlinePlayersWithPermission.get(rnd);
} else {
ArrayList<String> onlinePlayers = Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toCollection(ArrayList::new));
List<String> vanishPlayers = plugin.getVanish().getVanishPlayerList();
onlinePlayers.removeAll(vanishPlayers);
onlinePlayers.remove(oldEditor.getName());
if (!onlinePlayers.isEmpty()) {
int rnd = random.nextInt(onlinePlayers.size());
randomPlayer = Bukkit.getPlayer(onlinePlayers.get(rnd));
}
}
plugin.setCurrentEditor(randomPlayer);
}
public boolean hasEditor() {
return currentEditor != null;
}
public boolean isEditor(Player player) {
return hasEditor() && currentEditor.getUniqueId().equals(player.getUniqueId());
}
public void startResetTask() {
getLogger().info("Start Reset Task");
resetTask = plugin.getScheduler().runGlobalDelayed(() -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "reset confirm"), 3 * 60 * 20);
reset = true;
}
public void stopResetTask() {
getLogger().info("Stop Reset Task");
resetTask.cancel();
resetTask = null;
reset = false;
}
public void setPvP(Boolean value) {
for (World w : plugin.getServer().getWorlds()) {
if (w != null) {
w.setPVP(value);
}
}
}
public boolean getPvP() {
return Bukkit.getWorld("world").getPVP();
}
public void setDifficulty(Difficulty difficulty) {
for (World w : plugin.getServer().getWorlds()) {
if (w != null) {
w.setDifficulty(difficulty);
}
}
}
public Difficulty getDifficulty() {
return Bukkit.getWorld("world").getDifficulty();
}
public void setKeepInventory(Boolean value) {
for (World w : plugin.getServer().getWorlds()) {
if (w != null) {
getScheduler().run(() -> w.setGameRule(GameRule.KEEP_INVENTORY, value));
}
}
}
public boolean getKeepInventory() {
return Bukkit.getWorld("world").getGameRuleValue(GameRule.KEEP_INVENTORY);
}
public void setNaturalRegeneration(Boolean value) {
for (World w : plugin.getServer().getWorlds()) {
if (w != null) {
getScheduler().run(() -> w.setGameRule(GameRule.NATURAL_REGENERATION, value));
}
}
}
public boolean getNaturalRegeneration() {
return Bukkit.getWorld("world").getGameRuleValue(GameRule.NATURAL_REGENERATION);
}
public void setDayLightCircle(boolean value) {
for (World world : Bukkit.getWorlds()) {
if (world.getEnvironment() == World.Environment.NORMAL && plugin.getServerType() != ServerType.ADVENTURE) {
getScheduler().run(() -> world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, value));
}
}
}
public void portPlayerToLobby(Player player) {
if (plugin.getServerType() == ServerType.CHALLENGE || plugin.getServerType() == ServerType.CHALLENGE_LOAD) {
GlobalApi.portOnlinePlayerToLocation(player.getName(), "challenge");
} else if (plugin.getServerType() == ServerType.ADVENTURE) {
GlobalApi.portOnlinePlayerToLocation(player.getName(), "adventure");
} else if (plugin.getServerType() == ServerType.CHALLENGE_EVENT) {
GlobalApi.portOnlinePlayerToLocation(player.getName(), "challenge_event");
}
}
public Timer getTimer() {
return timer;
}
public VanishUtils getVanish() {
return vanish;
}
public boolean isWaitingForShutdown() {
return waitingForShutdown;
}
public void setWaitingForShutdown(boolean waitingForShutdown) {
this.waitingForShutdown = waitingForShutdown;
}
public BackpackGui getBackpack() {
return backpack;
}
public File getBackpackConfigFile() {
return backpackConfigFile;
}
public ScoreManager getScoreManager() {
return scoreManager;
}
public NMSUtils getNMSUtils() {
return nmsUtils;
}
public File getAllItemsConfigFile() {
return AllItemsConfigFile;
}
public ServerType getServerType() {
return serverType;
}
public TextComponent getPrefixComponent() {
return prefixComponent;
}
public TextComponent getGuiPrefix() {
return guiPrefix;
}
public ArrayList<Material> getNotAvailableMaterials() {
return not_available_materials;
}
public ArrayList<Material> getMaterials() {
return materials;
}
public ArrayList<Advancement> getAdvancements() {
return advancements;
}
public CubesideStatisticsAPI getCubesideStatistics() {
return cubesideStatistics;
}
public boolean isCubesideStatisticsInstalled() {
return cubesideStatistics != null;
}
public Statistics getStatistics() {
return statistics;
}
public PlayerUUIDCache getPlayerUUIDCache() {
return playerUUIDCache;
}
public void addstatisticPlayers(UUID uuid) {
statisticPlayers.add(uuid);
}
public ArrayList<UUID> getstatisticPlayers() {
return statisticPlayers;
}
public void addBannedPlayer(UUID uuid, boolean isPermaBan) {
bannedPlayers.add(uuid);
if (isPermaBan) {
List<String> bannedPlayer = Config.getStringList("bannedPlayers");
bannedPlayer.add(uuid.toString());
Config.setValue("bannedPlayers", bannedPlayer, false);
}
}
public void removeBannedPlayer(UUID uuid, Boolean removeConfig) {
bannedPlayers.remove(uuid);
if (removeConfig) {
List<String> bannedPlayer = Config.getStringList("bannedPlayers");
bannedPlayer.remove(uuid.toString());
Config.setValue("bannedPlayers", bannedPlayer, false);
}
}
public boolean isPlayerBanned(UUID uuid) {
return bannedPlayers.contains(uuid);
}
public String getCubesideMod_ModChannel() {
return CubesideMod_ModChannel;
}
public Scheduler getScheduler() {
return scheduler;
}
public ColorUtils getColorUtils() {
return colorUtils;
}
public Path getAdventureSavePath() {
return adventureSavePath;
}
public Path getChallengeSavePath() {
return challengeSavePath;
}
}