summaryrefslogtreewikicommitdiff
path: root/src/main/java/dev/tylerm/khs/configuration
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/dev/tylerm/khs/configuration')
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/Config.java289
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/ConfigManager.java331
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/Items.java220
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/Leaderboard.java51
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/Localization.java80
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/LocalizationString.java37
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/Map.java241
-rw-r--r--src/main/java/dev/tylerm/khs/configuration/Maps.java158
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;
+ }
+ }
+
+}