diff options
Diffstat (limited to 'src/main/java/dev/tylerm/khs/configuration')
8 files changed, 1407 insertions, 0 deletions
diff --git a/src/main/java/dev/tylerm/khs/configuration/Config.java b/src/main/java/dev/tylerm/khs/configuration/Config.java new file mode 100644 index 0000000..36d74d8 --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/Config.java @@ -0,0 +1,289 @@ +package dev.tylerm.khs.configuration; + +import com.cryptomorin.xseries.XItemStack; +import com.cryptomorin.xseries.XMaterial; +import com.cryptomorin.xseries.XSound; +import dev.tylerm.khs.Main; +import dev.tylerm.khs.game.util.CountdownDisplay; +import dev.tylerm.khs.util.Location; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class Config { + + private static ConfigManager config; + + public static String + messagePrefix, + errorPrefix, + tauntPrefix, + worldBorderPrefix, + abortPrefix, + gameOverPrefix, + warningPrefix, + locale, + leaveServer, + placeholderError, + placeholderNoData, + databaseType, + databaseHost, + databasePort, + databaseUser, + databasePass, + databaseName; + + public static boolean + nameTagsVisible, + permissionsRequired, + announceMessagesToNonPlayers, + tauntEnabled, + tauntCountdown, + tauntLast, + alwaysGlow, + glowEnabled, + glowStackable, + pvpEnabled, + autoJoin, + teleportToExit, + lobbyCountdownEnabled, + seekerPing, + bungeeLeave, + lobbyItemStartAdmin, + leaveOnEnd, + mapSaveEnabled, + allowNaturalCauses, + saveInventory, + delayedRespawn, + dontRewardQuit, + spawnPatch, + dropItems, + respawnAsSpectator, + waitTillNoneLeft, + gameOverTitle, + regenHealth; + + public static int + minPlayers, + gameLength, + tauntDelay, + glowLength, + countdown, + changeCountdown, + lobbyMin, + lobbyMax, + seekerPingLevel1, + seekerPingLevel2, + seekerPingLevel3, + lobbyItemLeavePosition, + lobbyItemStartPosition, + flightToggleItemPosition, + teleportItemPosition, + startingSeekerCount, + delayedRespawnDelay, + hidingTimer, + endGameDelay; + + public static float + seekerPingLeadingVolume, + seekerPingVolume, + seekerPingPitch; + + public static List<String> + blockedCommands, + blockedInteracts; + + public static ItemStack + lobbyLeaveItem, + lobbyStartItem, + glowPowerupItem, + flightToggleItem, + teleportItem; + + public static XSound + ringingSound, + heartbeatSound; + + public static CountdownDisplay + countdownDisplay; + + public static Location + exitPosition; + + public static void loadConfig() { + + config = ConfigManager.create("config.yml"); + config.saveConfig(); + + announceMessagesToNonPlayers = config.getBoolean("announceMessagesToNonPlayers"); + + //Prefix + char SYMBOL = 'ยง'; + String SYMBOL_STRING = String.valueOf(SYMBOL); + + messagePrefix = config.getString("prefix.default").replace("&", SYMBOL_STRING); + errorPrefix = config.getString("prefix.error").replace("&", SYMBOL_STRING); + tauntPrefix = config.getString("prefix.taunt").replace("&", SYMBOL_STRING); + worldBorderPrefix = config.getString("prefix.border").replace("&", SYMBOL_STRING); + abortPrefix = config.getString("prefix.abort").replace("&", SYMBOL_STRING); + gameOverPrefix = config.getString("prefix.gameover").replace("&", SYMBOL_STRING); + warningPrefix = config.getString("prefix.warning").replace("&", SYMBOL_STRING); + + // Locations + exitPosition = new Location( + config.getString("exit.world"), + config.getInt("exit.x"), + config.getInt("exit.y"), + config.getInt("exit.z") + ); + mapSaveEnabled = config.getBoolean("mapSaveEnabled"); + + //Taunt + tauntEnabled = config.getBoolean("taunt.enabled"); + tauntCountdown = config.getBoolean("taunt.showCountdown"); + tauntDelay = Math.max(60, config.getInt("taunt.delay")); + tauntLast = config.getBoolean("taunt.whenLastPerson"); + + //Glow + alwaysGlow = config.getBoolean("alwaysGlow") && Main.getInstance().supports(9); + glowLength = Math.max(1, config.getInt("glow.time")); + glowStackable = config.getBoolean("glow.stackable"); + glowEnabled = config.getBoolean("glow.enabled") && Main.getInstance().supports(9) && !alwaysGlow; + if (glowEnabled) { + glowPowerupItem = createItemStack("glow"); + } + + //Lobby + startingSeekerCount = Math.max(1, config.getInt("startingSeekerCount")); + waitTillNoneLeft = config.getBoolean("waitTillNoneLeft"); + minPlayers = Math.max(1 + startingSeekerCount + (waitTillNoneLeft ? 0 : 1), config.getInt("minPlayers")); + countdown = Math.max(10, config.getInt("lobby.countdown")); + changeCountdown = Math.max(minPlayers, config.getInt("lobby.changeCountdown")); + lobbyMin = Math.max(minPlayers, config.getInt("lobby.min")); + lobbyMax = config.getInt("lobby.max"); + lobbyCountdownEnabled = config.getBoolean("lobby.enabled"); + + //SeekerPing + seekerPing = config.getBoolean("seekerPing.enabled"); + seekerPingLevel1 = config.getInt("seekerPing.distances.level1"); + seekerPingLevel2 = config.getInt("seekerPing.distances.level2"); + seekerPingLevel3 = config.getInt("seekerPing.distances.level3"); + seekerPingLeadingVolume = config.getFloat("seekerPing.sounds.leadingVolume"); + seekerPingVolume = config.getFloat("seekerPing.sounds.volume"); + seekerPingPitch = config.getFloat("seekerPing.sounds.pitch"); + Optional<XSound> heartbeatOptional = XSound.matchXSound(config.getString("seekerPing.sounds.heartbeatNoise")); + heartbeatSound = heartbeatOptional.orElse(XSound.BLOCK_NOTE_BLOCK_BASEDRUM); + Optional<XSound> ringingOptional = XSound.matchXSound(config.getString("seekerPing.sounds.ringingNoise")); + ringingSound = ringingOptional.orElse(XSound.BLOCK_NOTE_BLOCK_PLING); + + //Other + nameTagsVisible = config.getBoolean("nametagsVisible"); + permissionsRequired = config.getBoolean("permissionsRequired"); + gameLength = config.getInt("gameLength"); + pvpEnabled = config.getBoolean("pvp"); + allowNaturalCauses = config.getBoolean("allowNaturalCauses"); + autoJoin = config.getBoolean("autoJoin"); + teleportToExit = config.getBoolean("teleportToExit"); + locale = config.getString("locale", "local"); + blockedCommands = config.getStringList("blockedCommands"); + leaveOnEnd = config.getBoolean("leaveOnEnd"); + placeholderError = config.getString("placeholder.incorrect"); + placeholderNoData = config.getString("placeholder.noData"); + saveInventory = config.getBoolean("saveInventory"); + respawnAsSpectator = config.getBoolean("respawnAsSpectator"); + dontRewardQuit = config.getBoolean("dontRewardQuit"); + endGameDelay = Math.max(0,config.getInt("endGameDelay")); + gameOverTitle = config.getBoolean("gameOverTitle"); + hidingTimer = Math.max(10, config.getInt("hidingTimer")); + + try { + countdownDisplay = CountdownDisplay.valueOf(config.getString("hideCountdownDisplay")); + } catch (IllegalArgumentException e) { + throw new RuntimeException("hideCountdownDisplay: "+config.getString("hideCountdownDisplay")+", is not a valid configuration option!"); + } + blockedInteracts = new ArrayList<>(); + List<String> tempInteracts = config.getStringList("blockedInteracts"); + for(String id : tempInteracts) { + Optional<XMaterial> optional_mat = XMaterial.matchXMaterial(id); + if (optional_mat.isPresent()) { + Material mat = optional_mat.get().parseMaterial(); + if (mat != null) { + blockedInteracts.add(mat.name()); + } + } + } + bungeeLeave = config.getString("leaveType") == null || config.getString("leaveType").equalsIgnoreCase("proxy"); + leaveServer = config.getString("leaveServer"); + + //Lobby Items + if (config.getBoolean("lobbyItems.leave.enabled")) { + lobbyLeaveItem = createItemStack("lobbyItems.leave"); + lobbyItemLeavePosition = config.getInt("lobbyItems.leave.position"); + } + if (config.getBoolean("lobbyItems.start.enabled")) { + lobbyStartItem = createItemStack("lobbyItems.start"); + lobbyItemStartAdmin = config.getBoolean("lobbyItems.start.adminOnly"); + lobbyItemStartPosition = config.getInt("lobbyItems.start.position"); + } + + //Spectator Items + flightToggleItem = createItemStack("spectatorItems.flight"); + flightToggleItemPosition = config.getInt("spectatorItems.flight.position"); + + teleportItem = createItemStack("spectatorItems.teleport"); + teleportItemPosition = config.getInt("spectatorItems.teleport.position"); + + //Database + databaseHost = config.getString("databaseHost"); + databasePort = config.getString("databasePort"); + databaseUser = config.getString("databaseUser"); + databasePass = config.getString("databasePass"); + databaseName = config.getString("databaseName"); + + databaseType = config.getString("databaseType").toUpperCase(); + if(!databaseType.equals("SQLITE") && !databaseType.equals("MYSQL")){ + throw new RuntimeException("databaseType: "+databaseType+" is not a valid configuration option!"); + } + + delayedRespawn = config.getBoolean("delayedRespawn.enabled"); + delayedRespawnDelay = Math.max(0,config.getInt("delayedRespawn.delay")); + + spawnPatch = config.getBoolean("spawnPatch"); + dropItems = config.getBoolean("dropItems"); + regenHealth = config.getBoolean("regenHealth"); + + } + + public static void addToConfig(String path, Object value) { + config.set(path, value); + } + + public static void saveConfig() { + config.saveConfig(); + } + + @Nullable + private static ItemStack createItemStack(String path){ + ConfigurationSection item = new YamlConfiguration().createSection("temp"); + item.set("name", ChatColor.translateAlternateColorCodes('&',config.getString(path+".name"))); + item.set("material", config.getString(path+".material")); + if (Main.getInstance().supports(14)) { + if (config.contains(path+".model-data") && config.getInt(path+".model-data") != 0) { + item.set("model-data", config.getInt(path+".model-data")); + } + } + List<String> lore = config.getStringList(path+".lore"); + if (lore != null && !lore.isEmpty()) item.set("lore", lore); + ItemStack temp = null; + try{ temp = XItemStack.deserialize(item); } catch(Exception ignored) {} + return temp; + } + +} diff --git a/src/main/java/dev/tylerm/khs/configuration/ConfigManager.java b/src/main/java/dev/tylerm/khs/configuration/ConfigManager.java new file mode 100644 index 0000000..3a81cb8 --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/ConfigManager.java @@ -0,0 +1,331 @@ +package dev.tylerm.khs.configuration; + +import dev.tylerm.khs.Main; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.List; +import java.util.Map; + +public class ConfigManager { + + private final File file; + private YamlConfiguration config,defaultConfig; + private String defaultFilename; + + public static ConfigManager create(String filename) { + return new ConfigManager(filename, filename); + } + + public static ConfigManager create(String filename, String defaultFilename) { + return new ConfigManager(filename, defaultFilename); + } + + private ConfigManager(String filename, String defaultFilename) { + + File dataFolder = Main.getInstance().getDataFolder(); + File oldDataFolder = new File(Main.getInstance().getDataFolder().getParent() + File.separator + "HideAndSeek"); + + this.defaultFilename = defaultFilename; + this.file = new File(dataFolder, filename); + + if(oldDataFolder.exists()){ + if(!dataFolder.exists()){ + if(!oldDataFolder.renameTo(dataFolder)){ + throw new RuntimeException("Could not rename folder: " + oldDataFolder.getPath()); + } + } else { + throw new RuntimeException("Plugin folders for HideAndSeek & KenshinsHideAndSeek both exists. There can only be one!"); + } + + } + + if (!dataFolder.exists()) { + if (!dataFolder.mkdirs()) { + throw new RuntimeException("Failed to make directory: " + file.getPath()); + } + } + + if (!file.exists()) { + try{ + InputStream input = Main.getInstance().getResource(defaultFilename); + if (input == null) { + throw new RuntimeException("Could not create input stream for "+defaultFilename); + } + java.nio.file.Files.copy(input, file.toPath()); + input.close(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + FileInputStream fileInputStream; + try { + fileInputStream = new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new RuntimeException("Could not create input stream for "+file.getPath()); + } + InputStreamReader reader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8); + this.config = new YamlConfiguration(); + try { + this.config.load(reader); + } catch(InvalidConfigurationException e) { + Main.getInstance().getLogger().severe(e.getMessage()); + throw new RuntimeException("Invalid configuration in config file: "+file.getPath()); + } catch(IOException e) { + throw new RuntimeException("Could not access file: "+file.getPath()); + } + + InputStream input = this.getClass().getClassLoader().getResourceAsStream(defaultFilename); + if (input == null) { + throw new RuntimeException("Could not create input stream for "+defaultFilename); + } + InputStreamReader default_reader = new InputStreamReader(input, StandardCharsets.UTF_8); + this.defaultConfig = new YamlConfiguration(); + try { + this.defaultConfig.load(default_reader); + } catch(InvalidConfigurationException e) { + Main.getInstance().getLogger().severe(e.getMessage()); + throw new RuntimeException("Invalid configuration in internal config file: "+defaultFilename); + } catch(IOException e) { + throw new RuntimeException("Could not access internal file: "+defaultFilename); + } + + try{ + fileInputStream.close(); + default_reader.close(); + } catch (IOException e) { + throw new RuntimeException("Unable to finalize loading of config files."); + } + } + + public boolean contains(String path) { + return config.contains(path); + } + + @SuppressWarnings("unused") + public double getDouble(String path) { + if (!config.contains(path)) { + return defaultConfig.getDouble(path); + } else { + return config.getDouble(path); + } + } + + public int getInt(String path) { + if (!config.contains(path)) { + return defaultConfig.getInt(path); + } else { + return config.getInt(path); + } + } + + public int getDefaultInt(String path) { + return defaultConfig.getInt(path); + } + + public float getFloat(String path) { + if (!config.contains(path)) { + return (float) defaultConfig.getDouble(path); + } else { + return (float) config.getDouble(path); + } + } + + public String getString(String path) { + String value = config.getString(path); + if (value == null) { + return defaultConfig.getString(path); + } else { + return value; + } + } + + public String getString(String path, String oldPath) { + String value = config.getString(path); + if (value == null) { + String oldValue = config.getString(oldPath); + if (oldValue == null) { + return defaultConfig.getString(path); + } else { + return oldValue; + } + } else { + return value; + } + } + + public List<String> getStringList(String path) { + List<String> value = config.getStringList(path); + if (value == null) { + return defaultConfig.getStringList(path); + } else { + return value; + } + } + + public void reset(String path) { + config.set(path, defaultConfig.get(path)); + } + + public void resetFile(String newDefaultFilename) { + this.defaultFilename = newDefaultFilename; + + InputStream input = Main.getInstance().getResource(defaultFilename); + if (input == null) { + throw new RuntimeException("Could not create input stream for "+defaultFilename); + } + InputStreamReader reader = new InputStreamReader(input); + this.config = YamlConfiguration.loadConfiguration(reader); + this.defaultConfig = YamlConfiguration.loadConfiguration(reader); + + } + + public boolean getBoolean(String path) { + if (!config.contains(path)) { + return defaultConfig.getBoolean(path); + } else { + return config.getBoolean(path); + } + } + + public ConfigurationSection getConfigurationSection(String path) { + ConfigurationSection section = config.getConfigurationSection(path); + if (section == null) { + return defaultConfig.getConfigurationSection(path); + } else { + return section; + } + } + + public ConfigurationSection getDefaultConfigurationSection(String path) { + return defaultConfig.getConfigurationSection(path); + } + + public void set(String path, Object value) { + config.set(path, value); + } + + public void overwriteConfig() { + try { + this.config.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void saveConfig() { + try { + // open config file + InputStream is = Main.getInstance().getResource(defaultFilename); + // if failed error + if (is == null) { + throw new RuntimeException("Could not create input stream for "+defaultFilename); + } + // manually read in each character to preserve string data + StringBuilder textBuilder = new StringBuilder(new String("".getBytes(), StandardCharsets.UTF_8)); + Reader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); + int c; + while((c = reader.read()) != -1) + textBuilder.append((char) c); + // store yaml file into a string + String yaml = new String(textBuilder.toString().getBytes(), StandardCharsets.UTF_8); + // get config values + Map<String, Object> data = config.getValues(true); + // write each stored config value into the yaml string + for(Map.Entry<String, Object> entry: data.entrySet()) { + // if type isn't supported, skip + if(!isSupported(entry.getValue())) continue; + // get index of key in yaml string + int index = getIndex(yaml, entry.getKey()); + // if index not found, skip + if (index < 10) continue; + // get start and end of the value + int start = yaml.indexOf(' ', index) + 1; + int end = yaml.indexOf('\n', index); + // if end not found, set it to the end of the file + if (end == -1) end = yaml.length(); + // create new replace sting + StringBuilder replace = new StringBuilder(new String("".getBytes(), StandardCharsets.UTF_8)); + // get value + Object value = entry.getValue(); + // if the value is a list, + if (value instanceof List) { + end = yaml.indexOf(']', start) + 1; + List<?> list = (List<?>) entry.getValue(); + if (list.isEmpty()) { + // if list is empty, put an empty list + replace.append("[]"); + } else { + // if list has values, populate values into the string + // get gap before key + int gap = whitespaceBefore(yaml, index); + String space = new String(new char[gap]).replace('\0', ' '); + replace.append("[\n"); + for (int i = 0; i < list.size(); i++) { + replace.append(space).append(" ").append(convert(list.get(i))); + if(i != list.size() -1) replace.append(",\n"); + } + replace.append('\n').append(space).append("]"); + } + // otherwise just put the value directly + } else { + replace.append(convert(value)); + } + // replace the new value in the yaml string + StringBuilder builder = new StringBuilder(yaml); + builder.replace(start, end, replace.toString()); + yaml = builder.toString(); + } + + // write yaml string to file + Writer fileWriter = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(file.toPath()), StandardCharsets.UTF_8)); + fileWriter.write(yaml); + fileWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private int getIndex(String yaml, String key) { + String[] parts = key.split("\\."); + int index = 0; + for(String part : parts) { + if (index == 0) { + index = yaml.indexOf("\n" + part + ":", index) + 1; + } else { + index = yaml.indexOf(" " + part + ":", index) + 1; + } + if (index == 0) break; + } + return index; + } + + public boolean isSupported(Object o) { + return o instanceof Integer || + o instanceof Double || + o instanceof String || + o instanceof Boolean || + o instanceof List; + } + + public int whitespaceBefore(String yaml, int index) { + int count = 0; + for(int i = index - 1; yaml.charAt(i) == ' '; i--) count++; + return count; + } + + private String convert(Object o) { + if(o instanceof String) { + return "\"" + o + "\""; + } else if (o instanceof Boolean) { + return (boolean)o ? "true" : "false"; + } + return o.toString(); + } + +} diff --git a/src/main/java/dev/tylerm/khs/configuration/Items.java b/src/main/java/dev/tylerm/khs/configuration/Items.java new file mode 100644 index 0000000..af8216d --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/Items.java @@ -0,0 +1,220 @@ +package dev.tylerm.khs.configuration; + +import com.cryptomorin.xseries.XItemStack; +import dev.tylerm.khs.Main; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.List; + +public class Items { + + public static List<ItemStack> HIDER_ITEMS, SEEKER_ITEMS; + public static ItemStack + HIDER_HELM, SEEKER_HELM, + HIDER_CHEST, SEEKER_CHEST, + HIDER_LEGS, SEEKER_LEGS, + HIDER_BOOTS, SEEKER_BOOTS; + + public static List<PotionEffect> HIDER_EFFECTS, SEEKER_EFFECTS; + + public static void loadItems() { + + ConfigManager manager = ConfigManager.create("items.yml"); + + SEEKER_ITEMS = new ArrayList<>(); + SEEKER_HELM = null; + SEEKER_CHEST = null; + SEEKER_LEGS = null; + SEEKER_BOOTS = null; + + ConfigurationSection SeekerItems = manager.getConfigurationSection("items.seeker"); + + for (int i = 0; i < 9; i++) { + ConfigurationSection section = SeekerItems.getConfigurationSection(String.valueOf(i)); + if (section == null) { + SEEKER_ITEMS.add(null); + continue; + } + ItemStack item = createItem(section); + SEEKER_ITEMS.add(item); + } + + ConfigurationSection SeekerHelmet = SeekerItems.getConfigurationSection("helmet"); + if (SeekerHelmet != null) { + ItemStack item = createItem(SeekerHelmet); + if (item != null) { + SEEKER_HELM = item; + } + } + + ConfigurationSection SeekerChestplate = SeekerItems.getConfigurationSection("chestplate"); + if (SeekerChestplate != null) { + ItemStack item = createItem(SeekerChestplate); + if (item != null) { + SEEKER_CHEST = item; + } + } + + ConfigurationSection SeekerLeggings = SeekerItems.getConfigurationSection("leggings"); + if (SeekerLeggings != null) { + ItemStack item = createItem(SeekerLeggings); + if (item != null) { + SEEKER_LEGS = item; + } + } + + ConfigurationSection SeekerBoots = SeekerItems.getConfigurationSection("boots"); + if (SeekerBoots != null) { + ItemStack item = createItem(SeekerBoots); + if (item != null) { + SEEKER_BOOTS = item; + } + } + + HIDER_ITEMS = new ArrayList<>(); + HIDER_HELM = null; + HIDER_CHEST = null; + HIDER_LEGS = null; + HIDER_BOOTS = null; + + ConfigurationSection HiderItems = manager.getConfigurationSection("items.hider"); + + for (int i = 0; i < 9; i++) { + ConfigurationSection section = HiderItems.getConfigurationSection(String.valueOf(i)); + if (section == null) { + HIDER_ITEMS.add(null); + continue; + } + ItemStack item = createItem(section); + HIDER_ITEMS.add(item); + } + + ConfigurationSection HiderHelmet = HiderItems.getConfigurationSection("helmet"); + if (HiderHelmet != null) { + ItemStack item = createItem(HiderHelmet); + if (item != null) { + HIDER_HELM = item; + } + } + + ConfigurationSection HiderChestplate = HiderItems.getConfigurationSection("chestplate"); + if (HiderChestplate != null) { + ItemStack item = createItem(HiderChestplate); + if (item != null) { + HIDER_CHEST = item; + } + } + + ConfigurationSection HiderLeggings = HiderItems.getConfigurationSection("leggings"); + if (HiderLeggings != null) { + ItemStack item = createItem(HiderLeggings); + if (item != null) { + HIDER_LEGS = item; + } + } + + ConfigurationSection HiderBoots = HiderItems.getConfigurationSection("boots"); + if (HiderBoots != null) { + ItemStack item = createItem(HiderBoots); + if (item != null) { + HIDER_BOOTS = item; + } + } + + SEEKER_EFFECTS = new ArrayList<>(); + ConfigurationSection SeekerEffects = manager.getConfigurationSection("effects.seeker"); + + int i = 1; + while (true) { + ConfigurationSection section = SeekerEffects.getConfigurationSection(String.valueOf(i)); + if (section == null) break; + PotionEffect effect = getPotionEffect(section); + if (effect != null) SEEKER_EFFECTS.add(effect); + i++; + } + + HIDER_EFFECTS = new ArrayList<>(); + ConfigurationSection HiderEffects = manager.getConfigurationSection("effects.hider"); + i = 1; + while (true) { + ConfigurationSection section = HiderEffects.getConfigurationSection(String.valueOf(i)); + if (section == null) break; + PotionEffect effect = getPotionEffect(section); + if (effect != null) HIDER_EFFECTS.add(effect); + i++; + } + } + + private static ItemStack createItem(ConfigurationSection item) { + ConfigurationSection config = new YamlConfiguration().createSection("temp"); + String material = item.getString("material").toUpperCase(); + boolean splash = false; + if (!Main.getInstance().supports(9)) { + if (material.contains("POTION")) { + config.set("level", 1); + } + if (material.equalsIgnoreCase("SPLASH_POTION") || material.equalsIgnoreCase("LINGERING_POTION")) { + material = "POTION"; + splash = true; + } + } + config.set("name", item.getString("name")); + config.set("material", material); + config.set("enchants", item.getConfigurationSection("enchantments")); + config.set("unbreakable", item.getBoolean("unbreakable")); + if (Main.getInstance().supports(14)) { + if (item.contains("model-data")) { + config.set("model-data", item.getInt("model-data")); + } + } + if (item.isSet("lore")) + config.set("lore", item.getStringList("lore")); + if (material.equalsIgnoreCase("POTION") || material.equalsIgnoreCase("SPLASH_POTION") || material.equalsIgnoreCase("LINGERING_POTION")) + config.set("base-effect", String.format("%s,%s,%s", item.getString("type"), false, splash)); + ItemStack stack = XItemStack.deserialize(config); + int amt = item.getInt("amount"); + if (amt < 1) amt = 1; + stack.setAmount(amt); + if (stack.getData().getItemType() == Material.AIR) return null; + return stack; + } + + private static PotionEffect getPotionEffect(ConfigurationSection item) { + String type = item.getString("type"); + if (type == null) return null; + if (PotionEffectType.getByName(type.toUpperCase()) == null) return null; + return new PotionEffect( + PotionEffectType.getByName(type.toUpperCase()), + item.getInt("duration"), + item.getInt("amplifier"), + item.getBoolean("ambient"), + item.getBoolean("particles") + ); + } + + public static boolean matchItem(ItemStack stack){ + for(ItemStack check : HIDER_ITEMS) + if(equals(stack,check)) return true; + for(ItemStack check : SEEKER_ITEMS) + if(equals(stack,check)) return true; + return false; + } + + private static boolean equals(ItemStack a, ItemStack b) { + if (a == null || b == null) { + return false; + } else if (a == b) { + return true; + } else { + return a.getType() == b.getType() && a.hasItemMeta() == b.hasItemMeta() && (!a.hasItemMeta() || Bukkit.getItemFactory().equals(a.getItemMeta(), b.getItemMeta())); + } + } + +} diff --git a/src/main/java/dev/tylerm/khs/configuration/Leaderboard.java b/src/main/java/dev/tylerm/khs/configuration/Leaderboard.java new file mode 100644 index 0000000..93ba855 --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/Leaderboard.java @@ -0,0 +1,51 @@ +package dev.tylerm.khs.configuration; + +import java.util.Collections; +import java.util.List; + +public class Leaderboard { + + public static String + LOBBY_TITLE, + GAME_TITLE, + COUNTDOWN_WAITING, + COUNTDOWN_COUNTING, + COUNTDOWN_ADMINSTART, + TAUNT_COUNTING, + TAUNT_ACTIVE, + TAUNT_EXPIRED, + GLOW_ACTIVE, + GLOW_INACTIVE, + BORDER_COUNTING, + BORDER_DECREASING; + + public static List<String> + LOBBY_CONTENTS, + GAME_CONTENTS; + + public static void loadLeaderboard() { + + ConfigManager leaderboard = ConfigManager.create("leaderboard.yml"); + + LOBBY_TITLE = leaderboard.getString("lobby.title"); + GAME_TITLE = leaderboard.getString("game.title"); + LOBBY_CONTENTS = leaderboard.getStringList("lobby.content"); + Collections.reverse(LOBBY_CONTENTS); + GAME_CONTENTS = leaderboard.getStringList("game.content"); + Collections.reverse(GAME_CONTENTS); + COUNTDOWN_WAITING = leaderboard.getString("countdown.waiting"); + COUNTDOWN_COUNTING = leaderboard.getString("countdown.counting"); + COUNTDOWN_ADMINSTART = leaderboard.getString("countdown.adminStart"); + TAUNT_COUNTING = leaderboard.getString("taunt.counting"); + TAUNT_ACTIVE = leaderboard.getString("taunt.active"); + TAUNT_EXPIRED = leaderboard.getString("taunt.expired"); + GLOW_ACTIVE = leaderboard.getString("glow.active"); + GLOW_INACTIVE = leaderboard.getString("glow.inactive"); + BORDER_COUNTING = leaderboard.getString("border.counting"); + BORDER_DECREASING = leaderboard.getString("border.decreasing"); + + leaderboard.saveConfig(); + + } + +} diff --git a/src/main/java/dev/tylerm/khs/configuration/Localization.java b/src/main/java/dev/tylerm/khs/configuration/Localization.java new file mode 100644 index 0000000..2ac84e7 --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/Localization.java @@ -0,0 +1,80 @@ +package dev.tylerm.khs.configuration; + +import net.md_5.bungee.api.ChatColor; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class Localization { + + public static final Map<String,LocalizationString> LOCAL = new HashMap<>(); + public static final Map<String,LocalizationString> DEFAULT_LOCAL = new HashMap<>(); + + private static final Map<String,String[][]> CHANGES = new HashMap<String,String[][]>() {{ + put("en-US", new String[][]{ + {"WORLDBORDER_DECREASING"}, + {"START","TAUNTED"}, + {"GAME_SETUP", "SETUP_GAME", "SETUP_LOBBY", "SETUP_SEEKER_LOBBY", "SETUP_EXIT", "SETUP_SAVEMAP", "SETUP_BOUNDS"}, + {"GAME_PLAYER_FOUND", "GAME_PLAYER_FOUND_BY"} + }); + put("de-DE", new String[][]{ + {}, + {"TAUNTED"}, + {"GAME_SETUP", "SETUP_GAME", "SETUP_LOBBY", "SETUP_SEEKER_LOBBY", "SETUP_EXIT", "SETUP_SAVEMAP", "SETUP_BOUNDS"}, + {"GAME_PLAYER_FOUND", "GAME_PLAYER_FOUND_BY"} + }); + }}; + + public static void loadLocalization() { + + ConfigManager manager = ConfigManager.create("localization.yml", "lang/localization_"+Config.locale +".yml"); + + int PLUGIN_VERSION = manager.getDefaultInt("version"); + int VERSION = manager.getInt("version"); + if (VERSION < PLUGIN_VERSION) { + for(int i = VERSION; i < PLUGIN_VERSION; i++) { + if (i < 1) continue; + String[] changeList = CHANGES.get(Config.locale)[i-1]; + for(String change : changeList) + manager.reset("Localization." + change); + } + manager.reset("version"); + } + + String SELECTED_LOCAL = manager.getString("type"); + if (SELECTED_LOCAL == null) { + manager.reset("type"); + } else if (!SELECTED_LOCAL.equals(Config.locale)) { + manager.resetFile("lang"+File.separator+"localization_"+Config.locale +".yml"); + } + + manager.saveConfig(); + + for(String key : manager.getConfigurationSection("Localization").getKeys(false)) { + LOCAL.put( + key, + new LocalizationString( ChatColor.translateAlternateColorCodes('&', manager.getString("Localization."+key) ) ) + ); + } + + for(String key : manager.getDefaultConfigurationSection("Localization").getKeys(false)) { + DEFAULT_LOCAL.put( + key, + new LocalizationString( ChatColor.translateAlternateColorCodes('&', manager.getString("Localization."+key) ) ) + ); + } + } + + public static LocalizationString message(String key) { + LocalizationString message = LOCAL.get(key); + if (message == null) { + LocalizationString defaultMessage = DEFAULT_LOCAL.get(key); + if(defaultMessage == null) { + return new LocalizationString(ChatColor.RED + "" + ChatColor.ITALIC + key + " is not found in localization.yml. This is a plugin issue, please report it."); + } + return new LocalizationString(defaultMessage.toString()); + } + return new LocalizationString(message.toString()); + } +} diff --git a/src/main/java/dev/tylerm/khs/configuration/LocalizationString.java b/src/main/java/dev/tylerm/khs/configuration/LocalizationString.java new file mode 100644 index 0000000..5dc3724 --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/LocalizationString.java @@ -0,0 +1,37 @@ +package dev.tylerm.khs.configuration; + +import org.bukkit.entity.Entity; + +public class LocalizationString { + + String message; + + public LocalizationString(String message) { + this.message = message; + } + + public LocalizationString addPlayer(Entity player) { + this.message = message.replaceFirst("\\{PLAYER}", player.getName()); + return this; + } + + public LocalizationString addPlayer(String player) { + this.message = message.replaceFirst("\\{PLAYER}", player); + return this; + } + + public LocalizationString addAmount(Integer value) { + this.message = message.replaceFirst("\\{AMOUNT}", value.toString()); + return this; + } + + public LocalizationString addAmount(String value) { + this.message = message.replaceFirst("\\{AMOUNT}", value); + return this; + } + + public String toString() { + return message; + } + +}
\ No newline at end of file diff --git a/src/main/java/dev/tylerm/khs/configuration/Map.java b/src/main/java/dev/tylerm/khs/configuration/Map.java new file mode 100644 index 0000000..7d3ef9f --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/Map.java @@ -0,0 +1,241 @@ +package dev.tylerm.khs.configuration; + +import java.util.ArrayList; +import java.util.List; + +import dev.tylerm.khs.Main; +import dev.tylerm.khs.game.events.Border; +import dev.tylerm.khs.util.Location; +import dev.tylerm.khs.world.WorldLoader; +import org.bukkit.*; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; + +import static dev.tylerm.khs.configuration.Config.*; + +public class Map { + + private final String name; + + private dev.tylerm.khs.util.Location + spawnPosition = dev.tylerm.khs.util.Location.getDefault(), + lobbyPosition = dev.tylerm.khs.util.Location.getDefault(), + seekerLobbyPosition = dev.tylerm.khs.util.Location.getDefault(); + + private int + xBoundMin = 0, + zBoundMin = 0, + xBoundMax = 0, + zBoundMax = 0, + xWorldBorder = 0, + zWorldBorder = 0, + worldBorderSize = 0, + worldBorderDelay = 0, + worldBorderChange = 0; + + private boolean + blockhunt = false; + + private List<Material> + blockhuntBlocks = new ArrayList<>(); + + private final Border + worldBorder; + + private final WorldLoader + worldLoader; + + public Map(String name) { + this.name = name; + this.worldBorder = new Border(this); + this.worldLoader = new WorldLoader(this); + } + + public void setSpawn(dev.tylerm.khs.util.Location pos) { + this.spawnPosition = pos; + } + + public void setLobby(dev.tylerm.khs.util.Location pos) { + this.lobbyPosition = pos; + } + + public void setSeekerLobby(dev.tylerm.khs.util.Location pos) { + this.seekerLobbyPosition = pos; + } + + public void setWorldBorderData(int x, int z, int size, int delay, int move) { + if(size < 1) { + this.worldBorderSize = 0; + this.worldBorderDelay = 0; + this.worldBorderChange = 0; + this.xWorldBorder = 0; + this.zWorldBorder = 0; + } else { + this.worldBorderSize = size; + this.worldBorderDelay = delay; + this.worldBorderChange = move; + this.xWorldBorder = x; + this.zWorldBorder = z; + } + this.worldBorder.resetWorldBorder(); + } + + public void setBlockhunt(boolean enabled, List<Material> blocks) { + if (Main.getInstance().supports(9)) { + this.blockhunt = enabled; + } else { + this.blockhunt = false; + } + this.blockhuntBlocks = blocks; + } + + public void setBoundMin(int x, int z) { + this.xBoundMin = x; + this.zBoundMin = z; + } + + public void setBoundMax(int x, int z) { + this.xBoundMax = x; + this.zBoundMax = z; + } + + @NotNull + public dev.tylerm.khs.util.Location getGameSpawn() { + if(mapSaveEnabled) { + return spawnPosition.changeWorld("hs_"+name); + } else { + return spawnPosition; + } + } + + @NotNull + public String getGameSpawnName() { + if(mapSaveEnabled) + return getGameSpawn().getWorld(); + else + return getSpawn().getWorld(); + } + + @NotNull + public dev.tylerm.khs.util.Location getSpawn() { + return spawnPosition; + } + + @NotNull + public String getSpawnName() { + return getSpawn().getWorld(); + } + + @NotNull + public dev.tylerm.khs.util.Location getLobby() { + return lobbyPosition; + } + + @NotNull + public String getLobbyName() { + return getLobby().getWorld(); + } + + @NotNull + public dev.tylerm.khs.util.Location getSeekerLobby() { + return seekerLobbyPosition; + } + + @NotNull + public String getSeekerLobbyName() { + return getSeekerLobby().getWorld(); + } + + @NotNull + public Location getGameSeekerLobby() { + if(mapSaveEnabled) { + return seekerLobbyPosition.changeWorld("hs_"+name); + } else { + return seekerLobbyPosition; + } + } + + public boolean isWorldBorderEnabled() { + return worldBorderSize > 0; + } + + @NotNull + public Vector getWorldBorderPos() { + return new Vector( + xWorldBorder, + 0, + zWorldBorder + ); + } + + @NotNull + public Vector getWorldBorderData() { + return new Vector( + worldBorderSize, + worldBorderDelay, + worldBorderChange + ); + } + + @NotNull + public Border getWorldBorder() { + return worldBorder; + } + + public boolean isBlockHuntEnabled() { + return blockhunt; + } + + @NotNull + public List<Material> getBlockHunt() { + return blockhuntBlocks; + } + + @NotNull + public Vector getBoundsMin() { + return new Vector( + xBoundMin, + 0, + zBoundMin + ); + } + + @NotNull + public Vector getBoundsMax() { + return new Vector( + xBoundMax, + 0, + zBoundMax + ); + } + + @NotNull + public String getName() { + return name; + } + + @NotNull + public WorldLoader getWorldLoader() { + return worldLoader; + } + + public boolean isNotSetup() { + if (spawnPosition.getBlockX() == 0 && spawnPosition.getBlockY() == 0 && spawnPosition.getBlockZ() == 0 || !spawnPosition.exists()) return true; + if (lobbyPosition.getBlockX() == 0 && lobbyPosition.getBlockY() == 0 && lobbyPosition.getBlockZ() == 0 || !lobbyPosition.exists()) return true; + if (exitPosition == null || exitPosition.getBlockX() == 0 && exitPosition.getBlockY() == 0 && exitPosition.getBlockZ() == 0 || !exitPosition.exists()) return true; + if (seekerLobbyPosition.getBlockX() == 0 && seekerLobbyPosition.getBlockY() == 0 && seekerLobbyPosition.getBlockZ() == 0 || !seekerLobbyPosition.exists()) return true; + if (mapSaveEnabled && !getGameSpawn().exists()) return true; + if (blockhunt && blockhuntBlocks.isEmpty()) return true; + if(isWorldBorderEnabled() && + new Vector(spawnPosition.getX(), 0, spawnPosition.getZ()).distance(new Vector(xWorldBorder, 0, zWorldBorder)) > 100) return true; + return isBoundsNotSetup(); + } + + public boolean isBoundsNotSetup() { + if (xBoundMin == 0 || zBoundMin == 0 || xBoundMax == 0 || zBoundMax == 0) return true; + int xDiff = xBoundMax - xBoundMin; + int zDiff = zBoundMax - zBoundMin; + return xDiff < 5 || zDiff < 5; + } + +} diff --git a/src/main/java/dev/tylerm/khs/configuration/Maps.java b/src/main/java/dev/tylerm/khs/configuration/Maps.java new file mode 100644 index 0000000..54c6d5b --- /dev/null +++ b/src/main/java/dev/tylerm/khs/configuration/Maps.java @@ -0,0 +1,158 @@ +package dev.tylerm.khs.configuration; + +import java.util.*; +import java.util.stream.Collectors; + +import dev.tylerm.khs.Main; +import dev.tylerm.khs.util.Location; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import com.cryptomorin.xseries.XMaterial; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class Maps { + + private static final HashMap<String, Map> MAPS = new HashMap<>(); + + @Nullable + public static Map getMap(String name) { + return MAPS.get(name); + } + + @Nullable + public static Map getRandomMap() { + Optional<Map> map; + if(MAPS.values().size() > 0) { + Collection<Map> setupMaps = MAPS.values().stream().filter(m -> !m.isNotSetup()).collect(Collectors.toList()); + if(setupMaps.size() < 1) { + return null; + } + map = setupMaps.stream().skip(new Random().nextInt(setupMaps.size())).findFirst(); + } else { + map = Optional.empty(); + } + return map.orElse(null); + } + + public static void setMap(String name, Map map) { + MAPS.put(name, map); + saveMaps(); + } + + public static boolean removeMap(String name) { + boolean status = MAPS.remove(name) != null; + saveMaps(); + return status; + } + + @NotNull + public static Collection<Map> getAllMaps() { + return MAPS.values(); + } + + public static void loadMaps() { + + ConfigManager manager = ConfigManager.create("maps.yml"); + + ConfigurationSection maps = manager.getConfigurationSection("maps"); + if(maps == null) return; + Set<String> keys = maps.getKeys(false); + if(keys == null) return; + + MAPS.clear(); + for(String key : keys) { + MAPS.put(key, parseMap(maps, key)); + } + + } + + private static Map parseMap(ConfigurationSection maps, String name) { + ConfigurationSection data = maps.getConfigurationSection(name); + if(data == null) return null; + Map map = new Map(name); + Main.getInstance().getLogger().info("Loading map: " + name + "..."); + map.setSpawn(getSpawn(data, "game")); + map.setLobby(getSpawn(data, "lobby")); + map.setSeekerLobby(getSpawn(data, "seeker")); + map.setBoundMin(data.getInt("bounds.min.x"), data.getInt("bounds.min.z")); + map.setBoundMax(data.getInt("bounds.max.x"), data.getInt("bounds.max.z")); + map.setWorldBorderData( + data.getInt("worldborder.pos.x"), + data.getInt("worldborder.pos.z"), + data.getInt("worldborder.size"), + data.getInt("worldborder.delay"), + data.getInt("worldborder.change") + ); + List<String> blockhunt = data.getStringList("blockhunt.blocks"); + if(blockhunt == null) blockhunt = new ArrayList<>(); + map.setBlockhunt( + data.getBoolean("blockhunt.enabled"), + blockhunt + .stream() + .map(XMaterial::matchXMaterial) + .filter(Optional::isPresent) + .map(e -> e.get().parseMaterial()) + .filter(Objects::nonNull) + .collect(Collectors.toList()) + ); + return map; + } + + private static Location getSpawn(ConfigurationSection data, String spawn) { + String world = data.getString("spawns."+spawn+".world"); + double x = data.getDouble("spawns."+spawn+".x"); + double y = data.getDouble("spawns."+spawn+".y"); + double z = data.getDouble("spawns."+spawn+".z"); + return new Location(world, x, y, z); + } + + private static void saveMaps() { + + ConfigManager manager = ConfigManager.create("maps.yml"); + ConfigurationSection maps = new YamlConfiguration(); + + for(Map map : MAPS.values()) { + ConfigurationSection data = new YamlConfiguration(); + saveSpawn(data, map.getSpawn(), "game", map); + saveSpawn(data, map.getLobby(), "lobby", map); + saveSpawn(data, map.getSeekerLobby(), "seeker", map); + data.set("bounds.min.x", map.getBoundsMin().getX()); + data.set("bounds.min.z", map.getBoundsMin().getZ()); + data.set("bounds.max.x", map.getBoundsMax().getX()); + data.set("bounds.max.z", map.getBoundsMax().getZ()); + data.set("worldborder.pos.x", map.getWorldBorderPos().getX()); + data.set("worldborder.pos.z", map.getWorldBorderPos().getZ()); + data.set("worldborder.pos.size", map.getWorldBorderData().getX()); + data.set("worldborder.pos.delay", map.getWorldBorderData().getY()); + data.set("worldborder.pos.change", map.getWorldBorderData().getZ()); + data.set("blockhunt.enabled", map.isBlockHuntEnabled()); + data.set("blockhunt.blocks", map.getBlockHunt().stream().map(Material::name).collect(Collectors.toList())); + maps.set(map.getName(), data); + } + + manager.set("maps", maps); + manager.overwriteConfig(); + + } + + private static void saveSpawn(ConfigurationSection data, Location spawn, String name, Map map) { + String worldName = getWorldName(name, map); + data.set("spawns." + name + ".world", worldName); + data.set("spawns." + name + ".x", spawn.getX()); + data.set("spawns." + name + ".y", spawn.getY()); + data.set("spawns." + name + ".z", spawn.getZ()); + } + + private static String getWorldName(String name, Map map) { + switch (name) { + case "game": return map.getSpawnName(); + case "lobby": return map.getLobbyName(); + case "seeker": return map.getSeekerLobbyName(); + default: return null; + } + } + +} |