package com.lifeknight.relaymchub; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.lifeknight.relaymchub.commands.*; import com.lifeknight.relaymchub.commands.map.SetSpawnCommand; import com.lifeknight.relaymchub.commands.map.ShareMapCommand; import com.lifeknight.relaymchub.commands.menu.*; import com.lifeknight.relaymchub.commands.movement.FlyCommand; import com.lifeknight.relaymchub.commands.movement.LeaveCommand; import com.lifeknight.relaymchub.commands.movement.SpawnCommand; import com.lifeknight.relaymchub.commands.movement.TeleportCommand; import com.lifeknight.relaymchub.commands.queue.DuelCommand; import com.lifeknight.relaymchub.commands.queue.RematchCommand; import com.lifeknight.relaymchub.miscellaneous.GameKit; import com.lifeknight.relaymchub.miscellaneous.MessageProcessor; import com.lifeknight.relaymchub.miscellaneous.SmartGUIUtils; import com.lifeknight.relaymchub.player.HubPlayer; import com.lifeknight.relaymchub.statistics.StatisticsLeaderboard; import com.lifeknight.relaymcutils.RelayMCUtils; import com.lifeknight.relaymcutils.event.NotEnoughMemoryEvent; import com.lifeknight.relaymcutils.network.MessageClient; import com.lifeknight.relaymcutils.player.CustomDuelsKit; import com.lifeknight.relaymcutils.player.CustomMap; import com.lifeknight.relaymcutils.player.DuelMap; import com.lifeknight.relaymcutils.player.SmartPlayer; import com.lifeknight.relaymcutils.player.commands.ParkourCommand; import com.lifeknight.relaymcutils.player.commands.ProfileCommand; import com.lifeknight.relaymcutils.player.commands.StatisticsCommand; import com.lifeknight.relaymcutils.utilities.Configuration; import com.lifeknight.relaymcutils.utilities.Parkour; import com.lifeknight.relaymcutils.utilities.SmartNPC; import com.lifeknight.relayutils.RelayUtils; import com.lifeknight.relayutils.basic.Miscellaneous; import com.lifeknight.relayutils.basic.Text; import com.lifeknight.relayutils.data.QueueData; import com.lifeknight.relayutils.game.GameAction; import com.lifeknight.relayutils.game.GameType; import com.lifeknight.relayutils.game.MainGame; import com.lifeknight.relayutils.game.SpecificGameAction; import com.lifeknight.relayutils.player.data.SmartDatabase; import com.lifeknight.relayutils.utilities.ComponentBuilder; import org.bukkit.*; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.ArmorStand; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.potion.PotionEffectType; import java.io.File; import java.io.IOException; import java.sql.ResultSet; import java.util.*; import java.util.concurrent.TimeUnit; public final class Main extends JavaPlugin implements Listener { public static Configuration configuration; public static String hubType = "main"; public static MainGame mainGame; public static String PLUGIN_ID = "relaymchub"; public static Main instance; public static boolean pvpArenaEnabled; private static boolean leaderboardsAreaEnabled; private static Location leaderboardsArea; public static int ticks = 0; public static boolean isAboutToRestart = false; public static Location arenaPosA; public static Location arenaPosB; public static float yaw = 0F; public static float leaderboardYaw = 0F; public static boolean isLimbo() { return Text.comparablyEquals(hubType, "limbo"); } public static final List CUSTOM_MAP_TEMPLATES = new ArrayList<>(); public static CustomMap getWallTemplate() { return Miscellaneous.match(CUSTOM_MAP_TEMPLATES, customMap -> customMap.getId().equalsIgnoreCase("walledtemplate")); } public static boolean hasWallTemplate() { return getWallTemplate() != null; } public static boolean isMainLobby() { return mainGame == null; } private static final List RECENT_MAPS = new ArrayList<>(); private static final List> POPULAR_MAPS = Miscellaneous.getList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); public static List getCustomMaps(boolean recent, int timeFrame) { return recent ? RECENT_MAPS : POPULAR_MAPS.get(timeFrame); } private static final List RECENT_KITS = new ArrayList<>(); private static final List> POPULAR_KITS = Miscellaneous.getList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); public static List getCustomKits(boolean recent, int timeFrame) { return recent ? RECENT_KITS : POPULAR_KITS.get(timeFrame); } public static List getMaps(GameType gameType) { if (gameType == GameType.DUELS_CRYSTAL) { return Miscellaneous.getList(DuelMap.INSANE_TERRAIN, DuelMap.CRAZY_TERRAIN, DuelMap.EPIC_TERRAIN, DuelMap.NATURAL_PLAINS, DuelMap.NATURAL_DESERT, DuelMap.NATURAL_BEDROCK, DuelMap.ARENA); } if (gameType == GameType.DUELS_AXE) { return Miscellaneous.getList(DuelMap.CASUAL_COURTYARD, DuelMap.ARENA, DuelMap.PERILOUS_PRISON, DuelMap.BLUE_KINGDOM, DuelMap.RED_PANDA, DuelMap.MUSHROOM_FOREST, DuelMap.KUNG_FOO_FORTRESS, DuelMap.COMBAT_CITY); } if (gameType == GameType.DUELS_SWORD) { return Miscellaneous.getList(DuelMap.COMBAT_CITY, DuelMap.PERILOUS_PRISON, DuelMap.CASUAL_COURTYARD, DuelMap.ARENA, DuelMap.INSANE_TERRAIN, DuelMap.CRAZY_TERRAIN, DuelMap.KUNG_FOO_FORTRESS); } if (gameType == GameType.DUELS_UHC) { return Miscellaneous.getList(DuelMap.NATURAL_PLAINS, DuelMap.NATURAL_DESERT, DuelMap.CRAZY_TERRAIN, DuelMap.INSANE_TERRAIN, DuelMap.EPIC_TERRAIN, DuelMap.MUSHROOM_FOREST, DuelMap.RED_PANDA, DuelMap.BLUE_KINGDOM, DuelMap.ARENA, DuelMap.CASUAL_COURTYARD); } if (gameType == GameType.DUELS_DIAMOND_POT || gameType == GameType.DUELS_NETHERITE_POT) { return Miscellaneous.getList(DuelMap.PERILOUS_PRISON, DuelMap.CASUAL_COURTYARD, DuelMap.COMBAT_CITY, DuelMap.ARENA, DuelMap.KUNG_FOO_FORTRESS, DuelMap.INSANE_TERRAIN, DuelMap.CRAZY_TERRAIN); } return new ArrayList<>(); } public static void schedule(Runnable runnable, double delay) { RelayMCUtils.schedule(runnable, delay); } @Override public void onEnable() { World overworld = getWorld(); instance = this; overworld.setAutoSave(false); this.readConfig(); if (hubType == null) { hubType = ""; } mainGame = MainGame.getMainGame(hubType); RelayMCUtils.set(this, Text.toComparable(hubType)); PluginManager pluginManager = this.getServer().getPluginManager(); pluginManager.registerEvents(new MessageProcessor(), this); pluginManager.registerEvents(new ExtraListeners(), this); pluginManager.registerEvents(this, this); RelayMCUtils.registerCommand("leave", new LeaveCommand()); RelayMCUtils.registerCommand(PLUGIN_ID, new RelayHubCommand()); if (!isLimbo()) { RelayMCUtils.registerCommand("rmch", new RelayHubCommand()); RelayMCUtils.registerCommand("fly", new FlyCommand()); RelayMCUtils.registerCommand("queue", new QueueCommand()); RelayMCUtils.registerCommand("settings", new SettingsCommand()); RelayMCUtils.registerCommand("vanish", new VanishCommand()); RelayMCUtils.registerCommand("kit", new KitCommand()); RelayMCUtils.registerCommand("spawn", new SpawnCommand()); RelayMCUtils.registerCommand("stuck", new SpawnCommand()); RelayMCUtils.registerCommand("statistics", new StatisticsCommand()); RelayMCUtils.registerCommand("profile", new ProfileCommand()); RelayMCUtils.registerCommand("leaderboards", new LeaderboardsCommand()); RelayMCUtils.registerCommand("parkour", new ParkourCommand()); RelayMCUtils.registerCommand("duel", new DuelCommand()); RelayMCUtils.registerCommand("nick", new NicknameCommand()); RelayMCUtils.registerCommand("setspawn", new SetSpawnCommand()); RelayMCUtils.registerCommand("hide", new HideCommand()); RelayMCUtils.registerCommand("afk", new AFKCommand()); RelayMCUtils.registerCommand("rematch", new RematchCommand()); RelayMCUtils.registerCommand("custommaps", new CustomMapsCommand()); RelayMCUtils.registerCommand("customkits", new CustomKitsCommand()); RelayMCUtils.registerCommand("cosmetics", new CosmeticsCommand()); RelayMCUtils.registerCommand("sharekit", new ShareKitCommand()); RelayMCUtils.registerCommand("sharemap", new ShareMapCommand()); RelayMCUtils.registerCommand("setmap", new SetMapCommand()); RelayMCUtils.registerCommand("teleport", new TeleportCommand()); RelayMCUtils.registerCommand("custommap", new CustomMapCommand()); } this.getServer().getScheduler().scheduleSyncRepeatingTask(this, Main::repeat, 0, 1); RelayMCUtils.setMinMemory(96); overworld.setPVP(true); overworld.setGameRule(GameRule.FALL_DAMAGE, false); overworld.setGameRule(GameRule.DO_TILE_DROPS, false); overworld.setGameRule(GameRule.DO_ENTITY_DROPS, false); if (isDuelsLobby()) { scheduleSyncDelayedTask(Main::getMapPresets, 2); } scheduleSyncDelayedTask(() -> { for (SmartNPC smartNPC : SmartNPC.getSmartNPCs()) { Collection armorStands = getWorld().getNearbyEntitiesByType(ArmorStand.class, smartNPC.getLocation().toLocation(getWorld()), 1); for (ArmorStand armorStand : armorStands) { if (!armorStand.getUniqueId().equals(smartNPC.getLowerArmorStand().getUniqueId()) && !armorStand.getUniqueId().equals(smartNPC.getUpperArmorStand().getUniqueId())) { armorStand.remove(); } } } for (Parkour parkour : Parkour.PARKOUR_LIST) { for (Location checkpoint : parkour.getCheckpoints()) { Collection armorStands = getWorld().getNearbyEntitiesByType(ArmorStand.class, checkpoint, 1); for (ArmorStand armorStand : armorStands) { if (!parkour.getArmorStands().contains(armorStand) && StatisticsLeaderboard.getFromStand(armorStand) == null) { armorStand.remove(); } } } } for (StatisticsLeaderboard leaderboard : StatisticsLeaderboard.LEADERBOARDS) { Collection armorStands = getWorld().getNearbyEntitiesByType(ArmorStand.class, leaderboard.getLocation(), 1); for (ArmorStand armorStand : armorStands) { if (StatisticsLeaderboard.getFromStand(armorStand) == null && Miscellaneous.match(Parkour.PARKOUR_LIST, parkour -> Miscellaneous.match(parkour.getArmorStands(), armorStand1 -> armorStand1 == armorStand) != null) == null) { armorStand.remove(); } } } }, 10); scheduleSyncDelayedTask(() -> { for (ArmorStand entitiesByClass : overworld.getEntitiesByClass(ArmorStand.class)) { entitiesByClass.remove(); } }, 5); scheduleSyncDelayedTask(() -> { configuration = new SpecialConfiguration(this.getDataFolder(), PLUGIN_ID); RelayMCUtils.setAvailable(true); }, 15); info("Enabled."); RelayMCUtils.setAvailable(false); SmartGUIUtils.initialize(); } private static void getMapPresets() { List ids = Miscellaneous.getList("walledtemplate", "laketemplate", "cavetemplate", "islandtemplate", "bedrocktemplate"); if (RelayUtils.testing) { ids.addAll(Miscellaneous.processList(Miscellaneous.getList(DuelMap.CASUAL_COURTYARD, DuelMap.BLUE_KINGDOM), DuelMap::getCodeName)); } for (String id : ids) { async(() -> { CustomMap customMap = CustomMap.getCustomMap(id); if (customMap != null) { CUSTOM_MAP_TEMPLATES.add(customMap); } }); } } public void saveConfig() { File dataFolder = this.getDataFolder(); info("Saving config."); RelayUtils.tryAndPrintException(() -> { if (!dataFolder.exists()) { dataFolder.mkdirs(); } File fileConfiguration = new File(dataFolder, "data.yml"); if (!fileConfiguration.exists()) { try { if (!fileConfiguration.createNewFile()) { try { throw new Exception("Could not create configuration file!"); } catch (Exception e) { throw new RuntimeException(e); } } } catch (IOException e) { throw new RuntimeException(e); } YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(fileConfiguration); yamlConfiguration.set("testing", RelayUtils.testing); yamlConfiguration.set("hubType", hubType); yamlConfiguration.set("spawnYaw", yaw); yamlConfiguration.set("pvpArena.enabled", false); yamlConfiguration.set("pvpArenaPos1", Miscellaneous.getList(0, 0, 0)); yamlConfiguration.set("pvpArenaPos2", Miscellaneous.getList(0, 0, 0)); yamlConfiguration.set("leaderboardsArea.enabled", false); yamlConfiguration.set("leaderboardsArea.coords", Miscellaneous.getList(0, 0, 0)); yamlConfiguration.set("leaderboardsArea.yaw", leaderboardYaw); try { yamlConfiguration.save(fileConfiguration); } catch (IOException e) { throw new RuntimeException(e); } } }, "save hub config"); } public void readConfig() { File dataFolder = this.getDataFolder(); info("Reading config."); RelayUtils.tryAndPrintException(() -> { World overworld = Bukkit.getWorld("overworld"); File fileConfiguration = new File(dataFolder, "data.yml"); if (!fileConfiguration.exists()) { this.saveConfig(); } YamlConfiguration yamlConfiguration = YamlConfiguration.loadConfiguration(fileConfiguration); hubType = yamlConfiguration.getString("hubType"); yaw = (float) yamlConfiguration.getDouble("spawnYaw"); pvpArenaEnabled = yamlConfiguration.getBoolean("pvpArena.enabled"); List pvpArenaPos1 = yamlConfiguration.getIntegerList("pvpArenaPos1"); List pvpArenaPos2 = yamlConfiguration.getIntegerList("pvpArenaPos2"); int x1 = pvpArenaPos1.get(0); int y1 = pvpArenaPos1.get(1); int z1 = pvpArenaPos1.get(2); int x2 = pvpArenaPos2.get(0); int y2 = pvpArenaPos2.get(1); int z2 = pvpArenaPos2.get(2); arenaPosA = new Location(overworld, x1, y1, z1); arenaPosB = new Location(overworld, x2, y2, z2); leaderboardsAreaEnabled = yamlConfiguration.getBoolean("leaderboardsArea.enabled"); List leaderboardsAreaCoords = yamlConfiguration.getIntegerList("leaderboardsArea.coords"); leaderboardYaw = (float) yamlConfiguration.getDouble("leaderboardsArea.yaw"); leaderboardsArea = new Location(overworld, leaderboardsAreaCoords.get(0), leaderboardsAreaCoords.get(1), leaderboardsAreaCoords.get(2)); leaderboardsArea.setYaw(leaderboardYaw); }, "read hub config"); this.saveConfig(); } public static void broadcastMessage(String format, Object... data) { Bukkit.broadcastMessage(RelayUtils.format(format, data)); } public static void async(Runnable runnable) { RelayMCUtils.async(runnable, false); } private static boolean scheduledRestartTriggered = false; @EventHandler public void onNotEnoughMemory(NotEnoughMemoryEvent event) { if (!scheduledRestartTriggered) { for (HubPlayer onlineHubPlayer : HubPlayer.getOnlineHubPlayers()) { onlineHubPlayer.playSound(Sound.BLOCK_NOTE_BLOCK_SNARE); onlineHubPlayer.sendMessage(new ComponentBuilder(ComponentBuilder.RED_ORANGE).line().newLine().color(ComponentBuilder.RED).append("This lobby will be restarting in 60 seconds.").newLine().color(ComponentBuilder.RED_ORANGE).line()); } isAboutToRestart = true; scheduleSyncDelayedTask(() -> { for (HubPlayer onlineHubPlayer : HubPlayer.getOnlineHubPlayers()) { onlineHubPlayer.sendErrorMessage("Server restarting."); scheduleSyncDelayedTask(() -> { onlineHubPlayer.sendToMainHub(); onlineHubPlayer.getSmartPlayer().scheduleKickIfOnline(1, "This lobby has restarted. You may rejoin the network."); }, 8.5); for (int i = 0; i < 10; i++) { scheduleSyncDelayedTask(() -> { if (onlineHubPlayer.isOnline()) { onlineHubPlayer.sendToHubType(getMainGame()); } }, i); } } info("Scheduled restart in 10 seconds."); scheduleSyncDelayedTask(RelayUtils::restart, 10); }, 55); } scheduledRestartTriggered = true; } public static MainGame getMainGame() { return mainGame; } public static void addPlayerToStats(HubPlayer hubPlayer) { SmartDatabase.addToStatisticsTableBasic(getMainGame(), hubPlayer.getUUID()); } public static List getLeaderboards(String column) { List resultSets = new ArrayList<>(); try { if (column.contains("parkour")) { resultSets.add(SmartDatabase.executeQuery(getSQLForLeaderboard(column.substring(8), "parkour_leaderboard")).get(5, TimeUnit.SECONDS)); } else if (column.contains("arena")) { String replacement = column.substring(6); if (replacement.contains("max")) { replacement = "max_killstreak"; } info("arena column: %s", replacement); resultSets.add(SmartDatabase.executeQuery(getSQLForLeaderboard(replacement, "arena_stats")).get(5, TimeUnit.SECONDS)); } else if (Miscellaneous.getList("credits", "experience", "time_played").contains(column)) { if (column.equalsIgnoreCase("time_played")) { column = "timePlayed"; } resultSets.add(SmartDatabase.executeQuery(getSQLForLeaderboard(column, "profile")).get(5, TimeUnit.SECONDS)); } else { resultSets.add(SmartDatabase.executeQuery(getSQLForLeaderboard(column, "leaderboard")).get(5, TimeUnit.SECONDS)); resultSets.add(SmartDatabase.executeQuery(getSQLForLeaderboard(column, "leaderboard_weekly")).get(5, TimeUnit.SECONDS)); resultSets.add(SmartDatabase.executeQuery(getSQLForLeaderboard(column, "leaderboard_daily")).get(5, TimeUnit.SECONDS)); } } catch (Exception exception) { error("An error occurred while attempting to get leaderboards for statistic (%s): %s", column, exception.getMessage()); } return resultSets; } public static String getSQLForLeaderboard(String column, String leaderboardName) { if (leaderboardName.contains("parkour")) { return String.format("SELECT `id`, `time` FROM `parkour_leaderboard` WHERE `parkour_id`='%s' ORDER BY `parkour_leaderboard`.`time` ASC LIMIT 100", column); } return String.format("SELECT `id`, `%s` FROM `%s` ORDER BY `%s`.`%s` DESC LIMIT 100", column, leaderboardName, leaderboardName, column); } public static String shortenNumber(Number number) { if (number.intValue() == number.doubleValue()) { return String.valueOf(Math.max(0, number.intValue())); } return Text.shortenDouble(number.doubleValue(), 2); } public static String getScoreboardName() { if (isGameLobby()) { return getMainGame().getName().toUpperCase(); } return "RELAY"; } public static boolean hasKits() { return GameKit.gameHasKits(getMainGame()); } public static World getWorld() { return Bukkit.getWorld("overworld"); } public static Location getSpawnLocation() { return getWorld().getSpawnLocation(); } public static List getSpecificGameActions() { return SpecificGameAction.getSpecificGameActions(getMainGame()); } public static GameAction getGameAction(String value) { for (GameAction gameAction : getGameActions()) { if (Text.toComparable(value).equals(Text.toComparable(gameAction.getCodeName()))) { return gameAction; } } return null; } public static List getGameActions() { return GameAction.getGameActions(getMainGame()); } public static boolean hasLeaderboardsArea() { return leaderboardsAreaEnabled; } public static Location getLeaderboardsArea() { return leaderboardsArea; } @Override public void onDisable() { if (configuration == null) { configuration = new SpecialConfiguration(this.getDataFolder(), PLUGIN_ID); } else { configuration.updateConfigurationFromVariables(); } for (ArmorStand entitiesByClass : getWorld().getEntitiesByClass(ArmorStand.class)) { entitiesByClass.remove(); } try { File file = new File(getWorld().getWorldFolder().getPath() + "/entities"); if (file.exists()) { for (File listFile : file.listFiles()) { listFile.deleteOnExit(); } } } catch (Exception e) { RelayUtils.printError("Couldn't delete entities folder", e); } SmartNPC.clear(); SmartPlayer.shutdown(); SmartDatabase.shutdown(); for (HubPlayer onlineHubPlayer : HubPlayer.getOnlineHubPlayers()) { onlineHubPlayer.disableAllCosmetics(); } MessageClient.end(); info("Ended message client."); info("Disabled."); } public static void info(String format, Object... data) { RelayUtils.info(format, data); } public static void warn(String format, Object... data) { RelayUtils.warn(format, data); } public static void error(String format, Object... data) { RelayUtils.error(format, data); } public static void repeat() { HubPlayer.onTick(); if (RelayMCUtils.getTicks() % (20 * 30) == 0) { StatisticsLeaderboard.updateLeaderboards(); } if (RelayMCUtils.getTicks() % (20 * 60) == 0) { async(Main::updateCustomMapsList); async(Main::updateCustomKitsList); } if (RelayMCUtils.getTicks() % ( 20 * 60) == 0) { info("------------------\nRemaining Memory: %d MB\n--------------------", Miscellaneous.getRemainingMemoryMegaBytes()); } StatisticsLeaderboard.onTick(); } private static void updateCustomMapsList() { if (!isDuelsLobby()) { return; } try { String query = RelayUtils.format("SELECT * FROM `%s` WHERE `visibility`='1' ORDER BY `published` DESC LIMIT 45", SmartDatabase.CUSTOM_MAP_TABLE_NAME); ResultSet recent = SmartDatabase.executeQuery(query).get(30, TimeUnit.SECONDS); RECENT_MAPS.clear(); while (recent.next()) { try { CustomMap customMap = CustomMap.getCustomMap(recent, true); if (customMap != null) { Miscellaneous.addIfAbsent(RECENT_MAPS, customMap); } } catch (Exception e) { RelayUtils.printError("processing custom map", e); } } List timeFrames = Miscellaneous.getList("", "_daily", "_weekly", "_monthly"); for (int i = 0; i < timeFrames.size(); i++) { String timeFrame = timeFrames.get(i); String databaseName = SmartDatabase.CUSTOM_MAP_TABLE_NAME + timeFrame; List popularList = POPULAR_MAPS.get(i); if (i == 0) { query = RelayUtils.format("SELECT * FROM `%s` WHERE `visibility`='1' ORDER BY `plays` DESC LIMIT 45", databaseName); } else { query = RelayUtils.format("SELECT * FROM `%s` ORDER BY `plays` DESC LIMIT 45", databaseName); } ResultSet popular = SmartDatabase.executeQuery(query).get(30, TimeUnit.SECONDS); popularList.clear(); while (popular.next()) { try { CustomMap customMap; if (i == 0) { customMap = CustomMap.getCustomMap(popular, true); } else { customMap = CustomMap.getCustomMap(popular.getString("id")); } if (customMap != null) { Miscellaneous.addIfAbsent(popularList, customMap); customMap.setPlays(i, popular.getInt("plays")); customMap.setVotes(i, popular.getInt("votes")); } } catch (Exception e) { RelayUtils.printError("processing custom map", e); } } } } catch (Exception exception) { RelayUtils.printError("getting custom maps", exception); } } private static void updateCustomKitsList() { if (!isDuelsLobby()) { return; } try { ResultSet recent = SmartDatabase.executeQuery("SELECT * FROM `%s` WHERE `visibility`='1' ORDER BY `published` DESC LIMIT 45", SmartDatabase.CUSTOM_KIT_TABLE_NAME).get(30, TimeUnit.SECONDS); RECENT_KITS.clear(); while (recent.next()) { try { CustomDuelsKit customMap = CustomDuelsKit.getCustomDuelsKit(recent, true); if (customMap != null) { Miscellaneous.addIfAbsent(RECENT_KITS, customMap); } } catch (Exception e) { RelayUtils.printError("processing custom kit", e); } } List timeFrames = Miscellaneous.getList("", "_daily", "_weekly", "_monthly"); for (int i = 0; i < timeFrames.size(); i++) { String timeFrame = timeFrames.get(i); String databaseName = SmartDatabase.CUSTOM_KIT_TABLE_NAME + timeFrame; List popularList = POPULAR_KITS.get(i); String query; if (i == 0) { query = RelayUtils.format("SELECT * FROM `%s` WHERE `visibility`='1' ORDER BY `plays` DESC LIMIT 45", databaseName); } else { query = RelayUtils.format("SELECT * FROM `%s` ORDER BY `plays` DESC LIMIT 45", databaseName); } ResultSet popular = SmartDatabase.executeQuery(query).get(30, TimeUnit.SECONDS); popularList.clear(); while (popular.next()) { try { CustomDuelsKit customDuelsKit; if (i == 0) { customDuelsKit = CustomDuelsKit.getCustomDuelsKit(popular, true); } else { customDuelsKit = CustomDuelsKit.getCustomDuelsKit(popular.getString("id")); } if (customDuelsKit != null) { Miscellaneous.addIfAbsent(popularList, customDuelsKit); customDuelsKit.setPlays(i, popular.getInt("plays")); customDuelsKit.setVotes(i, popular.getInt("votes")); } } catch (Exception e) { RelayUtils.printError("processing custom kit", e); } } } } catch (Exception exception) { RelayUtils.printError("getting custom kits", exception); } } public static void scheduleSyncDelayedTask(Runnable runnable, double secondDelay) { RelayMCUtils.scheduleSyncDelayedTask(runnable, secondDelay); } public static void synchronous(Runnable runnable) { scheduleSyncDelayedTask(runnable, 0); } public static void onPlayerCount(Map counts) { Map totals = new HashMap<>(); int totalPartyCount = 0; for (GameType gameType : counts.keySet()) { if (gameType != null && gameType.getMainGame() == MainGame.PARTY) { totalPartyCount += counts.get(gameType); } } for (MainGame mainGame : MainGame.values()) { int total = 0; for (GameType gameType : counts.keySet()) { if (gameType.getMainGame() == mainGame) { total += counts.get(gameType); } } totals.put(mainGame.getName(), total); } for (SmartNPC smartNPC : SmartNPC.getSmartNPCs()) { totals.forEach((s, integer) -> { if (Text.comparablyContains(smartNPC.lowerName.getValue(), s)) { smartNPC.setUpperName(ChatColor.YELLOW.toString() + integer + " playing"); } }); if (Text.comparablyContains(smartNPC.lowerName.getValue(), "games")) { smartNPC.setUpperName(ChatColor.YELLOW.toString() + totalPartyCount + " playing"); } for (GameType gameType : counts.keySet()) { if (Text.comparablyContains(smartNPC.lowerName.getValue(), gameType)) { smartNPC.setUpperName(ChatColor.YELLOW.toString() + counts.get(gameType) + " playing"); } else if (gameType != null) { /* SmartGUI smartGUI = smartNPC.commandOrMessage.getValue(); if (smartGUI != null && Text.comparablyEquals(smartGUI.getName(), gameType.getFullPrettyName())) { smartNPC.setUpperName(ChatColor.YELLOW.toString() + counts.get(gameType) + " playing"); } else { */ String command = smartNPC.commandOrMessage.getValue(); if (command.contains("/") && Text.comparablyContains(command, gameType.getFullPrettyName())) { smartNPC.setUpperName(ChatColor.YELLOW.toString() + counts.get(gameType) + " playing"); // } } } } } SmartGUIUtils.onPlayerCount(counts); } public static void onCustomKitsCount(String argument) { JsonObject jsonObject = RelayUtils.parseJsonObject(argument); JsonArray current = jsonObject.get("current").getAsJsonArray(); JsonArray queued = jsonObject.get("queued").getAsJsonArray(); List currentGames = Miscellaneous.processList(current, jsonElement -> QueueData.fromString(jsonElement.getAsString())); List queuedGames = Miscellaneous.processList(queued, jsonElement -> QueueData.fromString(jsonElement.getAsString())); SmartGUIUtils.currentGames = currentGames; SmartGUIUtils.queuedGames = queuedGames; synchronous(() -> SmartGUIUtils.updateQueueGUIs(currentGames, queuedGames)); } public static boolean isGameLobby() { return mainGame != null; } public static boolean isDuelsLobby() { return mainGame == MainGame.DUELS; } public static String getName(PotionEffectType type) { return Text.prettify(type.getName()); } }