diff --git a/pom.xml b/pom.xml index 9754f5e..e66540b 100644 --- a/pom.xml +++ b/pom.xml @@ -79,5 +79,10 @@ epicspawners 6-pre4 + + com.gmail.filoghost.holographicdisplays + holographicdisplays-api + 2.3.2 + diff --git a/src/main/java/com/songoda/epicanchors/EpicAnchors.java b/src/main/java/com/songoda/epicanchors/EpicAnchors.java index e8a6a97..3e5a4b4 100644 --- a/src/main/java/com/songoda/epicanchors/EpicAnchors.java +++ b/src/main/java/com/songoda/epicanchors/EpicAnchors.java @@ -3,10 +3,14 @@ package com.songoda.epicanchors; import com.songoda.epicanchors.anchor.Anchor; import com.songoda.epicanchors.anchor.AnchorManager; import com.songoda.epicanchors.command.CommandManager; +import com.songoda.epicanchors.hologram.Hologram; +import com.songoda.epicanchors.hologram.HologramHolographicDisplays; import com.songoda.epicanchors.tasks.AnchorTask; import com.songoda.epicanchors.listeners.BlockListeners; import com.songoda.epicanchors.listeners.InteractListeners; import com.songoda.epicanchors.utils.*; +import com.songoda.epicanchors.utils.settings.Setting; +import com.songoda.epicanchors.utils.settings.SettingsManager; import com.songoda.epicanchors.utils.updateModules.LocaleModule; import com.songoda.update.Plugin; import com.songoda.update.SongodaUpdate; @@ -25,10 +29,10 @@ public class EpicAnchors extends JavaPlugin { public ConfigWrapper dataFile = new ConfigWrapper(this, "", "data.yml"); - private ConfigWrapper hooksFile = new ConfigWrapper(this, "", "hooks.yml"); - private ServerVersion serverVersion = ServerVersion.fromPackageName(Bukkit.getServer().getClass().getPackage().getName()); + private Hologram hologram; + private static EpicAnchors INSTANCE; private SettingsManager settingsManager; @@ -53,11 +57,10 @@ public class EpicAnchors extends JavaPlugin { console.sendMessage(Methods.formatText("&7Action: &aEnabling&7...")); this.settingsManager = new SettingsManager(this); - - setupConfig(); + this.settingsManager.setupConfig(); // Locales - String langMode = SettingsManager.Setting.LANGUGE_MODE.getString(); + String langMode = Setting.LANGUGE_MODE.getString(); Locale.init(this); Locale.saveDefaultLocale("en_US"); this.locale = Locale.getLocale(langMode); @@ -87,6 +90,14 @@ public class EpicAnchors extends JavaPlugin { pluginManager.registerEvents(new BlockListeners(this), this); pluginManager.registerEvents(new InteractListeners(this), this); + // Register Hologram Plugin + if (Setting.HOLOGRAMS.getBoolean() + && pluginManager.isPluginEnabled("HolographicDisplays")) + hologram = new HologramHolographicDisplays(this); + + if (hologram != null) + hologram.loadHolograms(); + // Start Metrics new Metrics(this); @@ -95,7 +106,9 @@ public class EpicAnchors extends JavaPlugin { } public void onDisable() { - saveToFile(); + this.saveToFile(); + if (hologram != null) + this.hologram.unloadHolograms(); CommandSender console = Bukkit.getConsoleSender(); console.sendMessage(Methods.formatText("&a=============================")); console.sendMessage(Methods.formatText("&7EpicAnchors " + this.getDescription().getVersion() + " by &5Brianna <3!")); @@ -103,13 +116,6 @@ public class EpicAnchors extends JavaPlugin { console.sendMessage(Methods.formatText("&a=============================")); } - private void setupConfig() { - settingsManager.updateSettings(); - - getConfig().options().copyDefaults(true); - saveConfig(); - } - private void loadAnchorsFromFile() { if (dataFile.getConfig().contains("Anchors")) { for (String locationStr : dataFile.getConfig().getConfigurationSection("Anchors").getKeys(false)) { @@ -137,8 +143,7 @@ public class EpicAnchors extends JavaPlugin { this.locale.reloadMessages(); this.references = new References(); this.loadAnchorsFromFile(); - this.reloadConfig(); - this.setupConfig(); + this.settingsManager.reloadConfig(); } public int getTicksFromItem(ItemStack item) { @@ -152,9 +157,9 @@ public class EpicAnchors extends JavaPlugin { public ItemStack makAnchorItem(int ticks) { ItemStack item = new ItemStack(Material.valueOf(EpicAnchors.getInstance().getConfig().getString("Main.Anchor Block Material")), 1); ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(Methods.formatText(Methods.formatName(ticks, true))); + meta.setDisplayName(Methods.formatName(ticks, true)); ArrayList lore = new ArrayList<>(); - String[] parts = getConfig().getString("Main.Anchor-Lore").split("\\|"); + String[] parts = Setting.LORE.getString().split("\\|"); for (String line : parts) { lore.add(Methods.formatText(line)); } @@ -187,6 +192,10 @@ public class EpicAnchors extends JavaPlugin { return locale; } + public Hologram getHologram() { + return hologram; + } + public CommandManager getCommandManager() { return commandManager; } diff --git a/src/main/java/com/songoda/epicanchors/anchor/Anchor.java b/src/main/java/com/songoda/epicanchors/anchor/Anchor.java index 3768581..f4e2b11 100644 --- a/src/main/java/com/songoda/epicanchors/anchor/Anchor.java +++ b/src/main/java/com/songoda/epicanchors/anchor/Anchor.java @@ -76,13 +76,35 @@ public class Anchor { location.getWorld().playSound(location, plugin.isServerVersionAtLeast(ServerVersion.V1_9) ? Sound.ENTITY_GENERIC_EXPLODE : Sound.valueOf("EXPLODE"), 10, 10); - plugin.getAnchorManager().removAnchor(location); + if (plugin.getHologram() != null) + plugin.getHologram().remove(this); + plugin.getAnchorManager().removeAnchor(location); } public Location getLocation() { return location.clone(); } + + public int getX() { + return location.getBlockX(); + } + + + public int getY() { + return location.getBlockY(); + } + + + public int getZ() { + return location.getBlockZ(); + } + + + public World getWorld() { + return location.getWorld(); + } + public int getTicksLeft() { return ticksLeft; } diff --git a/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java b/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java index 9d7b24f..a9af901 100644 --- a/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java +++ b/src/main/java/com/songoda/epicanchors/anchor/AnchorManager.java @@ -14,7 +14,7 @@ public class AnchorManager { return registeredAnchors.put(roundLocation(location), anchor); } - public void removAnchor(Location location) { + public void removeAnchor(Location location) { registeredAnchors.remove(roundLocation(location)); } diff --git a/src/main/java/com/songoda/epicanchors/hologram/Hologram.java b/src/main/java/com/songoda/epicanchors/hologram/Hologram.java new file mode 100644 index 0000000..ab54035 --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/hologram/Hologram.java @@ -0,0 +1,60 @@ +package com.songoda.epicanchors.hologram; + +import com.songoda.epicanchors.EpicAnchors; +import com.songoda.epicanchors.anchor.Anchor; +import com.songoda.epicanchors.utils.Methods; +import org.bukkit.Location; + +import java.util.Collection; + +public abstract class Hologram { + + protected final EpicAnchors plugin; + + Hologram(EpicAnchors plugin) { + this.plugin = plugin; + } + + public void loadHolograms() { + Collection anchors = plugin.getAnchorManager().getAnchors().values(); + if (anchors.size() == 0) return; + + for (Anchor anchor : anchors) { + if (anchor.getWorld() == null) continue; + add(anchor); + } + } + + public void unloadHolograms() { + Collection anchors = plugin.getAnchorManager().getAnchors().values(); + if (anchors.size() == 0) return; + + for (Anchor anchor : anchors) { + if (anchor.getWorld() == null) continue; + remove(anchor); + } + } + + public void add(Anchor anchor) { + String name = Methods.formatName(anchor.getTicksLeft(), false).trim(); + + add(anchor.getLocation(), name); + } + + public void remove(Anchor anchor) { + remove(anchor.getLocation()); + } + + public void update(Anchor anchor) { + String name = Methods.formatName(anchor.getTicksLeft(), false).trim(); + + update(anchor.getLocation(), name); + } + + protected abstract void add(Location location, String line); + + protected abstract void remove(Location location); + + protected abstract void update(Location location, String line); + +} diff --git a/src/main/java/com/songoda/epicanchors/hologram/HologramHolographicDisplays.java b/src/main/java/com/songoda/epicanchors/hologram/HologramHolographicDisplays.java new file mode 100644 index 0000000..8af3991 --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/hologram/HologramHolographicDisplays.java @@ -0,0 +1,48 @@ +package com.songoda.epicanchors.hologram; + +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.songoda.epicanchors.EpicAnchors; +import org.bukkit.Location; + + +public class HologramHolographicDisplays extends Hologram { + + public HologramHolographicDisplays(EpicAnchors plugin) { + super(plugin); + } + + @Override + public void add(Location location, String line) { + fixLocation(location); + com.gmail.filoghost.holographicdisplays.api.Hologram hologram = HologramsAPI.createHologram(plugin, location); + hologram.appendTextLine(line); + } + + @Override + public void remove(Location location) { + fixLocation(location); + for (com.gmail.filoghost.holographicdisplays.api.Hologram hologram : HologramsAPI.getHolograms(plugin)) { + if (hologram.getX() != location.getX() + || hologram.getY() != location.getY() + || hologram.getZ() != location.getZ()) continue; + hologram.delete(); + } + } + + @Override + public void update(Location location, String line) { + fixLocation(location); + for (com.gmail.filoghost.holographicdisplays.api.Hologram hologram : HologramsAPI.getHolograms(plugin)) { + if (hologram.getX() != location.getX() + || hologram.getY() != location.getY() + || hologram.getZ() != location.getZ()) continue; + if (hologram.getLine(0).toString().equals("CraftTextLine [text=" + line + "]")) continue; + hologram.clearLines(); + hologram.appendTextLine(line); + } + } + + private void fixLocation(Location location) { + location.add(0.5, 1.52, 0.5); + } +} diff --git a/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java b/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java index da30a5d..4b3ca62 100644 --- a/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java +++ b/src/main/java/com/songoda/epicanchors/listeners/BlockListeners.java @@ -10,10 +10,10 @@ import org.bukkit.inventory.ItemStack; public class BlockListeners implements Listener { - private EpicAnchors instance; + private EpicAnchors plugin; public BlockListeners(EpicAnchors instance) { - this.instance = instance; + this.plugin = instance; } @EventHandler(ignoreCancelled = true) @@ -23,15 +23,19 @@ public class BlockListeners implements Listener { if (!item.hasItemMeta() || !item.getItemMeta().hasDisplayName() - || instance.getTicksFromItem(item) == 0) return; + || plugin.getTicksFromItem(item) == 0) return; - instance.getAnchorManager().addAnchor(event.getBlock().getLocation(), new Anchor(event.getBlock().getLocation(), instance.getTicksFromItem(item))); + Anchor anchor = new Anchor(event.getBlock().getLocation(), plugin.getTicksFromItem(item)); + plugin.getAnchorManager().addAnchor(event.getBlock().getLocation(), anchor); + + if (plugin.getHologram() != null) + plugin.getHologram().add(anchor); } @EventHandler public void onPortalCreation(EntityCreatePortalEvent e) { if (e.getBlocks().size() < 1) return; - if (instance.getAnchorManager().isAnchor(e.getBlocks().get(0).getLocation())) e.setCancelled(true); + if (plugin.getAnchorManager().isAnchor(e.getBlocks().get(0).getLocation())) e.setCancelled(true); } } diff --git a/src/main/java/com/songoda/epicanchors/tasks/AnchorTask.java b/src/main/java/com/songoda/epicanchors/tasks/AnchorTask.java index 75b35b2..f25aacd 100644 --- a/src/main/java/com/songoda/epicanchors/tasks/AnchorTask.java +++ b/src/main/java/com/songoda/epicanchors/tasks/AnchorTask.java @@ -34,7 +34,7 @@ public class AnchorTask extends BukkitRunnable { public AnchorTask(EpicAnchors plug) { plugin = plug; epicSpawners = Bukkit.getPluginManager().getPlugin("EpicSpawners") != null; - + try { String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23); clazzMinecraftServer = Class.forName("net.minecraft.server." + ver + ".MinecraftServer"); @@ -68,14 +68,9 @@ public class AnchorTask extends BukkitRunnable { for (Anchor anchor : plugin.getAnchorManager().getAnchors().values()) { Location location1 = anchor.getLocation().add(.5, .5, .5); if (location1.getWorld() == null) continue; - float xx = (float) (0 + (Math.random() * .15)); + float xx = (float) (0 + (Math.random() * .75)); float yy = (float) (0 + (Math.random() * 1)); - float zz = (float) (0 + (Math.random() * .15)); - location1.getWorld().spawnParticle(Particle.SPELL, location1, 5, xx, yy, zz, 5); - - xx = (float) (0 + (Math.random() * .75)); - yy = (float) (0 + (Math.random() * 1)); - zz = (float) (0 + (Math.random() * .75)); + float zz = (float) (0 + (Math.random() * .75)); if (!plugin.isServerVersionAtLeast(ServerVersion.V1_13)) location1.getWorld().spawnParticle(Particle.REDSTONE, location1, 5, xx, yy, zz, 1); else @@ -91,6 +86,9 @@ public class AnchorTask extends BukkitRunnable { if (anchor.getLocation() == null) continue; + if (plugin.getHologram() != null) + plugin.getHologram().update(anchor); + Location location = anchor.getLocation(); if (anchor.getLocation().getBlock().getType() != Material.valueOf(plugin.getConfig().getString("Main.Anchor Block Material"))) @@ -122,7 +120,7 @@ public class AnchorTask extends BukkitRunnable { anchor.setTicksLeft(ticksLeft - 3); if (ticksLeft <= 0) { - plugin.getAnchorManager().removAnchor(location); + plugin.getAnchorManager().removeAnchor(location); if (plugin.isServerVersionAtLeast(ServerVersion.V1_9)) location.getWorld().spawnParticle(Particle.LAVA, location.clone().add(.5, .5, .5), 5, 0, 0, 0, 5); location.getWorld().playSound(location, plugin.isServerVersionAtLeast(ServerVersion.V1_13) diff --git a/src/main/java/com/songoda/epicanchors/utils/Methods.java b/src/main/java/com/songoda/epicanchors/utils/Methods.java index 723b39a..c36dad2 100644 --- a/src/main/java/com/songoda/epicanchors/utils/Methods.java +++ b/src/main/java/com/songoda/epicanchors/utils/Methods.java @@ -1,6 +1,7 @@ package com.songoda.epicanchors.utils; import com.songoda.epicanchors.EpicAnchors; +import com.songoda.epicanchors.utils.settings.Setting; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -23,27 +24,24 @@ public class Methods { private static Map serializeCache = new HashMap<>(); - public static void takeItem(Player p, int amt) { - if (p.getGameMode() != GameMode.CREATIVE) { - int result = p.getInventory().getItemInHand().getAmount() - amt; + public static void takeItem(Player player, int amt) { + if (player.getGameMode() != GameMode.CREATIVE) { + int result = player.getInventory().getItemInHand().getAmount() - amt; if (result > 0) { - ItemStack is = p.getItemInHand(); + ItemStack is = player.getItemInHand(); is.setAmount(is.getAmount() - amt); - p.setItemInHand(is); + player.setItemInHand(is); } else { - p.setItemInHand(null); + player.setItemInHand(null); } } } public static String formatName(int ticks2, boolean full) { - int hours = ((ticks2 / 20) / 60) / 60; - int minutes = ((ticks2 / 20) / 60) - hours * 60; - String remaining = minutes == 0 ? String.format("%sh", hours) : String.format("%sh %sm", hours, minutes); + String remaining = Methods.makeReadable((ticks2 / 20L) * 1000L); - - String name = EpicAnchors.getInstance().getConfig().getString("Main.Name-Tag").replace("{REMAINING}", remaining); + String name = Setting.NAMETAG.getString().replace("{REMAINING}", remaining); String info = ""; if (full) { @@ -158,16 +156,56 @@ public class Methods { return location; } - /** - * Makes the specified Unix Epoch time human readable as per the format settings in the Arconix config. - * - * @param time The time to convert. - * @return A human readable string representing to specified time. - */ public static String makeReadable(Long time) { if (time == null) return ""; - return String.format("%d hour(s), %d min(s), %d sec(s)", TimeUnit.MILLISECONDS.toHours(time), TimeUnit.MILLISECONDS.toMinutes(time) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time)), TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))); + + StringBuilder sb = new StringBuilder(); + + long days = TimeUnit.MILLISECONDS.toDays(time); + long hours = TimeUnit.MILLISECONDS.toHours(time) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(time)); + long minutes = TimeUnit.MILLISECONDS.toMinutes(time) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time)); + long seconds = TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)); + + if (days != 0L) + sb.append(" ").append(days).append("d"); + if (hours != 0L) + sb.append(" ").append(hours).append("h"); + if (minutes != 0L) + sb.append(" ").append(minutes).append("m"); + if (seconds != 0L) + sb.append(" ").append(seconds).append("s"); + return sb.toString().trim(); + } + + + public static long parseTime(String input) { + long result = 0; + StringBuilder number = new StringBuilder(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (Character.isDigit(c)) { + number.append(c); + } else if (Character.isLetter(c) && (number.length() > 0)) { + result += convert(Integer.parseInt(number.toString()), c); + number = new StringBuilder(); + } + } + return result; + } + + private static long convert(long value, char unit) { + switch (unit) { + case 'd': + return value * 1000 * 60 * 60 * 24; + case 'h': + return value * 1000 * 60 * 60; + case 'm': + return value * 1000 * 60; + case 's': + return value * 1000; + } + return 0; } /** diff --git a/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java b/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java deleted file mode 100644 index 64f2ff9..0000000 --- a/src/main/java/com/songoda/epicanchors/utils/SettingsManager.java +++ /dev/null @@ -1,222 +0,0 @@ -package com.songoda.epicanchors.utils; - -import com.songoda.epicanchors.EpicAnchors; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.player.AsyncPlayerChatEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -/** - * Created by songo on 6/4/2017. - */ -public class SettingsManager implements Listener { - - private static final Pattern SETTINGS_PATTERN = Pattern.compile("(.{1,28}(?:\\s|$))|(.{0,28})", Pattern.DOTALL); - private final EpicAnchors instance; - private String pluginName = "EpicAnchors"; - private Map cat = new HashMap<>(); - private Map current = new HashMap<>(); - - public SettingsManager(EpicAnchors plugin) { - this.instance = plugin; - Bukkit.getPluginManager().registerEvents(this, plugin); - } - - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - ItemStack clickedItem = event.getCurrentItem(); - - if (event.getInventory() != event.getWhoClicked().getOpenInventory().getTopInventory() - || clickedItem == null || !clickedItem.hasItemMeta() - || !clickedItem.getItemMeta().hasDisplayName()) { - return; - } - - if (event.getView().getTitle().equals(pluginName + " Settings Manager")) { - event.setCancelled(true); - if (clickedItem.getType().name().contains("STAINED_GLASS")) return; - - String type = ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName()); - this.cat.put((Player) event.getWhoClicked(), type); - this.openEditor((Player) event.getWhoClicked()); - } else if (event.getView().getTitle().equals(pluginName + " Settings Editor")) { - event.setCancelled(true); - if (clickedItem.getType().name().contains("STAINED_GLASS")) return; - - Player player = (Player) event.getWhoClicked(); - - String key = cat.get(player) + "." + ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName()); - - if (instance.getConfig().get(key).getClass().getName().equals("java.lang.Boolean")) { - this.instance.getConfig().set(key, !instance.getConfig().getBoolean(key)); - this.finishEditing(player); - } else { - this.editObject(player, key); - } - } - } - - @EventHandler - public void onChat(AsyncPlayerChatEvent event) { - Player player = event.getPlayer(); - if (!current.containsKey(player)) return; - - String value = current.get(player); - FileConfiguration config = instance.getConfig(); - if (config.isInt(value)) { - config.set(value, Integer.parseInt(event.getMessage())); - } else if (config.isDouble(value)) { - config.set(value, Double.parseDouble(event.getMessage())); - } else if (config.isString(value)) { - config.set(value, event.getMessage()); - } - - Bukkit.getScheduler().scheduleSyncDelayedTask(EpicAnchors.getInstance(), () -> - this.finishEditing(player), 0L); - - event.setCancelled(true); - } - - private void finishEditing(Player player) { - this.current.remove(player); - this.instance.saveConfig(); - this.openEditor(player); - } - - private void editObject(Player player, String current) { - this.current.put(player, ChatColor.stripColor(current)); - - player.closeInventory(); - player.sendMessage(""); - player.sendMessage(Methods.formatText("&7Please enter a value for &6" + current + "&7.")); - if (instance.getConfig().isInt(current) || instance.getConfig().isDouble(current)) { - player.sendMessage(Methods.formatText("&cUse only numbers.")); - } - player.sendMessage(""); - } - - public void openSettingsManager(Player player) { - Inventory inventory = Bukkit.createInventory(null, 27, pluginName + " Settings Manager"); - ItemStack glass = Methods.getGlass(); - for (int i = 0; i < inventory.getSize(); i++) { - inventory.setItem(i, glass); - } - - int slot = 10; - for (String key : instance.getConfig().getDefaultSection().getKeys(false)) { - ItemStack item = new ItemStack(instance.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.WHITE_WOOL : Material.valueOf("WOOL"), 1, (byte) (slot - 9)); //ToDo: Make this function as it was meant to. - ItemMeta meta = item.getItemMeta(); - meta.setLore(Collections.singletonList(Methods.formatText("&6Click To Edit This Category."))); - meta.setDisplayName(Methods.formatText("&f&l" + key)); - item.setItemMeta(meta); - inventory.setItem(slot, item); - slot++; - } - - player.openInventory(inventory); - } - - private void openEditor(Player player) { - Inventory inventory = Bukkit.createInventory(null, 54, pluginName + " Settings Editor"); - FileConfiguration config = instance.getConfig(); - - int slot = 0; - for (String key : config.getConfigurationSection(cat.get(player)).getKeys(true)) { - String fKey = cat.get(player) + "." + key; - ItemStack item = new ItemStack(Material.DIAMOND_HELMET); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(Methods.formatText("&6" + key)); - - List lore = new ArrayList<>(); - if (config.isBoolean(fKey)) { - item.setType(Material.LEVER); - lore.add(Methods.formatText(config.getBoolean(fKey) ? "&atrue" : "&cfalse")); - } else if (config.isString(fKey)) { - item.setType(Material.PAPER); - lore.add(Methods.formatText("&9" + config.getString(fKey))); - } else if (config.isInt(fKey)) { - item.setType(instance.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH")); - lore.add(Methods.formatText("&5" + config.getInt(fKey))); - } - - meta.setLore(lore); - item.setItemMeta(meta); - - inventory.setItem(slot, item); - slot++; - } - - player.openInventory(inventory); - } - - public void updateSettings() { - FileConfiguration config = instance.getConfig(); - - for (Setting setting : Setting.values()) { - config.addDefault(setting.setting, setting.option); - } - } - - public enum Setting { - o1("Main.Name-Tag", "&Anchor &8(&7{REMAINING}&8)"), - o2("Main.Anchor-Lore", "&7Place down to keep that chunk|&7loaded until the time runs out."), - o3("Main.Anchor Block Material", EpicAnchors.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "END_PORTAL_FRAME" : "ENDER_PORTAL_FRAME"), - o4("Main.Add Time With Economy", true), - o5("Main.Economy Cost", 5000.0), - o6("Main.Add Time With XP", true), - o7("Main.XP Cost", 10), - o8("Main.Allow Anchor Breaking", false), - o9("Interfaces.Economy Icon", EpicAnchors.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "SUNFLOWER" : "GOLD_INGOT"), - o10("Interfaces.XP Icon", EpicAnchors.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "EXPERIENCE_BOTTLE" : "EXP_BOTTLE"), - o11("Interfaces.Glass Type 1", 7), - o12("Interfaces.Glass Type 2", 11), - o13("Interfaces.Glass Type 3", 3), - - LANGUGE_MODE("System.Language Mode", "en_US"); - - private String setting; - private Object option; - - Setting(String setting, Object option) { - this.setting = setting; - this.option = option; - } - - public List getStringList() { - return EpicAnchors.getInstance().getConfig().getStringList(setting); - } - - public boolean getBoolean() { - return EpicAnchors.getInstance().getConfig().getBoolean(setting); - } - - public int getInt() { - return EpicAnchors.getInstance().getConfig().getInt(setting); - } - - public String getString() { - return EpicAnchors.getInstance().getConfig().getString(setting); - } - - public char getChar() { - return EpicAnchors.getInstance().getConfig().getString(setting).charAt(0); - } - - - } -} \ No newline at end of file diff --git a/src/main/java/com/songoda/epicanchors/utils/settings/Category.java b/src/main/java/com/songoda/epicanchors/utils/settings/Category.java new file mode 100644 index 0000000..94aac5f --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/utils/settings/Category.java @@ -0,0 +1,21 @@ +package com.songoda.epicanchors.utils.settings; + +public enum Category { + + MAIN("General settings and options."), + INTERFACES("These settings allow you to alter the way interfaces look.", + "They are used in GUI's to make patterns, change them up then open up a", + "GUI to see how it works."), + SYSTEM("System related settings."); + + private String[] comments; + + + Category(String... comments) { + this.comments = comments; + } + + public String[] getComments() { + return comments; + } +} \ No newline at end of file diff --git a/src/main/java/com/songoda/epicanchors/utils/settings/Setting.java b/src/main/java/com/songoda/epicanchors/utils/settings/Setting.java new file mode 100644 index 0000000..6070583 --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/utils/settings/Setting.java @@ -0,0 +1,106 @@ +package com.songoda.epicanchors.utils.settings; + +import com.songoda.epicanchors.EpicAnchors; +import com.songoda.epicanchors.utils.ServerVersion; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public enum Setting { + + NAMETAG("Main.Name Tag", "&6Anchor &8(&7{REMAINING}&8)"), + + LORE("Main.Anchor Lore", "&7Place down to keep that chunk|&7loaded until the time runs out."), + + MATERIAL("Main.Anchor Block Material", EpicAnchors.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "END_PORTAL_FRAME" : "ENDER_PORTAL_FRAME"), + + ADD_TIME_WITH_ECONOMY("Main.Add Time With Economy", true), + + ECONOMY_COST("Main.Economy Cost", 5000.0), + + ADD_TIME_WITH_XP("Main.Add Time With XP", true), + + XP_COST("Main.XP Cost", 10), + + ALLOW_ANCHOR_BREAKING("Main.Allow Anchor Breaking", false), + + HOLOGRAMS("Main.Holograms", true, + "Toggle holograms showing above anchors."), + + ECO_ICON("Interfaces.Economy Icon", EpicAnchors.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "SUNFLOWER" : "DOUBLE_PLANT", + "Item to be displayed as the icon for economy upgrades."), + + XP_ICON("Interfaces.XP Icon", EpicAnchors.getInstance().isServerVersionAtLeast(ServerVersion.V1_13) ? "EXPERIENCE_BOTTLE" : "EXP_BOTTLE", + "Item to be displayed as the icon for XP upgrades."), + + GLASS_TYPE_1("Interfaces.Glass Type 1", 7), + GLASS_TYPE_2("Interfaces.Glass Type 2", 11), + GLASS_TYPE_3("Interfaces.Glass Type 3", 3), + + LANGUGE_MODE("System.Language Mode", "en_US", + "The enabled language file.", + "More language files (if available) can be found in the plugins data folder."); + + private String setting; + private Object option; + private String[] comments; + + Setting(String setting, Object option, String... comments) { + this.setting = setting; + this.option = option; + this.comments = comments; + } + + Setting(String setting, Object option) { + this.setting = setting; + this.option = option; + this.comments = null; + } + + public static com.songoda.epicanchors.utils.settings.Setting getSetting(String setting) { + List settings = Arrays.stream(values()).filter(setting1 -> setting1.setting.equals(setting)).collect(Collectors.toList()); + if (settings.isEmpty()) return null; + return settings.get(0); + } + + public String getSetting() { + return setting; + } + + public Object getOption() { + return option; + } + + public String[] getComments() { + return comments; + } + + public List getStringList() { + return EpicAnchors.getInstance().getConfig().getStringList(setting); + } + + public boolean getBoolean() { + return EpicAnchors.getInstance().getConfig().getBoolean(setting); + } + + public int getInt() { + return EpicAnchors.getInstance().getConfig().getInt(setting); + } + + public long getLong() { + return EpicAnchors.getInstance().getConfig().getLong(setting); + } + + public String getString() { + return EpicAnchors.getInstance().getConfig().getString(setting); + } + + public char getChar() { + return EpicAnchors.getInstance().getConfig().getString(setting).charAt(0); + } + + public double getDouble() { + return EpicAnchors.getInstance().getConfig().getDouble(setting); + } +} \ No newline at end of file diff --git a/src/main/java/com/songoda/epicanchors/utils/settings/SettingsManager.java b/src/main/java/com/songoda/epicanchors/utils/settings/SettingsManager.java new file mode 100644 index 0000000..68a00ef --- /dev/null +++ b/src/main/java/com/songoda/epicanchors/utils/settings/SettingsManager.java @@ -0,0 +1,311 @@ +package com.songoda.epicanchors.utils.settings; + +import com.songoda.epicanchors.EpicAnchors; +import com.songoda.epicanchors.utils.Methods; +import com.songoda.epicanchors.utils.ServerVersion; +import com.songoda.epicanchors.utils.settings.Category; +import com.songoda.epicanchors.utils.settings.Setting; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.*; +import java.util.*; + +/** + * Created by songoda on 6/4/2017. + */ +public class SettingsManager implements Listener { + + private final EpicAnchors plugin; + private Map cat = new HashMap<>(); + private Map current = new HashMap<>(); + + public SettingsManager(EpicAnchors plugin) { + this.plugin = plugin; + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + ItemStack clickedItem = event.getCurrentItem(); + + if (event.getInventory() != event.getWhoClicked().getOpenInventory().getTopInventory() + || clickedItem == null || !clickedItem.hasItemMeta() + || !clickedItem.getItemMeta().hasDisplayName()) { + return; + } + + if (event.getView().getTitle().equals(plugin.getName() + " Settings Manager")) { + event.setCancelled(true); + if (clickedItem.getType().name().contains("STAINED_GLASS")) return; + + String type = ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName()); + this.cat.put((Player) event.getWhoClicked(), type); + this.openEditor((Player) event.getWhoClicked()); + } else if (event.getView().getTitle().equals(plugin.getName() + " Settings Editor")) { + event.setCancelled(true); + if (clickedItem.getType().name().contains("STAINED_GLASS")) return; + + Player player = (Player) event.getWhoClicked(); + + String key = cat.get(player) + "." + ChatColor.stripColor(clickedItem.getItemMeta().getDisplayName()); + + if (plugin.getConfig().get(key).getClass().getName().equals("java.lang.Boolean")) { + this.plugin.getConfig().set(key, !plugin.getConfig().getBoolean(key)); + this.finishEditing(player); + } else { + this.editObject(player, key); + } + } + } + + @EventHandler + public void onChat(AsyncPlayerChatEvent event) { + Player player = event.getPlayer(); + if (!current.containsKey(player)) return; + + String value = current.get(player); + FileConfiguration config = plugin.getConfig(); + if (config.isLong(value)) { + config.set(value, Long.parseLong(event.getMessage())); + } else if (config.isInt(value)) { + config.set(value, Integer.parseInt(event.getMessage())); + } else if (config.isDouble(value)) { + config.set(value, Double.parseDouble(event.getMessage())); + } else if (config.isString(value)) { + config.set(value, event.getMessage()); + } + + Bukkit.getScheduler().scheduleSyncDelayedTask(EpicAnchors.getInstance(), () -> + this.finishEditing(player), 0L); + + event.setCancelled(true); + } + + private void finishEditing(Player player) { + this.current.remove(player); + this.saveConfig(); + this.openEditor(player); + } + + private void editObject(Player player, String current) { + this.current.put(player, ChatColor.stripColor(current)); + + player.closeInventory(); + player.sendMessage(""); + player.sendMessage(Methods.formatText("&7Please enter a value for &6" + current + "&7.")); + if (plugin.getConfig().isInt(current) || plugin.getConfig().isDouble(current)) { + player.sendMessage(Methods.formatText("&cUse only numbers.")); + } + player.sendMessage(""); + } + + public void openSettingsManager(Player player) { + Inventory inventory = Bukkit.createInventory(null, 27, plugin.getName() + " Settings Manager"); + ItemStack glass = Methods.getGlass(); + for (int i = 0; i < inventory.getSize(); i++) { + inventory.setItem(i, glass); + } + + int slot = 10; + for (String key : plugin.getConfig().getDefaultSection().getKeys(false)) { + ItemStack item = new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.LEGACY_WOOL : Material.valueOf("WOOL"), 1, (byte) (slot - 9)); + ItemMeta meta = item.getItemMeta(); + meta.setLore(Collections.singletonList(Methods.formatText("&6Click To Edit This Category."))); + meta.setDisplayName(Methods.formatText("&f&l" + key)); + item.setItemMeta(meta); + inventory.setItem(slot, item); + slot++; + } + + player.openInventory(inventory); + } + + private void openEditor(Player player) { + Inventory inventory = Bukkit.createInventory(null, 54, plugin.getName() + " Settings Editor"); + FileConfiguration config = plugin.getConfig(); + + int slot = 0; + for (String key : config.getConfigurationSection(cat.get(player)).getKeys(true)) { + String fKey = cat.get(player) + "." + key; + ItemStack item = new ItemStack(Material.DIAMOND_HELMET); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(Methods.formatText("&6" + key)); + + List lore = new ArrayList<>(); + if (config.isBoolean(fKey)) { + item.setType(Material.LEVER); + lore.add(Methods.formatText(config.getBoolean(fKey) ? "&atrue" : "&cfalse")); + } else if (config.isString(fKey)) { + item.setType(Material.PAPER); + lore.add(Methods.formatText("&7" + config.getString(fKey))); + } else if (config.isInt(fKey)) { + item.setType(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH")); + lore.add(Methods.formatText("&7" + config.getInt(fKey))); + } else if (config.isLong(fKey)) { + item.setType(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH")); + lore.add(Methods.formatText("&7" + config.getLong(fKey))); + } else if (config.isDouble(fKey)) { + item.setType(plugin.isServerVersionAtLeast(ServerVersion.V1_13) ? Material.CLOCK : Material.valueOf("WATCH")); + lore.add(Methods.formatText("&7" + config.getDouble(fKey))); + } + + Setting setting = Setting.getSetting(fKey); + + if (setting != null && setting.getComments() != null) { + lore.add(""); + + String comment = String.join(" ", setting.getComments()); + + int lastIndex = 0; + for (int n = 0; n < comment.length(); n++) { + if (n - lastIndex < 30) + continue; + + if (comment.charAt(n) == ' ') { + lore.add(Methods.formatText("&8" + comment.substring(lastIndex, n).trim())); + lastIndex = n; + } + } + + if (lastIndex - comment.length() < 30) + lore.add(Methods.formatText("&8" + comment.substring(lastIndex).trim())); + + } + + meta.setLore(lore); + item.setItemMeta(meta); + + inventory.setItem(slot, item); + slot++; + } + + player.openInventory(inventory); + } + + public void reloadConfig() { + plugin.reloadConfig(); + this.setupConfig(); + } + + public void setupConfig() { + FileConfiguration config = plugin.getConfig(); + + for (Setting setting : Setting.values()) { + config.addDefault(setting.getSetting(), setting.getOption()); + } + plugin.getConfig().options().copyDefaults(true); + saveConfig(); + } + + private void saveConfig() { + String dump = plugin.getConfig().saveToString(); + + StringBuilder config = new StringBuilder(); + + BufferedReader bufReader = new BufferedReader(new StringReader(dump)); + + try { + boolean first = true; + + String line; + int currentTab = 0; + String category = ""; + + while ((line = bufReader.readLine()) != null) { + if (line.trim().startsWith("#")) continue; + + int tabChange = line.length() - line.trim().length(); + if (currentTab != tabChange) { + category = category.contains(".") && tabChange != 0 ? category.substring(0, category.indexOf(".")) : ""; + currentTab = tabChange; + } + + if (line.endsWith(":")) { + bufReader.mark(1000); + String found = bufReader.readLine(); + bufReader.reset(); + + if (!found.trim().startsWith("-")) { + + String newCategory = line.substring(0, line.length() - 1).trim(); + + if (category.equals("")) + category = newCategory; + else + category += "." + newCategory; + + currentTab = tabChange + 2; + + if (!first) { + config.append("\n\n"); + } else { + first = false; + } + + if (!category.contains(".")) + config.append("#").append("\n"); + try { + Category categoryObj = Category.valueOf(category.toUpperCase() + .replace(" ", "_") + .replace(".", "_")); + + config.append(new String(new char[tabChange]).replace('\0', ' ')); + for (String l : categoryObj.getComments()) + config.append("# ").append(l).append("\n"); + } catch (IllegalArgumentException e) { + config.append("# ").append(category).append("\n"); + } + if (!category.contains(".")) + config.append("#").append("\n"); + + config.append(line).append("\n"); + + continue; + } + } + + if (line.trim().startsWith("-")) { + config.append(line).append("\n"); + continue; + } + + String key = category + "." + (line.split(":")[0].trim()); + for (Setting setting : Setting.values()) { + if (!setting.getSetting().equals(key) || setting.getComments() == null) continue; + config.append(" ").append("\n"); + for (String l : setting.getComments()) { + config.append(new String(new char[currentTab]).replace('\0', ' ')); + config.append("# ").append(l).append("\n"); + } + } + config.append(line).append("\n"); + } + } catch (IOException e) { + e.printStackTrace(); + } + + try { + if (!plugin.getDataFolder().exists()) + plugin.getDataFolder().mkdir(); + BufferedWriter writer = + new BufferedWriter(new FileWriter(new File(plugin.getDataFolder() + File.separator + "config.yml"))); + writer.write(config.toString()); + writer.flush(); + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file