From 124e37d56da05c9977606bbcec7b50c030f565a2 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Thu, 2 Jul 2020 09:01:54 +1000 Subject: [PATCH] Initial commit --- Command Panels.iml | 18 + resource/example.yml | 121 ++ resource/plugin.yml | 63 + src/me/rockyhawk/commandPanels/Metrics.java | 718 ++++++++ src/me/rockyhawk/commandPanels/Updater.java | 773 ++++++++ .../commandPanels/commandpanels.java | 1557 +++++++++++++++++ .../commandPanels/commands/commandpanel.java | 578 ++++++ .../commands/commandpanelclose.java | 32 + .../commands/commandpanelcustom.java | 82 + .../commands/commandpanelsdebug.java | 39 + .../commands/commandpanelslist.java | 94 + .../commands/commandpanelsreload.java | 35 + .../commands/commandpanelversion.java | 34 + .../completeTabs/cpTabComplete.java | 59 + .../generatePanels/commandpanelsgenerate.java | 53 + .../generatePanels/newGenUtils.java | 126 ++ .../generatePanels/tabCompleteGenerate.java | 34 + .../ingameEditor/cpIngameEditCommand.java | 199 +++ .../ingameEditor/cpTabCompleteIngame.java | 59 + .../ingameEditor/editorUserInput.java | 402 +++++ .../ingameEditor/editorUtils.java | 648 +++++++ .../premium/commandpanelUserInput.java | 42 + .../premium/commandpanelrefresher.java | 174 ++ src/me/rockyhawk/commandPanels/utils.java | 689 ++++++++ 24 files changed, 6629 insertions(+) create mode 100644 Command Panels.iml create mode 100644 resource/example.yml create mode 100644 resource/plugin.yml create mode 100644 src/me/rockyhawk/commandPanels/Metrics.java create mode 100644 src/me/rockyhawk/commandPanels/Updater.java create mode 100644 src/me/rockyhawk/commandPanels/commandpanels.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanel.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanelclose.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanelcustom.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanelsdebug.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanelslist.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanelsreload.java create mode 100644 src/me/rockyhawk/commandPanels/commands/commandpanelversion.java create mode 100644 src/me/rockyhawk/commandPanels/completeTabs/cpTabComplete.java create mode 100644 src/me/rockyhawk/commandPanels/generatePanels/commandpanelsgenerate.java create mode 100644 src/me/rockyhawk/commandPanels/generatePanels/newGenUtils.java create mode 100644 src/me/rockyhawk/commandPanels/generatePanels/tabCompleteGenerate.java create mode 100644 src/me/rockyhawk/commandPanels/ingameEditor/cpIngameEditCommand.java create mode 100644 src/me/rockyhawk/commandPanels/ingameEditor/cpTabCompleteIngame.java create mode 100644 src/me/rockyhawk/commandPanels/ingameEditor/editorUserInput.java create mode 100644 src/me/rockyhawk/commandPanels/ingameEditor/editorUtils.java create mode 100644 src/me/rockyhawk/commandPanels/premium/commandpanelUserInput.java create mode 100644 src/me/rockyhawk/commandPanels/premium/commandpanelrefresher.java create mode 100644 src/me/rockyhawk/commandPanels/utils.java diff --git a/Command Panels.iml b/Command Panels.iml new file mode 100644 index 0000000..65f5c86 --- /dev/null +++ b/Command Panels.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resource/example.yml b/resource/example.yml new file mode 100644 index 0000000..e37c551 --- /dev/null +++ b/resource/example.yml @@ -0,0 +1,121 @@ +panels: + example: + perm: default + rows: 4 + title: '&6[&bExample Panel&6]&f Welcome!' + command: example + sound-on-open: BLOCK_NOTE_BLOCK_CHIME + empty: BLACK_STAINED_GLASS_PANE + open-with-item: + material: CLOCK + name: '&6[&bExample Panel&6]' + lore: + - '&3Click me to open the panel!' + stationary: 4 + item: + '0': + material: LEATHER_HELMET + name: '&d&lPURPLE' + leatherarmor: PURPLE + '9': + material: LEATHER_CHESTPLATE + name: '&9&lBLUE' + leatherarmor: BLUE + '18': + material: LEATHER_LEGGINGS + name: '&a&lLIME' + leatherarmor: LIME + '2': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGJiMjczN2VjYmY5MTBlZmUzYjI2N2RiN2Q0YjMyN2YzNjBhYmM3MzJjNzdiZDBlNGVmZjFkNTEwY2RlZiJ9fX0= + name: '&e&lE' + '3': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWE2Nzg3YmEzMjU2NGU3YzJmM2EwY2U2NDQ5OGVjYmIyM2I4OTg0NWU1YTY2YjVjZWM3NzM2ZjcyOWVkMzcifX19 + name: '&e&lX' + '4': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTY3ZDgxM2FlN2ZmZTViZTk1MWE0ZjQxZjJhYTYxOWE1ZTM4OTRlODVlYTVkNDk4NmY4NDk0OWM2M2Q3NjcyZSJ9fX0= + name: '&e&lA' + '5': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDljNDVhMjRhYWFiZjQ5ZTIxN2MxNTQ4MzIwNDg0OGE3MzU4MmFiYTdmYWUxMGVlMmM1N2JkYjc2NDgyZiJ9fX0= + name: '&e&lM' + '6': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTBhNzk4OWI1ZDZlNjIxYTEyMWVlZGFlNmY0NzZkMzUxOTNjOTdjMWE3Y2I4ZWNkNDM2MjJhNDg1ZGMyZTkxMiJ9fX0= + name: '&e&lP' + '7': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzE5ZjUwYjQzMmQ4NjhhZTM1OGUxNmY2MmVjMjZmMzU0MzdhZWI5NDkyYmNlMTM1NmM5YWE2YmIxOWEzODYifX19 + name: '&e&lL' + '8': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGJiMjczN2VjYmY5MTBlZmUzYjI2N2RiN2Q0YjMyN2YzNjBhYmM3MzJjNzdiZDBlNGVmZjFkNTEwY2RlZiJ9fX0= + name: '&e&lE' + '13': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTBhNzk4OWI1ZDZlNjIxYTEyMWVlZGFlNmY0NzZkMzUxOTNjOTdjMWE3Y2I4ZWNkNDM2MjJhNDg1ZGMyZTkxMiJ9fX0= + name: '&e&lP' + '14': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTY3ZDgxM2FlN2ZmZTViZTk1MWE0ZjQxZjJhYTYxOWE1ZTM4OTRlODVlYTVkNDk4NmY4NDk0OWM2M2Q3NjcyZSJ9fX0= + name: '&e&lA' + '15': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzViOGIzZDhjNzdkZmI4ZmJkMjQ5NWM4NDJlYWM5NGZmZmE2ZjU5M2JmMTVhMjU3NGQ4NTRkZmYzOTI4In19fQ== + name: '&e&lN' + '16': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGJiMjczN2VjYmY5MTBlZmUzYjI2N2RiN2Q0YjMyN2YzNjBhYmM3MzJjNzdiZDBlNGVmZjFkNTEwY2RlZiJ9fX0= + name: '&e&lE' + '17': + material: cps= eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzE5ZjUwYjQzMmQ4NjhhZTM1OGUxNmY2MmVjMjZmMzU0MzdhZWI5NDkyYmNlMTM1NmM5YWE2YmIxOWEzODYifX19 + name: '&e&lL' + '20': + material: RED_WOOL + name: '&cYour nickname is not ''RockyHawk''' + commands: + - 'msg= &cNot RockyHawk' + hasvalue: + output: true + value: RockyHawk + compare: '%cp-player-name%' + material: LIME_WOOL + name: '&aYour username is ''RockyHawk''' + commands: + - 'msg= &aWelcome my master!' + '27': + material: LEATHER_BOOTS + name: '&e&lYELLOW' + leatherarmor: YELLOW + '32': + material: COMPASS + stack: 12 + enchanted: true + name: '&cClick Me' + lore: + - '&fI will teleport you home!' + commands: + - home + - commandpanels:commandpanelclose + - console= title %cp-player-name% times 20 60 20 + - console= title %cp-player-name% subtitle {"text":"%cp-player-displayname%","color":"green"} + - console= title %cp-player-name% title {"text":"Welcome Home"} + '30': + material: POTION + name: '&5&lInstant Health II' + potion: INSTANT_HEAL + commands: + - heal + - commandpanels:commandpanelclose + '34': + material: REDSTONE_BLOCK + name: '&cNo Permission' + lore: + - '&4You cannot change to' + - '&4creative looking like that!' + hasperm: + perm: essentials.gamemode + output: true + material: EMERALD_BLOCK + name: '&aClick Me' + lore: + - '&2I will change you' + - '&2to creative mode!' + commands: + - gamemode creative + - commandpanels:commandpanelclose + - console= title %cp-player-name% times 20 60 20 + - console= title %cp-player-name% subtitle {"text":"You are now in creative + mode!","color":"green"} + - console= title %cp-player-name% title {"text":"Awesome %cp-player-displayname%"} diff --git a/resource/plugin.yml b/resource/plugin.yml new file mode 100644 index 0000000..9adff47 --- /dev/null +++ b/resource/plugin.yml @@ -0,0 +1,63 @@ +name: CommandPanels +main: me.rockyhawk.commandPanels.commandpanels +author: RockyHawk +version: 3.2.0-pre3 +api-version: 1.13 +description: Fully Custom GUIs. Make your Server Professional. +softdepend: [PlaceholderAPI, Vault, HeadDatabase, TokenManager, VotingPlugin] +commands: + commandpanel: + description: Open a command panel. + usage: /commandpanel [player:item] [player] + aliases: [cp, cpanel] + commandpanelreload: + description: Reloads plugin config. + usage: /commandpanelsreload + aliases: [cpr, cpanelr] + commandpaneldebug: + description: Enable and Disable debug mode globally + usage: /commandpanelsdebug + aliases: [cpd, cpaneld] + commandpanelclose: + description: Close current GUI. + usage: /commandpanelclose + aliases: [cpc, cpanelc] + commandpanelgenerate: + description: Generate GUI. + usage: /commandpanelgenerate + aliases: [cpg, cpanelg] + commandpanelversion: + description: Display the current version. + usage: /commandpanelversion + aliases: [cpv, cpanelv] + commandpaneledit: + description: Edit panels ingame. + usage: /commandpaneledit [panel] + aliases: [cpe, cpanele] + commandpanellist: + description: Lists the currently loaded panels. + usage: /commandpanellist + aliases: [cpl, cpanell] +permissions: + commandpanel.panel.default: + default: true + commandpanel.other: + default: op + commandpanel.panel.*: + default: op + commandpanel.item.*: + default: op + commandpanel.reload: + default: op + commandpanel.debug: + default: op + commandpanel.generate: + default: op + commandpanel.version: + default: true + commandpanel.editor: + default: true + commandpanel.edit: + default: op + commandpanel.list: + default: op \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/Metrics.java b/src/me/rockyhawk/commandPanels/Metrics.java new file mode 100644 index 0000000..c3d1a56 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/Metrics.java @@ -0,0 +1,718 @@ +package me.rockyhawk.commandPanels; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicePriority; + +import javax.net.ssl.HttpsURLConnection; +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.zip.GZIPOutputStream; + +/** + * bStats collects some data for plugin authors. + *

+ * Check out https://bStats.org/ to learn more about bStats! + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public class Metrics { + + static { + // You can use the property to disable the check in your test environment + if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) { + // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D + final String defaultPackage = new String( + new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'}); + final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); + // We want to make sure nobody just copy & pastes the example and use the wrong package names + if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) { + throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); + } + } + } + + // The version of this bStats class + public static final int B_STATS_VERSION = 1; + + // The url to which the data is sent + private static final String URL = "https://bStats.org/submitData/bukkit"; + + // Is bStats enabled on this server? + private boolean enabled; + + // Should failed requests be logged? + private static boolean logFailedRequests; + + // Should the sent data be logged? + private static boolean logSentData; + + // Should the response text be logged? + private static boolean logResponseStatusText; + + // The uuid of the server + private static String serverUUID; + + // The plugin + private final Plugin plugin; + + // A list with all custom charts + private final List charts = new ArrayList<>(); + + /** + * Class constructor. + * + * @param plugin The plugin which stats should be submitted. + */ + public Metrics(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null!"); + } + this.plugin = plugin; + + // Get the config file + File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); + File configFile = new File(bStatsFolder, "config.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + + // Check if the config file exists + if (!config.isSet("serverUuid")) { + + // Add default values + config.addDefault("enabled", true); + // Every server gets it's unique random id. + config.addDefault("serverUuid", UUID.randomUUID().toString()); + // Should failed request be logged? + config.addDefault("logFailedRequests", false); + // Should the sent data be logged? + config.addDefault("logSentData", false); + // Should the response text be logged? + config.addDefault("logResponseStatusText", false); + + // Inform the server owners about bStats + config.options().header( + "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)" + ).copyDefaults(true); + try { + config.save(configFile); + } catch (IOException ignored) { } + } + + // Load the data + enabled = config.getBoolean("enabled", true); + serverUUID = config.getString("serverUuid"); + logFailedRequests = config.getBoolean("logFailedRequests", false); + logSentData = config.getBoolean("logSentData", false); + logResponseStatusText = config.getBoolean("logResponseStatusText", false); + + if (enabled) { + boolean found = false; + // Search for all other bStats Metrics classes to see if we are the first one + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + found = true; // We aren't the first + break; + } catch (NoSuchFieldException ignored) { } + } + // Register our service + Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); + if (!found) { + // We are the first! + startSubmitting(); + } + } + } + + /** + * Checks if bStats is enabled. + * + * @return Whether bStats is enabled or not. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Adds a custom chart. + * + * @param chart The chart to add. + */ + public void addCustomChart(CustomChart chart) { + if (chart == null) { + throw new IllegalArgumentException("Chart cannot be null!"); + } + charts.add(chart); + } + + /** + * Starts the Scheduler which submits our data every 30 minutes. + */ + private void startSubmitting() { + final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + if (!plugin.isEnabled()) { // Plugin was disabled + timer.cancel(); + return; + } + // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler + // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) + Bukkit.getScheduler().runTask(plugin, () -> submitData()); + } + }, 1000 * 60 * 5, 1000 * 60 * 30); + // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start + // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! + // WARNING: Just don't do it! + } + + /** + * Gets the plugin specific data. + * This method is called using Reflection. + * + * @return The plugin specific data. + */ + public JsonObject getPluginData() { + JsonObject data = new JsonObject(); + + String pluginName = plugin.getDescription().getName(); + String pluginVersion = plugin.getDescription().getVersion(); + + data.addProperty("pluginName", pluginName); // Append the name of the plugin + data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin + JsonArray customCharts = new JsonArray(); + for (CustomChart customChart : charts) { + // Add the data of the custom charts + JsonObject chart = customChart.getRequestJsonObject(); + if (chart == null) { // If the chart is null, we skip it + continue; + } + customCharts.add(chart); + } + data.add("customCharts", customCharts); + + return data; + } + + /** + * Gets the server specific data. + * + * @return The server specific data. + */ + private JsonObject getServerData() { + // Minecraft specific data + int playerAmount; + try { + // Around MC 1.8 the return type was changed to a collection from an array, + // This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; + Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); + playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) + ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() + : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; + } catch (Exception e) { + playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed + } + int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; + String bukkitVersion = Bukkit.getVersion(); + String bukkitName = Bukkit.getName(); + + // OS/Java specific data + String javaVersion = System.getProperty("java.version"); + String osName = System.getProperty("os.name"); + String osArch = System.getProperty("os.arch"); + String osVersion = System.getProperty("os.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + JsonObject data = new JsonObject(); + + data.addProperty("serverUUID", serverUUID); + + data.addProperty("playerAmount", playerAmount); + data.addProperty("onlineMode", onlineMode); + data.addProperty("bukkitVersion", bukkitVersion); + data.addProperty("bukkitName", bukkitName); + + data.addProperty("javaVersion", javaVersion); + data.addProperty("osName", osName); + data.addProperty("osArch", osArch); + data.addProperty("osVersion", osVersion); + data.addProperty("coreCount", coreCount); + + return data; + } + + /** + * Collects the data and sends it afterwards. + */ + private void submitData() { + final JsonObject data = getServerData(); + + JsonArray pluginData = new JsonArray(); + // Search for all other bStats Metrics classes to get their plugin data + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + + for (RegisteredServiceProvider provider : Bukkit.getServicesManager().getRegistrations(service)) { + try { + Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider()); + if (plugin instanceof JsonObject) { + pluginData.add((JsonObject) plugin); + } else { // old bstats version compatibility + try { + Class jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject"); + if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) { + Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString"); + jsonStringGetter.setAccessible(true); + String jsonString = (String) jsonStringGetter.invoke(plugin); + JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject(); + pluginData.add(object); + } + } catch (ClassNotFoundException e) { + // minecraft version 1.14+ + if (logFailedRequests) { + this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e); + } + continue; // continue looping since we cannot do any other thing. + } + } + } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { } + } + } catch (NoSuchFieldException ignored) { } + } + + data.add("plugins", pluginData); + + // Create a new thread for the connection to the bStats server + new Thread(new Runnable() { + @Override + public void run() { + try { + // Send the data + sendData(plugin, data); + } catch (Exception e) { + // Something went wrong! :( + if (logFailedRequests) { + plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); + } + } + } + }).start(); + } + + /** + * Sends the data to the bStats server. + * + * @param plugin Any plugin. It's just used to get a logger instance. + * @param data The data to send. + * @throws Exception If the request failed. + */ + private static void sendData(Plugin plugin, JsonObject data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("Data cannot be null!"); + } + if (Bukkit.isPrimaryThread()) { + throw new IllegalAccessException("This method must not be called from the main thread!"); + } + if (logSentData) { + plugin.getLogger().info("Sending data to bStats: " + data.toString()); + } + HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); + + // Compress the data to save bandwidth + byte[] compressedData = compress(data.toString()); + + // Add headers + connection.setRequestMethod("POST"); + connection.addRequestProperty("Accept", "application/json"); + connection.addRequestProperty("Connection", "close"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request + connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); + connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format + connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); + + // Send data + connection.setDoOutput(true); + DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); + outputStream.write(compressedData); + outputStream.flush(); + outputStream.close(); + + InputStream inputStream = connection.getInputStream(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + StringBuilder builder = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + builder.append(line); + } + bufferedReader.close(); + if (logResponseStatusText) { + plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString()); + } + } + + /** + * Gzips the given String. + * + * @param str The string to gzip. + * @return The gzipped String. + * @throws IOException If the compression failed. + */ + private static byte[] compress(final String str) throws IOException { + if (str == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + GZIPOutputStream gzip = new GZIPOutputStream(outputStream); + gzip.write(str.getBytes(StandardCharsets.UTF_8)); + gzip.close(); + return outputStream.toByteArray(); + } + + /** + * Represents a custom chart. + */ + public static abstract class CustomChart { + + // The id of the chart + final String chartId; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + CustomChart(String chartId) { + if (chartId == null || chartId.isEmpty()) { + throw new IllegalArgumentException("ChartId cannot be null or empty!"); + } + this.chartId = chartId; + } + + private JsonObject getRequestJsonObject() { + JsonObject chart = new JsonObject(); + chart.addProperty("chartId", chartId); + try { + JsonObject data = getChartData(); + if (data == null) { + // If the data is null we don't send the chart. + return null; + } + chart.add("data", data); + } catch (Throwable t) { + if (logFailedRequests) { + Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); + } + return null; + } + return chart; + } + + protected abstract JsonObject getChartData() throws Exception; + + } + + /** + * Represents a custom simple pie. + */ + public static class SimplePie extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimplePie(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + String value = callable.call(); + if (value == null || value.isEmpty()) { + // Null = skip the chart + return null; + } + data.addProperty("value", value); + return data; + } + } + + /** + * Represents a custom advanced pie. + */ + public static class AdvancedPie extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedPie(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.addProperty(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + } + + /** + * Represents a custom drilldown pie. + */ + public static class DrilldownPie extends CustomChart { + + private final Callable>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public DrilldownPie(String chartId, Callable>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + public JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean reallyAllSkipped = true; + for (Map.Entry> entryValues : map.entrySet()) { + JsonObject value = new JsonObject(); + boolean allSkipped = true; + for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { + value.addProperty(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + values.add(entryValues.getKey(), value); + } + } + if (reallyAllSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + } + + /** + * Represents a custom single line chart. + */ + public static class SingleLineChart extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SingleLineChart(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + int value = callable.call(); + if (value == 0) { + // Null = skip the chart + return null; + } + data.addProperty("value", value); + return data; + } + + } + + /** + * Represents a custom multi line chart. + */ + public static class MultiLineChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public MultiLineChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.addProperty(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom simple bar chart. + */ + public static class SimpleBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimpleBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + for (Map.Entry entry : map.entrySet()) { + JsonArray categoryValues = new JsonArray(); + categoryValues.add(entry.getValue()); + values.add(entry.getKey(), categoryValues); + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom advanced bar chart. + */ + public static class AdvancedBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().length == 0) { + continue; // Skip this invalid + } + allSkipped = false; + JsonArray categoryValues = new JsonArray(); + for (int categoryValue : entry.getValue()) { + categoryValues.add(categoryValue); + } + values.add(entry.getKey(), categoryValues); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + } + +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/Updater.java b/src/me/rockyhawk/commandPanels/Updater.java new file mode 100644 index 0000000..39a931d --- /dev/null +++ b/src/me/rockyhawk/commandPanels/Updater.java @@ -0,0 +1,773 @@ +package me.rockyhawk.commandPanels; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Enumeration; +import java.util.logging.Level; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +/** + * Check for updates on BukkitDev for a given plugin, and download the updates if needed. + *

+ * VERY, VERY IMPORTANT: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating. + *
+ * It is a BUKKIT POLICY that you include a boolean value in your config that prevents the auto-updater from running AT ALL. + *
+ * If you fail to include this option in your config, your plugin will be REJECTED when you attempt to submit it to dev.bukkit.org. + *

+ * An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater. + *
+ * If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l + * + * @author Gravity + * @version 2.4 + */ + +public class Updater { + + /* Constants */ + + // Remote file's title + private static final String TITLE_VALUE = "name"; + // Remote file's download link + private static final String LINK_VALUE = "downloadUrl"; + // Remote file's release type + private static final String TYPE_VALUE = "releaseType"; + // Remote file's build version + private static final String VERSION_VALUE = "gameVersion"; + // Path to GET + private static final String QUERY = "/servermods/files?projectIds="; + // Slugs will be appended to this to get to the project's RSS feed + private static final String HOST = "https://api.curseforge.com"; + // User-agent when querying Curse + private static final String USER_AGENT = "Updater (by Gravity)"; + // Used for locating version numbers in file names + private static final String DELIMETER = "[^\\d.]"; + //original: ^v|[\s_-]v edit: ^\d. + // If the version number contains one of these, don't update. + private static final String[] NO_UPDATE_TAG = { "-DEV", "-PRE", "-SNAPSHOT" }; + // Used for downloading files + private static final int BYTE_SIZE = 1024; + // Config key for api key + private static final String API_KEY_CONFIG_KEY = "api-key"; + // Config key for disabling Updater + private static final String DISABLE_CONFIG_KEY = "disable"; + // Default api key value in config + private static final String API_KEY_DEFAULT = "PUT_API_KEY_HERE"; + // Default disable value in config + private static final boolean DISABLE_DEFAULT = false; + + /* User-provided variables */ + + // Plugin running Updater + private final Plugin plugin; + // Type of update check to run + private final UpdateType type; + // Whether to announce file downloads + private final boolean announce; + // The plugin file (jar) + private final File file; + // The folder that downloads will be placed in + private final File updateFolder; + // The provided callback (if any) + private final UpdateCallback callback; + // Project's Curse ID + private int id = -1; + // BukkitDev ServerMods API key + private String apiKey = null; + + /* Collected from Curse API */ + + private String versionName; + private String versionLink; + private String versionType; + private String versionGameVersion; + + /* Update process variables */ + + // Connection to RSS + private URL url; + // Updater thread + private Thread thread; + // Used for determining the outcome of the update process + private Updater.UpdateResult result = Updater.UpdateResult.SUCCESS; + + /** + * Gives the developer the result of the update process. Can be obtained by called {@link #getResult()} + */ + public enum UpdateResult { + /** + * The updater found an update, and has readied it to be loaded the next time the server restarts/reloads. + */ + SUCCESS, + /** + * The updater did not find an update, and nothing was downloaded. + */ + NO_UPDATE, + /** + * The server administrator has disabled the updating system. + */ + DISABLED, + /** + * The updater found an update, but was unable to download it. + */ + FAIL_DOWNLOAD, + /** + * For some reason, the updater was unable to contact dev.bukkit.org to download the file. + */ + FAIL_DBO, + /** + * When running the version check, the file on DBO did not contain a recognizable version. + */ + FAIL_NOVERSION, + /** + * The id provided by the plugin running the updater was invalid and doesn't exist on DBO. + */ + FAIL_BADID, + /** + * The server administrator has improperly configured their API key in the configuration. + */ + FAIL_APIKEY, + /** + * The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded. + */ + UPDATE_AVAILABLE + } + + /** + * Allows the developer to specify the type of update that will be run. + */ + public enum UpdateType { + /** + * Run a version check, and then if the file is out of date, download the newest version. + */ + DEFAULT, + /** + * Don't run a version check, just find the latest update and download it. + */ + NO_VERSION_CHECK, + /** + * Get information about the version and the download size, but don't actually download anything. + */ + NO_DOWNLOAD + } + + /** + * Represents the various release types of a file on BukkitDev. + */ + public enum ReleaseType { + /** + * An "alpha" file. + */ + ALPHA, + /** + * A "beta" file. + */ + BETA, + /** + * A "release" file. + */ + RELEASE + } + + /** + * Initialize the updater. + * + * @param plugin The plugin that is checking for an update. + * @param id The dev.bukkit.org id of the project. + * @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class. + * @param type Specify the type of update this will be. See {@link UpdateType} + * @param announce True if the program should announce the progress of new updates in console. + */ + public Updater(Plugin plugin, int id, File file, UpdateType type, boolean announce) { + this(plugin, id, file, type, null, announce); + } + + /** + * Initialize the updater with the provided callback. + * + * @param plugin The plugin that is checking for an update. + * @param id The dev.bukkit.org id of the project. + * @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class. + * @param type Specify the type of update this will be. See {@link UpdateType} + * @param callback The callback instance to notify when the Updater has finished + */ + public Updater(Plugin plugin, int id, File file, UpdateType type, UpdateCallback callback) { + this(plugin, id, file, type, callback, false); + } + + /** + * Initialize the updater with the provided callback. + * + * @param plugin The plugin that is checking for an update. + * @param id The dev.bukkit.org id of the project. + * @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class. + * @param type Specify the type of update this will be. See {@link UpdateType} + * @param callback The callback instance to notify when the Updater has finished + * @param announce True if the program should announce the progress of new updates in console. + */ + public Updater(Plugin plugin, int id, File file, UpdateType type, UpdateCallback callback, boolean announce) { + this.plugin = plugin; + this.type = type; + this.announce = announce; + this.file = file; + this.id = id; + this.updateFolder = this.plugin.getServer().getUpdateFolderFile(); + this.callback = callback; + + final File pluginFile = this.plugin.getDataFolder().getParentFile(); + final File updaterFile = new File(pluginFile, "Updater"); + final File updaterConfigFile = new File(updaterFile, "config.yml"); + + YamlConfiguration config = new YamlConfiguration(); + config.options().header("This configuration file affects all plugins using the Updater system (version 2+ - http://forums.bukkit.org/threads/96681/ )" + '\n' + + "If you wish to use your API key, read http://wiki.bukkit.org/ServerMods_API and place it below." + '\n' + + "Some updating systems will not adhere to the disabled value, but these may be turned off in their plugin's configuration."); + config.addDefault(API_KEY_CONFIG_KEY, API_KEY_DEFAULT); + config.addDefault(DISABLE_CONFIG_KEY, DISABLE_DEFAULT); + + if (!updaterFile.exists()) { + this.fileIOOrError(updaterFile, updaterFile.mkdir(), true); + } + + boolean createFile = !updaterConfigFile.exists(); + try { + if (createFile) { + this.fileIOOrError(updaterConfigFile, updaterConfigFile.createNewFile(), true); + config.options().copyDefaults(true); + config.save(updaterConfigFile); + } else { + config.load(updaterConfigFile); + } + } catch (final Exception e) { + final String message; + if (createFile) { + message = "The updater could not create configuration at " + updaterFile.getAbsolutePath(); + } else { + message = "The updater could not load configuration at " + updaterFile.getAbsolutePath(); + } + this.plugin.getLogger().log(Level.SEVERE, message, e); + } + + if (config.getBoolean(DISABLE_CONFIG_KEY)) { + this.result = UpdateResult.DISABLED; + return; + } + + String key = config.getString(API_KEY_CONFIG_KEY); + if (API_KEY_DEFAULT.equalsIgnoreCase(key) || "".equals(key)) { + key = null; + } + + this.apiKey = key; + + try { + this.url = new URL(Updater.HOST + Updater.QUERY + this.id); + } catch (final MalformedURLException e) { + this.plugin.getLogger().log(Level.SEVERE, "The project ID provided for updating, " + this.id + " is invalid.", e); + this.result = UpdateResult.FAIL_BADID; + } + + if (this.result != UpdateResult.FAIL_BADID) { + this.thread = new Thread(new UpdateRunnable()); + this.thread.start(); + } else { + runUpdater(); + } + } + + /** + * Get the result of the update process. + * + * @return result of the update process. + * @see UpdateResult + */ + public Updater.UpdateResult getResult() { + this.waitForThread(); + return this.result; + } + + /** + * Get the latest version's release type. + * + * @return latest version's release type. + * @see ReleaseType + */ + public ReleaseType getLatestType() { + this.waitForThread(); + if (this.versionType != null) { + for (ReleaseType type : ReleaseType.values()) { + if (this.versionType.equalsIgnoreCase(type.name())) { + return type; + } + } + } + return null; + } + + /** + * Get the latest version's game version (such as "CB 1.2.5-R1.0"). + * + * @return latest version's game version. + */ + public String getLatestGameVersion() { + this.waitForThread(); + return this.versionGameVersion; + } + + /** + * Get the latest version's name (such as "Project v1.0"). + * + * @return latest version's name. + */ + public String getLatestName() { + this.waitForThread(); + return this.versionName; + } + + /** + * Get the latest version's direct file link. + * + * @return latest version's file link. + */ + public String getLatestFileLink() { + this.waitForThread(); + return this.versionLink; + } + + /** + * As the result of Updater output depends on the thread's completion, it is necessary to wait for the thread to finish + * before allowing anyone to check the result. + */ + private void waitForThread() { + if ((this.thread != null) && this.thread.isAlive()) { + try { + this.thread.join(); + } catch (final InterruptedException e) { + this.plugin.getLogger().log(Level.SEVERE, null, e); + } + } + } + + /** + * Save an update from dev.bukkit.org into the server's update folder. + * + * @param file the name of the file to save it as. + */ + private void saveFile(String file) { + final File folder = this.updateFolder; + + deleteOldFiles(); + if (!folder.exists()) { + this.fileIOOrError(folder, folder.mkdir(), true); + } + downloadFile(); + + // Check to see if it's a zip file, if it is, unzip it. + final File dFile = new File(folder.getAbsolutePath(), file); + if (dFile.getName().endsWith(".zip")) { + // Unzip + this.unzip(dFile.getAbsolutePath()); + } + if (this.announce) { + this.plugin.getLogger().info("Finished updating."); + } + } + + /** + * Download a file and save it to the specified folder. + */ + private void downloadFile() { + BufferedInputStream in = null; + FileOutputStream fout = null; + try { + URL fileUrl = followRedirects(this.versionLink); + final int fileLength = fileUrl.openConnection().getContentLength(); + in = new BufferedInputStream(fileUrl.openStream()); + fout = new FileOutputStream(new File(this.updateFolder, file.getName())); + + final byte[] data = new byte[Updater.BYTE_SIZE]; + int count; + if (this.announce) { + this.plugin.getLogger().info("About to download a new update: " + this.versionName); + } + long downloaded = 0; + while ((count = in.read(data, 0, Updater.BYTE_SIZE)) != -1) { + downloaded += count; + fout.write(data, 0, count); + final int percent = (int) ((downloaded * 100) / fileLength); + if (this.announce && ((percent % 10) == 0)) { + this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes."); + } + } + } catch (Exception ex) { + this.plugin.getLogger().log(Level.WARNING, "The auto-updater tried to download a new update, but was unsuccessful.", ex); + this.result = Updater.UpdateResult.FAIL_DOWNLOAD; + } finally { + try { + if (in != null) { + in.close(); + } + } catch (final IOException ex) { + this.plugin.getLogger().log(Level.SEVERE, null, ex); + } + try { + if (fout != null) { + fout.close(); + } + } catch (final IOException ex) { + this.plugin.getLogger().log(Level.SEVERE, null, ex); + } + } + } + + private URL followRedirects(String location) throws IOException { + URL resourceUrl, base, next; + HttpURLConnection conn; + String redLoc; + while (true) { + resourceUrl = new URL(location); + conn = (HttpURLConnection) resourceUrl.openConnection(); + + conn.setConnectTimeout(15000); + conn.setReadTimeout(15000); + conn.setInstanceFollowRedirects(false); + conn.setRequestProperty("User-Agent", "Mozilla/5.0..."); + + switch (conn.getResponseCode()) { + case HttpURLConnection.HTTP_MOVED_PERM: + case HttpURLConnection.HTTP_MOVED_TEMP: + redLoc = conn.getHeaderField("Location"); + base = new URL(location); + next = new URL(base, redLoc); // Deal with relative URLs + location = next.toExternalForm(); + continue; + } + break; + } + return conn.getURL(); + } + + /** + * Remove possibly leftover files from the update folder. + */ + private void deleteOldFiles() { + //Just a quick check to make sure we didn't leave any files from last time... + File[] list = listFilesOrError(this.updateFolder); + for (final File xFile : list) { + if (xFile.getName().endsWith(".zip")) { + this.fileIOOrError(xFile, xFile.mkdir(), true); + } + } + } + + /** + * Part of Zip-File-Extractor, modified by Gravity for use with Updater. + * + * @param file the location of the file to extract. + */ + private void unzip(String file) { + final File fSourceZip = new File(file); + try { + final String zipPath = file.substring(0, file.length() - 4); + ZipFile zipFile = new ZipFile(fSourceZip); + Enumeration e = zipFile.entries(); + while (e.hasMoreElements()) { + ZipEntry entry = e.nextElement(); + File destinationFilePath = new File(zipPath, entry.getName()); + this.fileIOOrError(destinationFilePath.getParentFile(), destinationFilePath.getParentFile().mkdirs(), true); + if (!entry.isDirectory()) { + final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry)); + int b; + final byte[] buffer = new byte[Updater.BYTE_SIZE]; + final FileOutputStream fos = new FileOutputStream(destinationFilePath); + final BufferedOutputStream bos = new BufferedOutputStream(fos, Updater.BYTE_SIZE); + while ((b = bis.read(buffer, 0, Updater.BYTE_SIZE)) != -1) { + bos.write(buffer, 0, b); + } + bos.flush(); + bos.close(); + bis.close(); + final String name = destinationFilePath.getName(); + if (name.endsWith(".jar") && this.pluginExists(name)) { + File output = new File(this.updateFolder, name); + this.fileIOOrError(output, destinationFilePath.renameTo(output), true); + } + } + } + zipFile.close(); + + // Move any plugin data folders that were included to the right place, Bukkit won't do this for us. + moveNewZipFiles(zipPath); + + } catch (final IOException e) { + this.plugin.getLogger().log(Level.SEVERE, "The auto-updater tried to unzip a new update file, but was unsuccessful.", e); + this.result = Updater.UpdateResult.FAIL_DOWNLOAD; + } finally { + this.fileIOOrError(fSourceZip, fSourceZip.delete(), false); + } + } + + /** + * Find any new files extracted from an update into the plugin's data directory. + * @param zipPath path of extracted files. + */ + private void moveNewZipFiles(String zipPath) { + File[] list = listFilesOrError(new File(zipPath)); + for (final File dFile : list) { + if (dFile.isDirectory() && this.pluginExists(dFile.getName())) { + // Current dir + final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName()); + // List of existing files in the new dir + final File[] dList = listFilesOrError(dFile); + // List of existing files in the current dir + final File[] oList = listFilesOrError(oFile); + for (File cFile : dList) { + // Loop through all the files in the new dir + boolean found = false; + for (final File xFile : oList) { + // Loop through all the contents in the current dir to see if it exists + if (xFile.getName().equals(cFile.getName())) { + found = true; + break; + } + } + if (!found) { + // Move the new file into the current dir + File output = new File(oFile, cFile.getName()); + this.fileIOOrError(output, cFile.renameTo(output), true); + } else { + // This file already exists, so we don't need it anymore. + this.fileIOOrError(cFile, cFile.delete(), false); + } + } + } + this.fileIOOrError(dFile, dFile.delete(), false); + } + File zip = new File(zipPath); + this.fileIOOrError(zip, zip.delete(), false); + } + + /** + * Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip. + * + * @param name a name to check for inside the plugins folder. + * @return true if a file inside the plugins folder is named this. + */ + private boolean pluginExists(String name) { + File[] plugins = listFilesOrError(new File("plugins")); + for (final File file : plugins) { + if (file.getName().equals(name)) { + return true; + } + } + return false; + } + + /** + * Check to see if the program should continue by evaluating whether the plugin is already updated, or shouldn't be updated. + * + * @return true if the version was located and is not the same as the remote's newest. + */ + private boolean versionCheck() { + final String title = this.versionName; + if (this.type != UpdateType.NO_VERSION_CHECK) { + final String localVersion = this.plugin.getDescription().getVersion(); + if (title.split(DELIMETER).length >= 2) { + // Get the newest file's version number + final String remoteVersion = title.split(DELIMETER)[title.split(DELIMETER).length - 1].split(" ")[0]; + + if (this.hasTag(localVersion) || !this.shouldUpdate(localVersion, remoteVersion)) { + // We already have the latest version, or this build is tagged for no-update + this.result = Updater.UpdateResult.NO_UPDATE; + return false; + } + } else { + // The file's name did not contain the string 'vVersion' + final String authorInfo = this.plugin.getDescription().getAuthors().isEmpty() ? "" : " (" + this.plugin.getDescription().getAuthors().get(0) + ")"; + this.plugin.getLogger().warning("The author of this plugin" + authorInfo + " has misconfigured their Auto Update system"); + this.plugin.getLogger().warning("File versions should follow the format 'PluginName vVERSION'"); + this.plugin.getLogger().warning("Please notify the author of this error."); + this.result = Updater.UpdateResult.FAIL_NOVERSION; + return false; + } + } + return true; + } + + /** + * If you wish to run mathematical versioning checks, edit this method. + *

+ * With default behavior, Updater will NOT verify that a remote version available on BukkitDev + * which is not this version is indeed an "update". + * If a version is present on BukkitDev that is not the version that is currently running, + * Updater will assume that it is a newer version. + * This is because there is no standard versioning scheme, and creating a calculation that can + * determine whether a new update is actually an update is sometimes extremely complicated. + *

+ *

+ * Updater will call this method from {@link #versionCheck()} before deciding whether + * the remote version is actually an update. + * If you have a specific versioning scheme with which a mathematical determination can + * be reliably made to decide whether one version is higher than another, you may + * revise this method, using the local and remote version parameters, to execute the + * appropriate check. + *

+ *

+ * Returning a value of false will tell the update process that this is NOT a new version. + * Without revision, this method will always consider a remote version at all different from + * that of the local version a new update. + *

+ * @param localVersion the current version + * @param remoteVersion the remote version + * @return true if Updater should consider the remote version an update, false if not. + */ + public boolean shouldUpdate(String localVersion, String remoteVersion) { + return !localVersion.equalsIgnoreCase(remoteVersion); + } + + /** + * Evaluate whether the version number is marked showing that it should not be updated by this program. + * + * @param version a version number to check for tags in. + * @return true if updating should be disabled. + */ + private boolean hasTag(String version) { + for (final String string : Updater.NO_UPDATE_TAG) { + if (version.contains(string)) { + return true; + } + } + return false; + } + + /** + * Make a connection to the BukkitDev API and request the newest file's details. + * + * @return true if successful. + */ + private boolean read() { + try { + final URLConnection conn = this.url.openConnection(); + conn.setConnectTimeout(5000); + + if (this.apiKey != null) { + conn.addRequestProperty("X-API-Key", this.apiKey); + } + conn.addRequestProperty("User-Agent", Updater.USER_AGENT); + + conn.setDoOutput(true); + + final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + final String response = reader.readLine(); + + final JSONArray array = (JSONArray) JSONValue.parse(response); + + if (array.isEmpty()) { + this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id); + this.result = UpdateResult.FAIL_BADID; + return false; + } + + JSONObject latestUpdate = (JSONObject) array.get(array.size() - 1); + this.versionName = (String) latestUpdate.get(Updater.TITLE_VALUE); + this.versionLink = (String) latestUpdate.get(Updater.LINK_VALUE); + this.versionType = (String) latestUpdate.get(Updater.TYPE_VALUE); + this.versionGameVersion = (String) latestUpdate.get(Updater.VERSION_VALUE); + + return true; + } catch (final IOException e) { + if (e.getMessage().contains("HTTP response code: 403")) { + this.plugin.getLogger().severe("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml"); + this.plugin.getLogger().severe("Please double-check your configuration to ensure it is correct."); + this.result = UpdateResult.FAIL_APIKEY; + } else { + this.plugin.getLogger().severe("The updater could not contact dev.bukkit.org for updating."); + this.plugin.getLogger().severe("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime."); + this.result = UpdateResult.FAIL_DBO; + } + this.plugin.getLogger().log(Level.SEVERE, null, e); + return false; + } + } + + /** + * Perform a file operation and log any errors if it fails. + * @param file file operation is performed on. + * @param result result of file operation. + * @param create true if a file is being created, false if deleted. + */ + private void fileIOOrError(File file, boolean result, boolean create) { + if (!result) { + this.plugin.getLogger().severe("The updater could not " + (create ? "create" : "delete") + " file at: " + file.getAbsolutePath()); + } + } + + private File[] listFilesOrError(File folder) { + File[] contents = folder.listFiles(); + if (contents == null) { + this.plugin.getLogger().severe("The updater could not access files at: " + this.updateFolder.getAbsolutePath()); + return new File[0]; + } else { + return contents; + } + } + + /** + * Called on main thread when the Updater has finished working, regardless + * of result. + */ + public interface UpdateCallback { + /** + * Called when the updater has finished working. + * @param updater The updater instance + */ + void onFinish(Updater updater); + } + + private class UpdateRunnable implements Runnable { + @Override + public void run() { + runUpdater(); + } + } + + private void runUpdater() { + if (this.url != null && (this.read() && this.versionCheck())) { + // Obtain the results of the project's file feed + if ((this.versionLink != null) && (this.type != UpdateType.NO_DOWNLOAD)) { + String name = this.file.getName(); + // If it's a zip file, it shouldn't be downloaded as the plugin's name + if (this.versionLink.endsWith(".zip")) { + name = this.versionLink.substring(this.versionLink.lastIndexOf("/") + 1); + } + this.saveFile(name); + } else { + this.result = UpdateResult.UPDATE_AVAILABLE; + } + } + + if (this.callback != null) { + new BukkitRunnable() { + @Override + public void run() { + runCallback(); + } + }.runTask(this.plugin); + } + } + + private void runCallback() { + this.callback.onFinish(this); + } +} diff --git a/src/me/rockyhawk/commandPanels/commandpanels.java b/src/me/rockyhawk/commandPanels/commandpanels.java new file mode 100644 index 0000000..b605934 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commandpanels.java @@ -0,0 +1,1557 @@ +package me.rockyhawk.commandPanels; + +import com.Ben12345rocks.VotingPlugin.UserManager.UserManager; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.lang.reflect.Field; +import java.util.*; + +import me.arcaniax.hdb.api.HeadDatabaseAPI; +import me.clip.placeholderapi.PlaceholderAPI; +import me.realized.tokenmanager.api.TokenManager; +import me.rockyhawk.commandPanels.commands.*; +import me.rockyhawk.commandPanels.completeTabs.cpTabComplete; +import me.rockyhawk.commandPanels.generatePanels.commandpanelsgenerate; +import me.rockyhawk.commandPanels.generatePanels.newGenUtils; +import me.rockyhawk.commandPanels.generatePanels.tabCompleteGenerate; +import me.rockyhawk.commandPanels.ingameEditor.cpIngameEditCommand; +import me.rockyhawk.commandPanels.ingameEditor.cpTabCompleteIngame; +import me.rockyhawk.commandPanels.ingameEditor.editorUserInput; +import me.rockyhawk.commandPanels.ingameEditor.editorUtils; +import me.rockyhawk.commandPanels.premium.commandpanelUserInput; +import me.rockyhawk.commandPanels.premium.commandpanelrefresher; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.*; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.craftbukkit.libs.org.apache.commons.io.IOUtils; +import org.bukkit.craftbukkit.libs.org.apache.commons.io.input.CharSequenceReader; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.*; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.potion.PotionData; +import org.bukkit.potion.PotionType; + +public class commandpanels extends JavaPlugin { + public YamlConfiguration config; + public Economy econ = null; + public boolean update = false; + public boolean debug = false; + public List panelRunning = new ArrayList(); + public List userInputStrings = new ArrayList(); + public List editorInputStrings = new ArrayList(); + public ArrayList panelFiles = new ArrayList(); + public ArrayList panelNames = new ArrayList(); //this will return something like {"mainMenuPanel","4"} which means the 4 is for panelFiles.get(4). So you know which file it is for + public File panelsf; + + public commandpanels() { + this.panelsf = new File(this.getDataFolder() + File.separator + "panels"); + } + + public void onEnable() { + this.config = YamlConfiguration.loadConfiguration(new File(this.getDataFolder() + File.separator + "config.yml")); + Bukkit.getLogger().info("[CommandPanels] RockyHawk's CommandPanels v" + this.getDescription().getVersion() + " Plugin Loading..."); + this.setupEconomy(); + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + new Metrics(this); + this.getCommand("commandpanel").setExecutor(new commandpanel(this)); + this.getCommand("commandpanel").setTabCompleter(new cpTabComplete(this)); + this.getCommand("commandpanelgenerate").setTabCompleter(new tabCompleteGenerate(this)); + this.getCommand("commandpaneledit").setTabCompleter(new cpTabCompleteIngame(this)); + this.getCommand("commandpanelgenerate").setExecutor(new commandpanelsgenerate(this)); + this.getCommand("commandpanelreload").setExecutor(new commandpanelsreload(this)); + this.getCommand("commandpaneldebug").setExecutor(new commandpanelsdebug(this)); + this.getCommand("commandpanelclose").setExecutor(new commandpanelclose(this)); + this.getCommand("commandpanelversion").setExecutor(new commandpanelversion(this)); + this.getCommand("commandpanellist").setExecutor(new commandpanelslist(this)); + this.getCommand("commandpaneledit").setExecutor(new cpIngameEditCommand(this)); + this.getServer().getPluginManager().registerEvents(new utils(this), this); + this.getServer().getPluginManager().registerEvents(new editorUtils(this), this); + this.getServer().getPluginManager().registerEvents(new newGenUtils(this), this); + this.getServer().getPluginManager().registerEvents(new commandpanelcustom(this), this); + this.getServer().getPluginManager().registerEvents(new commandpanelUserInput(this), this); + this.getServer().getPluginManager().registerEvents(new editorUserInput(this), this); + this.getServer().getPluginManager().registerEvents(new commandpanelrefresher(this), this); + this.config.addDefault("config.version", "3.0"); + this.config.addDefault("config.refresh-panels", "true"); + this.config.addDefault("config.refresh-delay", "4"); + this.config.addDefault("config.stop-sound", "true"); + this.config.addDefault("config.disabled-world-message", "true"); + this.config.addDefault("config.update-notifications", "true"); + this.config.addDefault("config.panel-snooper", "false"); + this.config.addDefault("config.ingame-editor", "true"); + this.config.addDefault("config.input-cancel", "cancel"); + this.config.addDefault("config.input-cancelled", "&cCancelled!"); + List inputMessage = new ArrayList(); + inputMessage.add("%cp-tag%&aEnter Input for Command"); + inputMessage.add("&cType &4%cp-args% &cto Cancel the command"); + this.config.addDefault("config.input-message", inputMessage); + this.config.addDefault("config.format.perms", "&cNo permission."); + this.config.addDefault("config.format.reload", "&aReloaded."); + this.config.addDefault("config.format.nopanel", "&cPanel not found."); + this.config.addDefault("config.format.noitem", "&cPanel doesn't have clickable item."); + this.config.addDefault("config.format.notitem", "&cPlayer not found."); + this.config.addDefault("config.format.error", "&cError found in config at"); + this.config.addDefault("config.format.needmoney", "&cInsufficient Funds!"); + this.config.addDefault("config.format.needitems", "&cInsufficient Items!"); + this.config.addDefault("config.format.bought", "&aSuccessfully Bought For $%cp-args%"); + this.config.addDefault("config.format.sold", "&aSuccessfully Sold For $%cp-args%"); + this.config.addDefault("config.format.signtag", "[CommandPanel]"); + this.config.addDefault("config.format.tag", "&6[&bCommandPanels&6]"); + this.config.addDefault("config.format.offline", "Offline"); + this.config.addDefault("config.format.offlineHeadValue", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNmU1Mjg2YzQ3MGY2NmZmYTFhMTgzMzFjYmZmYjlhM2MyYTQ0MjRhOGM3MjU5YzQ0MzZmZDJlMzU1ODJhNTIyIn19fQ=="); + if (!this.panelsf.exists() || this.panelsf.list().length == 0) { + try { + FileConfiguration exampleFileConfiguration = YamlConfiguration.loadConfiguration(getReaderFromStream(this.getResource("example.yml"))); + exampleFileConfiguration.save(new File(this.panelsf + File.separator + "example.yml")); + } catch (IOException var11) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " WARNING: Could not save the example file!"); + } + } + + this.config.options().copyDefaults(true); + + try { + this.config.save(new File(this.getDataFolder() + File.separator + "config.yml")); + } catch (IOException var10) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " WARNING: Could not save the config file!"); + } + try { + if (!this.config.getString("config.version").equals("3.0")) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " WARNING: Config version doesn't match the recommended version. You may run into issues."); + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " WARNING: Either remove the config and generate a new one, or restore the original version of the plugin initially being used."); + } + } catch (Exception e) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " WARNING: Could not find config version! Your config may be missing some information!"); + } + + try { + if (this.config.getString("config.update-notifications").trim().equalsIgnoreCase("true")) { + if(!this.getDescription().getVersion().contains("-")) { + Updater check = new Updater(this, 325941, this.getFile(), Updater.UpdateType.NO_DOWNLOAD, true); + if (!check.getLatestName().toLowerCase().trim().equals("commandpanels v" + this.getDescription().getVersion())) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " WARNING: CommandPanels is not running the latest version (" + check.getLatestName().trim() + ") Download a new version at"); + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " https://www.spigotmc.org/resources/command-panels-custom-guis.67788/"); + this.update = true; + } else { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.GREEN + " CommandPanels is up to date."); + } + }else{ + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.GREEN + " CommandPanels is running a custom version."); + } + } + } catch (Exception var9) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels]" + ChatColor.RED + " Could not check for update online."); + } + + //load panelFiles + reloadPanelFiles(); + + Bukkit.getLogger().info("[CommandPanels] RockyHawk's CommandPanels v" + this.getDescription().getVersion() + " Plugin Loaded!"); + } + + public void onDisable() { + Bukkit.getLogger().info("RockyHawk's CommandPanels Plugin Disabled, aww man."); + } + + public Inventory openGui(String panels, Player p, YamlConfiguration pconfig, int onOpen, int animateValue) { + String tag = this.config.getString("config.format.tag") + " "; + if (Integer.parseInt(pconfig.getString("panels." + panels + ".rows")) < 7 && Integer.parseInt(pconfig.getString("panels." + panels + ".rows")) > 0) { + Inventory i; + if (onOpen != 3) { + //use the regular inventory + i = Bukkit.createInventory((InventoryHolder) null, Integer.parseInt(pconfig.getString("panels." + panels + ".rows")) * 9, ChatColor.translateAlternateColorCodes('&', pconfig.getString("panels." + panels + ".title"))); + } else { + //this means it is the Editor window + i = Bukkit.createInventory((InventoryHolder) null, Integer.parseInt(pconfig.getString("panels." + panels + ".rows")) * 9, ChatColor.translateAlternateColorCodes('&', ChatColor.GRAY + "Editing Panel: " + pconfig.getString("panels." + panels + ".title"))); + } + String item = ""; + + String key; + for (Iterator var6 = pconfig.getConfigurationSection("panels." + panels + ".item").getKeys(false).iterator(); var6.hasNext(); item = item + key + " ") { + key = (String) var6.next(); + } + + item = item.trim(); + int c; + for (c = 0; item.split("\\s").length - 1 >= c; ++c) { + if(item.equals("")){ + //skip putting any items in the inventory if it is empty + break; + } + String section = ""; + //onOpen needs to not be 3 so the editor won't include hasperm and noperm items + if (onOpen != 3) { + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue")) { + //loop through possible hasvalue 1,2,3,etc + for (int count = 0; pconfig.getConfigurationSection("panels." + panels + ".item." + item.split("\\s")[c]).getKeys(false).size() > count; count++) { + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue" + count)) { + boolean outputValue = true; + //outputValue will default to true + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue" + count + ".output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = pconfig.getBoolean("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue" + count + ".output"); + } + String value = pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue" + count + ".value"); + String compare = ChatColor.stripColor(papi(p,setCpPlaceholders(p,pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue" + count + ".compare")))); + if (compare.equals(value) == outputValue) { + //onOpen being 3 means it is the editor panel.. hasvalue items cannot be included to avoid item breaking + section = ".hasvalue" + count; + break; + } + } + } + //this will do the hasvalue without any numbers + boolean outputValue = true; + //outputValue will default to true + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue.output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = pconfig.getBoolean("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue.output"); + } + String value = pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue.value"); + String compare = ChatColor.stripColor(papi(p,setCpPlaceholders(p,pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + ".hasvalue.compare")))); + if (compare.equals(value) == outputValue) { + //onOpen being 3 means it is the editor panel.. hasvalue items cannot be included to avoid item breaking + section = ".hasvalue"; + } + } + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm")) { + //loop through possible noperm/hasperm 1,2,3,etc + for (int count = 0; pconfig.getConfigurationSection("panels." + panels + ".item." + item.split("\\s")[c]).getKeys(false).size() > count; count++) { + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm" + count)) { + boolean outputValue = true; + //outputValue will default to true + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm" + count + ".output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = pconfig.getBoolean("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm" + count + ".output"); + } + if (p.hasPermission(pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm" + count + ".perm")) == outputValue) { + //onOpen being 3 means it is the editor panel.. noPerm and hasPerm items cannot be included to avoid item breaking + section = ".hasperm" + count; + break; + } + } + } + //this will do the hasperm without any numbers + boolean outputValue = true; + //outputValue will default to true + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm" + ".output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = pconfig.getBoolean("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm" + ".output"); + } + if (p.hasPermission(pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + ".hasperm.perm")) == outputValue) { + section = ".hasperm"; + } + } + //This section is for animations below here: VISUAL ONLY + + //check for if there is animations inside the items section + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".animate" + animateValue)) { + //check for if it contains the animate that has the animvatevalue + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".animate" + animateValue)) { + section = section + ".animate" + animateValue; + } + } + } + String material = pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".material"); + if (!pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".material").equalsIgnoreCase("AIR")) { + ItemStack s; + String mat; + String matskull; + String skullname; + //this will convert the %cp-player-online-1-find% into cps= NAME + if (material.contains("%cp-player-online-")) { + int start = material.indexOf("%cp-player-online-"); + int end = material.lastIndexOf("-find%"); + String playerLocation = material.substring(start, end).replace("%cp-player-online-", ""); + Player[] playerFind = Bukkit.getOnlinePlayers().toArray(new Player[Bukkit.getOnlinePlayers().size()]); + if (Integer.parseInt(playerLocation) > playerFind.length) { + material = material.replace(material.substring(start, end) + "-find%", "cps= " + config.getString("config.format.offlineHeadValue")); + } else { + material = material.replace(material.substring(start, end) + "-find%", "cpo= " + playerFind[Integer.parseInt(playerLocation) - 1].getName()); + //cpo is to get the skull of the player online. It is fine since the plugin knows the player is online + } + } + try { + mat = material.toUpperCase(); + matskull = material; + skullname = "no skull"; + if (matskull.split("\\s")[0].toLowerCase().equals("cps=") || matskull.split("\\s")[0].toLowerCase().equals("cpo=")) { + skullname = p.getUniqueId().toString(); + mat = "PLAYER_HEAD"; + } + + if (matskull.split("\\s")[0].toLowerCase().equals("hdb=")) { + skullname = "hdb"; + mat = "PLAYER_HEAD"; + } + + s = new ItemStack(Material.matchMaterial(mat), 1); + + if (!skullname.equals("no skull") && !skullname.equals("hdb") && !matskull.split("\\s")[0].equalsIgnoreCase("cpo=")) { + try { + SkullMeta meta; + if (matskull.split("\\s")[1].equalsIgnoreCase("self")) { + //if self/own + meta = (SkullMeta) s.getItemMeta(); + try { + meta.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString(skullname))); + } catch (Exception var23) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + this.config.getString("config.format.error") + " material: cps= self")); + debug(var23); + } + s.setItemMeta(meta); + } else { + //custom data + s = this.getItem(matskull.split("\\s")[1]); + } + } catch (Exception var32) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + this.config.getString("config.format.error") + " head material: Could not load skull")); + debug(var32); + } + } + if (!skullname.equals("no skull") && matskull.split("\\s")[0].equalsIgnoreCase("cpo=")) { + SkullMeta cpoMeta = (SkullMeta) s.getItemMeta(); + cpoMeta.setOwningPlayer(Bukkit.getOfflinePlayer(Bukkit.getPlayer(matskull.split("\\s")[1]).getUniqueId())); + s.setItemMeta(cpoMeta); + } + + if (skullname.equals("hdb")) { + if (this.getServer().getPluginManager().isPluginEnabled("HeadDatabase")) { + HeadDatabaseAPI api; + api = new HeadDatabaseAPI(); + + try { + s = api.getItemHead(matskull.split("\\s")[1].trim()); + } catch (Exception var22) { + p.sendMessage(this.papi(p, ChatColor.translateAlternateColorCodes('&', tag + this.config.getString("config.format.error") + " hdb: could not load skull!"))); + debug(var22); + } + } else { + p.sendMessage(this.papi(p, ChatColor.translateAlternateColorCodes('&', tag + "Download HeadDatabaseHook from Spigot to use this feature!"))); + } + } + + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".enchanted")) { + try { + ItemMeta EnchantMeta; + if (pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".enchanted").trim().equalsIgnoreCase("true")) { + EnchantMeta = s.getItemMeta(); + EnchantMeta.addEnchant(Enchantment.KNOCKBACK, 1, false); + EnchantMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + s.setItemMeta(EnchantMeta); + } else if (!pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".enchanted").trim().equalsIgnoreCase("false")) { + EnchantMeta = s.getItemMeta(); + EnchantMeta.addEnchant(Enchantment.getByKey(NamespacedKey.minecraft(pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".enchanted").split("\\s")[0].toLowerCase())), Integer.parseInt(pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".enchanted").split("\\s")[1]), true); + s.setItemMeta(EnchantMeta); + } + } catch (Exception ench) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " enchanted: " + pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".enchanted")))); + debug(ench); + } + } + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".customdata")) { + ItemMeta customMeta = s.getItemMeta(); + customMeta.setCustomModelData(Integer.parseInt(pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".customdata"))); + s.setItemMeta(customMeta); + } + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".leatherarmor")) { + //if the item is leather armor, change the colour to this + try { + if (s.getType() == Material.LEATHER_BOOTS || s.getType() == Material.LEATHER_LEGGINGS || s.getType() == Material.LEATHER_CHESTPLATE || s.getType() == Material.LEATHER_HELMET) { + LeatherArmorMeta leatherMeta = (LeatherArmorMeta) s.getItemMeta(); + String colourCode = pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".leatherarmor"); + if (!colourCode.contains(",")) { + //use a color name + leatherMeta.setColor(colourCodes.get(colourCode.toUpperCase())); + } else { + //use RGB sequence + int[] colorRGB = {255, 255, 255}; + int count = 0; + for (String colourNum : colourCode.split(",")) { + colorRGB[count] = Integer.parseInt(colourNum); + count += 1; + } + leatherMeta.setColor(Color.fromRGB(colorRGB[0], colorRGB[1], colorRGB[2])); + } + s.setItemMeta(leatherMeta); + } + } catch (Exception er) { + //don't colour the armor + debug(er); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " leatherarmor: " + pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".leatherarmor")))); + } + } + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".potion")) { + //if the item is a potion, give it an effect + try { + PotionMeta potionMeta = (PotionMeta)s.getItemMeta(); + String effectType = pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".potion"); + potionMeta.setBasePotionData(new PotionData(PotionType.valueOf(effectType.toUpperCase()))); + potionMeta.addItemFlags(new ItemFlag[]{ItemFlag.HIDE_POTION_EFFECTS}); + s.setItemMeta(potionMeta); + } catch (Exception er) { + //don't add the effect + debug(er); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + this.config.getString("config.format.error") + " potion: " + pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".potion"))); + } + } + if (pconfig.contains("panels." + panels + ".item." + item.split("\\s")[c] + section + ".stack")) { + //change the stack amount + s.setAmount(Integer.parseInt(pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".stack"))); + } + } catch (IllegalArgumentException var33) { + debug(var33); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " material: " + pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".material")))); + return null; + } catch (NullPointerException var34) { + debug(var34); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " material: " + pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".material")))); + return null; + } + if (onOpen != 3) { + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + this.setName(s, PlaceholderAPI.setPlaceholders(p, pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".name")), PlaceholderAPI.setPlaceholders(p, (List) pconfig.getList("panels." + panels + ".item." + item.split("\\s")[c] + section + ".lore")), p, true); + } else { + this.setName(s, pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".name"), pconfig.getList("panels." + panels + ".item." + item.split("\\s")[c] + section + ".lore"), p, true); + } + }else{ + this.setName(s, pconfig.getString("panels." + panels + ".item." + item.split("\\s")[c] + section + ".name"), pconfig.getList("panels." + panels + ".item." + item.split("\\s")[c] + section + ".lore"), p, false); + } + + try { + i.setItem(Integer.parseInt(item.split("\\s")[c]), s); + } catch (ArrayIndexOutOfBoundsException var24) { + debug(var24); + if (debug) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " item: One of the items does not fit in the Panel!"))); + } + } + } + } + if (pconfig.contains("panels." + panels + ".empty") && !pconfig.getString("panels." + panels + ".empty").equals("AIR")) { + for (c = 0; Integer.parseInt(pconfig.getString("panels." + panels + ".rows")) * 9 - 1 >= c; ++c) { + boolean found = false; + if(!item.equals("")) { + for (int f = 0; item.split("\\s").length - 1 >= f; ++f) { + if (Integer.parseInt(item.split("\\s")[f]) == c) { + found = true; + } + } + }else{ + found = false; + } + if (!found) { + ItemStack empty; + try { + empty = new ItemStack(Material.matchMaterial(pconfig.getString("panels." + panels + ".empty").toUpperCase()), 1); + if (empty.getType() == Material.AIR) { + continue; + } + } catch (IllegalArgumentException var26) { + debug(var26); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " empty: " + pconfig.getString("panels." + panels + ".empty")))); + return null; + } catch (NullPointerException var27) { + debug(var27); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " empty: " + pconfig.getString("panels." + panels + ".empty")))); + return null; + } + + ItemMeta renamedMeta = empty.getItemMeta(); + renamedMeta.setDisplayName(" "); + empty.setItemMeta(renamedMeta); + if (onOpen != 3) { + //only place empty items if not editing + i.setItem(c, empty); + } + } + } + } + if (ChatColor.translateAlternateColorCodes('&', pconfig.getString("panels." + panels + ".title")).equals("Chest")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " Title: Cannot be named Chest"))); + return null; + } + if (ChatColor.translateAlternateColorCodes('&', pconfig.getString("panels." + panels + ".title")).contains("Editing Panel:")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " Title: Cannot contain Editing Panel:"))); + return null; + } + if (ChatColor.translateAlternateColorCodes('&', pconfig.getString("panels." + panels + ".title")).contains("Panel Settings:")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " Title: Cannot contain Panel Settings:"))); + return null; + } + if (ChatColor.translateAlternateColorCodes('&', pconfig.getString("panels." + panels + ".title")).contains("Item Settings:")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " Title: Cannot contain Item Settings:"))); + return null; + } + if (ChatColor.translateAlternateColorCodes('&', pconfig.getString("panels." + panels + ".title")).equals("Command Panels Editor")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " Title: Cannot be named Command Panels Editor"))); + return null; + } + if (onOpen == 1 || onOpen == 3) { + //onOpen 1 is default and 3 is for the editor + p.openInventory(i); + } else if (onOpen == 0) { + //onOpen 0 will just refresh the panel + p.getOpenInventory().getTopInventory().setStorageContents(i.getStorageContents()); + } else if (onOpen == 2) { + //will return the inventory, not opening it at all + return i; + } + return i; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, this.config.getString("config.format.error") + " rows: " + pconfig.getString("panels." + panels + ".rows")))); + return null; + } + } + + public void setName(ItemStack renamed, String customName, List lore, Player p, Boolean usePlaceholders) { + try { + ItemMeta renamedMeta = renamed.getItemMeta(); + //set cp placeholders + if(usePlaceholders) { + customName = papi(p, setCpPlaceholders(p, customName)); + } + + renamedMeta.addItemFlags(new ItemFlag[]{ItemFlag.HIDE_ATTRIBUTES}); + if (customName != null) { + renamedMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', customName)); + } + + List clore = new ArrayList(); + if (lore != null) { + for (int i = 0; lore.size() > i; ++i) { + clore.add(ChatColor.translateAlternateColorCodes('&', lore.get(i).toString())); + if(usePlaceholders) { + clore.set(i, papi(p, setCpPlaceholders(p, clore.get(i)))); + } + } + renamedMeta.setLore(clore); + } + renamed.setItemMeta(renamedMeta); + } catch (Exception var11) { + } + + } + + private boolean setupEconomy() { + if (this.getServer().getPluginManager().getPlugin("Vault") == null) { + return false; + } else { + RegisteredServiceProvider rsp = this.getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } else { + this.econ = (Economy) rsp.getProvider(); + return this.econ != null; + } + } + } + + public boolean checkPanels(YamlConfiguration temp) { + try { + return temp.contains("panels"); + } catch (Exception var3) { + return false; + } + } + + public String getHeadBase64(ItemStack var0) { + if (var0.getType().equals(Material.PLAYER_HEAD) && var0.hasItemMeta()) { + try { + SkullMeta var1 = (SkullMeta) var0.getItemMeta(); + if (!var1.hasOwner()) { + Field var2 = var1.getClass().getDeclaredField("profile"); + var2.setAccessible(true); + GameProfile var3 = (GameProfile) var2.get(var1); + Iterator var4 = var3.getProperties().get("textures").iterator(); + if (var4.hasNext()) { + Property var5 = (Property) var4.next(); + return var5.getValue(); + } + } + }catch(Exception exc){/*If there is a problem with the head skip and return null*/} + } + return null; + } + + public ItemStack getItem(String b64stringtexture) { + GameProfile profile = new GameProfile(UUID.randomUUID(), (String) null); + PropertyMap propertyMap = profile.getProperties(); + if (propertyMap == null) { + throw new IllegalStateException("Profile doesn't contain a property map"); + } else { + propertyMap.put("textures", new Property("textures", b64stringtexture)); + ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1); + ItemMeta headMeta = head.getItemMeta(); + Class headMetaClass = headMeta.getClass(); + + try { + getField(headMetaClass, "profile", GameProfile.class, 0).set(headMeta, profile); + } catch (IllegalArgumentException var10) { + var10.printStackTrace(); + } catch (IllegalAccessException var11) { + var11.printStackTrace(); + } + + head.setItemMeta(headMeta); + return head; + } + } + + private Field getField(Class target, String name, Class fieldType, int index) { + Field[] var4 = target.getDeclaredFields(); + int var5 = var4.length; + + for (int var6 = 0; var6 < var5; ++var6) { + Field field = var4[var6]; + if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0) { + field.setAccessible(true); + return field; + } + } + + if (target.getSuperclass() != null) { + return getField(target.getSuperclass(), name, fieldType, index); + } else { + throw new IllegalArgumentException("Cannot find field with type " + fieldType); + } + } + + public String papi(Player p, String setpapi) { + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + setpapi = PlaceholderAPI.setPlaceholders(p, setpapi); + } + return ChatColor.translateAlternateColorCodes('&',setpapi); + } + + public void commandTags(Player p, String command) { + String tag = config.getString("config.format.tag") + " "; + //set cp placeholders + command = papi(p, setCpPlaceholders(p, command)); + if (command.split("\\s")[0].equalsIgnoreCase("server=")) { + //this contacts bungee and tells it to send the server change command + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Connect"); + out.writeUTF(command.split("\\s")[1]); + Player player = Bukkit.getPlayerExact(p.getName()); + player.sendPluginMessage(this, "BungeeCord", out.toByteArray()); + } else if (command.split("\\s")[0].equalsIgnoreCase("op=")) { + //if player uses op= it will perform command as op + boolean isop = p.isOp(); + try { + p.setOp(true); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + Bukkit.dispatchCommand(p, ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.setPlaceholders(p, command.replace("op=", "").trim()))); + } else { + Bukkit.dispatchCommand(p, ChatColor.translateAlternateColorCodes('&', command.replace("op=", "").trim())); + } + p.setOp(isop); + } catch (Exception exc) { + p.setOp(isop); + debug(exc); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " op=: Error in op command!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " op=: Error in op command!")); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("console=")) { + //if player uses console= it will perform command in the console + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.setPlaceholders(p, command.replace("console=", "").trim()))); + } else { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ChatColor.translateAlternateColorCodes('&', command.replace("console=", "").trim())); + } + } else if (command.split("\\s")[0].equalsIgnoreCase("buy=")) { + //if player uses buy= it will be eg. buy= + try { + if (econ != null) { + if (econ.getBalance(p) >= Double.parseDouble(command.split("\\s")[1])) { + econ.withdrawPlayer(p, Double.parseDouble(command.split("\\s")[1])); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", command.split("\\s")[1]))); + if (p.getInventory().firstEmpty() >= 0) { + p.getInventory().addItem(new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3]))); + } else { + p.getLocation().getWorld().dropItemNaturally(p.getLocation(), new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3]))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Buying Requires Vault and an Economy to work!")); + } + } catch (Exception buy) { + debug(buy); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " " + "commands: " + command))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " " + "commands: " + command)); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("tokenbuy=")) { + //if player uses tokenbuy= it will be eg. tokenbuy= + try { + if (this.getServer().getPluginManager().isPluginEnabled("TokenManager")) { + TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager"); + int balance = Integer.parseInt(Long.toString(api.getTokens(p).orElse(0))); + if (balance >= Double.parseDouble(command.split("\\s")[1])) { + api.removeTokens(p, Long.parseLong(command.split("\\s")[1])); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", command.split("\\s")[1]))); + if (p.getInventory().firstEmpty() >= 0) { + p.getInventory().addItem(new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3]))); + } else { + p.getLocation().getWorld().dropItemNaturally(p.getLocation(), new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3]))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Buying Requires TokenManager to work!")); + } + } catch (Exception buy) { + debug(buy); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " " + "commands: " + command))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " " + "commands: " + command)); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("sell=")) { + //if player uses sell= it will be eg. sell= [enchanted:KNOCKBACK:1] [potion:JUMP] + try { + if (econ != null) { + boolean sold = false; + for (int f = 0; f < p.getInventory().getSize(); f++) { + ItemStack itm = p.getInventory().getItem(f); + if (itm != null && itm.getType().equals(Material.matchMaterial(command.split("\\s")[2]))) { + //determine if the command contains parameters for extensions + //String enchanted[] = {"false","0"}; + String potion = "false"; + for(String argsTemp : command.split("\\s")){ + /*if(argsTemp.startsWith("enchanted:")){ + enchanted = argsTemp.replace("enchanted:","").split(":"); + }*/ + if(argsTemp.startsWith("potion:")){ + potion = argsTemp.replace("potion:",""); + } + } + //check to ensure any extensions are checked + try { + /*if (!enchanted[0].equals("false")) { + EnchantmentStorageMeta enchMeta = (EnchantmentStorageMeta) itm.getItemMeta(); + enchMeta.addStoredEnchant(Enchantment.getByKey(NamespacedKey.minecraft(enchanted[0].toLowerCase())), Integer.parseInt(enchanted[1]), false); + if (enchMeta.getStoredEnchants().equals(itm.getEnchantments())) { + p.sendMessage("TRUE"); + } + if (itm.getEnchantments().containsKey(Enchantment.getByKey(NamespacedKey.minecraft(enchanted[0].toLowerCase())))) { + if (itm.getEnchantmentLevel(Enchantment.getByKey(NamespacedKey.minecraft(enchanted[0].toLowerCase()))) != Integer.parseInt(enchanted[1])) { + p.sendMessage(papi(p, tag + ChatColor.RED + "Your item needs Enchantment level " + enchanted[1])); + return; + } + } else { + p.sendMessage(papi(p, tag + ChatColor.RED + "Your item has the wrong enchantment")); + return; + } + }*/ + if (!potion.equals("false")) { + PotionMeta potionMeta = (PotionMeta) itm.getItemMeta(); + if (!potionMeta.getBasePotionData().getType().name().equalsIgnoreCase(potion)) { + p.sendMessage(papi(p, tag + ChatColor.RED + "Your item has the wrong potion effect")); + return; + } + } + }catch(Exception exc){ + //skip unless debug enabled + debug(exc); + } + if (itm.getAmount() >= new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3])).getAmount()) { + int amt = itm.getAmount() - new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3])).getAmount(); + itm.setAmount(amt); + p.getInventory().setItem(f, amt > 0 ? itm : null); + econ.depositPlayer(p, Double.parseDouble(command.split("\\s")[1])); + sold = true; + p.updateInventory(); + break; + } + } + } + if (sold == false) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needitems"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.sold").replaceAll("%cp-args%", command.split("\\s")[1]))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Selling Requires Vault and an Economy to work!")); + } + } catch (Exception sell) { + debug(sell); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " " + "commands: " + command))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " " + "commands: " + command)); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("tokensell=")) { + //if player uses tokensell= it will be eg. tokensell= [enchanted:KNOCKBACK:1] [potion:JUMP] + try { + if (this.getServer().getPluginManager().isPluginEnabled("TokenManager")) { + TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager"); + boolean sold = false; + for (int f = 0; f < p.getInventory().getSize(); f++) { + ItemStack itm = p.getInventory().getItem(f); + if (itm != null && itm.getType().equals(Material.matchMaterial(command.split("\\s")[2]))) { + //determine if the command contains parameters for extensions + String potion = "false"; + for(String argsTemp : command.split("\\s")){ + if(argsTemp.startsWith("potion:")){ + potion = argsTemp.replace("potion:",""); + } + } + //check to ensure any extensions are checked + try { + if (!potion.equals("false")) { + PotionMeta potionMeta = (PotionMeta) itm.getItemMeta(); + if (!potionMeta.getBasePotionData().getType().name().equalsIgnoreCase(potion)) { + p.sendMessage(papi(p, tag + ChatColor.RED + "Your item has the wrong potion effect")); + return; + } + } + }catch(Exception exc){ + //skip if it cannot do unless debug is enabled + debug(exc); + } + if (itm.getAmount() >= new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3])).getAmount()) { + int amt = itm.getAmount() - new ItemStack(Material.matchMaterial(command.split("\\s")[2]), Integer.parseInt(command.split("\\s")[3])).getAmount(); + itm.setAmount(amt); + p.getInventory().setItem(f, amt > 0 ? itm : null); + econ.depositPlayer(p, Double.parseDouble(command.split("\\s")[1])); + api.addTokens(p, Long.parseLong(command.split("\\s")[1])); + sold = true; + p.updateInventory(); + break; + } + } + } + if (sold == false) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needitems"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.sold").replaceAll("%cp-args%", command.split("\\s")[1]))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Selling Requires TokenManager to work!")); + } + } catch (Exception sell) { + debug(sell); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " " + "commands: " + command))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " " + "commands: " + command)); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("msg=")) { + //if player uses msg= it will send the player a message + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.setPlaceholders(p, command.replace("msg=", "").trim()))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', command.replace("msg=", "").trim())); + } + } else if (command.split("\\s")[0].equalsIgnoreCase("sound=")) { + //if player uses sound= it will play a sound (sound= [sound]) + try { + p.playSound(p.getLocation(), Sound.valueOf(command.split("\\s")[1]), 1F, 1F); + } catch (Exception s) { + debug(s); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, config.getString("config.format.error") + " " + "commands: " + command))); + } + } else if (command.split("\\s")[0].equalsIgnoreCase("tokenbuycommand=")) { + //if player uses tokenbuycommand [price] [command] + try { + if (this.getServer().getPluginManager().isPluginEnabled("TokenManager")) { + TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager"); + int balance = Integer.parseInt(Long.toString(api.getTokens(p).orElse(0))); + if (balance >= Double.parseDouble(command.split("\\s")[1])) { + api.removeTokens(p, Long.parseLong(command.split("\\s")[1])); + //execute command under here + String commandp = command; + commandp = commandp.replace("tokenbuycommand=", "").trim(); + String price = commandp.split(" ", 2)[0]; + commandp = commandp.split(" ", 2)[1]; + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ChatColor.translateAlternateColorCodes('&', papi(p, commandp))); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", price))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Buying Requires Vault and an Economy to work!")); + } + } catch (Exception buyc) { + debug(buyc); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " " + "commands: " + command))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " " + "commands: " + command)); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("buycommand=")) { + //if player uses buycommand [price] [command] + try { + if (econ != null) { + if (econ.getBalance(p) >= Double.parseDouble(command.split("\\s")[1])) { + econ.withdrawPlayer(p, Double.parseDouble(command.split("\\s")[1])); + //execute command under here + String commandp = command; + commandp = commandp.replace("buycommand=", "").trim(); + String price = commandp.split(" ", 2)[0]; + commandp = commandp.split(" ", 2)[1]; + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ChatColor.translateAlternateColorCodes('&', papi(p, commandp))); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", price))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Buying Requires Vault and an Economy to work!")); + } + } catch (Exception buyc) { + debug(buyc); + if (this.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, config.getString("config.format.error") + " " + "commands: " + command))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.error") + " " + "commands: " + command)); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("teleport=")) { + //if player uses teleport= x y z (optional other player) + if (command.split("\\s").length == 6) { + float x, y, z, yaw, pitch; //pitch is the heads Y axis and yaw is the X axis + x = Float.parseFloat(papi(p, command.split("\\s")[1])); + y = Float.parseFloat(papi(p, command.split("\\s")[2])); + z = Float.parseFloat(papi(p, command.split("\\s")[3])); + yaw = Float.parseFloat(papi(p, command.split("\\s")[4])); + pitch = Float.parseFloat(papi(p, command.split("\\s")[5])); + p.teleport(new Location(p.getWorld(), x, y, z, yaw, pitch)); + } else if (command.split("\\s").length <= 4) { + float x, y, z; + x = Float.parseFloat(papi(p, command.split("\\s")[1])); + y = Float.parseFloat(papi(p, command.split("\\s")[2])); + z = Float.parseFloat(papi(p, command.split("\\s")[3])); + p.teleport(new Location(p.getWorld(), x, y, z)); + } else { + try { + Player otherplayer = Bukkit.getPlayer(papi(p, command.split("\\s")[4])); + float x, y, z; + x = Float.parseFloat(papi(p, command.split("\\s")[1])); + y = Float.parseFloat(papi(p, command.split("\\s")[2])); + z = Float.parseFloat(papi(p, command.split("\\s")[3])); + otherplayer.teleport(new Location(otherplayer.getWorld(), x, y, z)); + } catch (Exception tpe) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.notitem"))); + } + } + } else if (command.split("\\s")[0].equalsIgnoreCase("stopsound=")) { + //if player uses stopsound= [sound] + try { + p.stopSound(Sound.valueOf(command.split("\\s")[1])); + } catch (Exception ss) { + debug(ss); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, config.getString("config.format.error") + " " + "commands: " + command))); + } + } else if (command.split("\\s")[0].equalsIgnoreCase("sudo=")) { + //if player uses sudo= [command] + p.chat(ChatColor.translateAlternateColorCodes('&', papi(p, "/" + command.replaceAll("sudo=", "").trim()))); + } else { + Bukkit.dispatchCommand(p, ChatColor.translateAlternateColorCodes('&', papi(p, command))); + } + } + + public String setCpPlaceholders(Player p, String str) { + String tag = config.getString("config.format.tag") + " "; + //replace nodes with PlaceHolders + str = str.replaceAll("%cp-player-displayname%", p.getDisplayName()); + str = str.replaceAll("%cp-player-name%", p.getName()); + str = str.replaceAll("%cp-player-world%", p.getWorld().getName()); + str = str.replaceAll("%cp-player-x%", String.valueOf(Math.round(p.getLocation().getX()))); + str = str.replaceAll("%cp-player-y%", String.valueOf(Math.round(p.getLocation().getY()))); + str = str.replaceAll("%cp-player-z%", String.valueOf(Math.round(p.getLocation().getZ()))); + str = str.replaceAll("%cp-online-players%", Integer.toString(Bukkit.getServer().getOnlinePlayers().size())); + if (str.contains("%cp-player-online-")) { + int start = str.indexOf("%cp-player-online-"); + int end = str.lastIndexOf("-find%"); + String playerLocation = str.substring(start, end).replace("%cp-player-online-", ""); + Player[] playerFind = Bukkit.getOnlinePlayers().toArray(new Player[Bukkit.getOnlinePlayers().size()]); + if (Integer.parseInt(playerLocation) > playerFind.length) { + str = str.replace(str.substring(start, end) + "-find%", papi(p, ChatColor.translateAlternateColorCodes('&', config.getString("config.format.offline")))); + } else { + str = str.replace(str.substring(start, end) + "-find%", playerFind[Integer.parseInt(playerLocation) - 1].getName()); + } + } + try { + if (econ != null) { + str = str.replaceAll("%cp-player-balance%", String.valueOf(Math.round(econ.getBalance(p)))); + } + } catch (Exception place) { + //skip + } + if (this.getServer().getPluginManager().isPluginEnabled("TokenManager")) { + TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager"); + str = str.replaceAll("%cp-tokenmanager-balance%", Long.toString(api.getTokens(p).orElse(0))); + } + if (this.getServer().getPluginManager().isPluginEnabled("VotingPlugin")) { + str = str.replaceAll("%cp-votingplugin-points%", String.valueOf(UserManager.getInstance().getVotingPluginUser(p).getPoints())); + } + if (str.contains("%cp-player-input%")) { + for (String[] key : userInputStrings) { + if (key[0].equals(p.getName())) { + userInputStrings.add(new String[]{p.getName(), str}); + return "commandpanels:commandpanelclose"; + } + } + userInputStrings.add(new String[]{p.getName(), str}); + List inputMessages = new ArrayList(config.getStringList("config.input-message")); + for (String temp : inputMessages) { + temp = temp.replaceAll("%cp-args%", config.getString("config.input-cancel")); + temp = temp.replaceAll("%cp-tag%", tag); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', papi(p, temp))); + } + str = "commandpanels:commandpanelclose"; + } + //end nodes with PlaceHolders + return str; + } + + public int commandPayWall(Player p, String command) { //return 0 means no funds, 1 is they passed and 2 means paywall is not this command + String tag = config.getString("config.format.tag") + " "; + if (command.split("\\s")[0].equalsIgnoreCase("paywall=")) { + //if player uses paywall= [price] + try { + if (econ != null) { + if (econ.getBalance(p) >= Double.parseDouble(command.split("\\s")[1])) { + econ.withdrawPlayer(p, Double.parseDouble(command.split("\\s")[1])); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", command.split("\\s")[1]))); + return 1; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + return 0; + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Paying Requires Vault and an Economy to work!")); + return 0; + } + } catch (Exception buyc) { + debug(buyc); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, config.getString("config.format.error") + " " + "commands: " + command))); + return 0; + } + } else if (command.split("\\s")[0].equalsIgnoreCase("tokenpaywall=")) { + //if player uses tokenpaywall= [price] + try { + if (getServer().getPluginManager().isPluginEnabled("TokenManager")) { + TokenManager api = (TokenManager) Bukkit.getServer().getPluginManager().getPlugin("TokenManager"); + int balance = Integer.parseInt(Long.toString(api.getTokens(p).orElse(0))); + if (balance >= Double.parseDouble(command.split("\\s")[1])) { + api.removeTokens(p, Long.parseLong(command.split("\\s")[1])); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", command.split("\\s")[1]))); + return 1; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + return 0; + } + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Paying TokenManager to work!")); + return 0; + } + } catch (Exception buyc) { + debug(buyc); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, config.getString("config.format.error") + " " + "commands: " + command))); + return 0; + } + } else if (command.split("\\s")[0].equalsIgnoreCase("xp-paywall=")) { + //if player uses xp-paywall= [price] + try { + int balance = p.getLevel(); + if (balance >= Integer.parseInt(command.split("\\s")[1])) { + p.setLevel(p.getLevel() - Integer.parseInt(command.split("\\s")[1])); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.bought").replaceAll("%cp-args%", command.split("\\s")[1]))); + return 1; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + config.getString("config.format.needmoney"))); + return 0; + } + } catch (Exception buyc) { + debug(buyc); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + papi(p, config.getString("config.format.error") + " " + "commands: " + command))); + return 0; + } + } else { + return 2; + } + } + + public void reloadPanelFiles() { + try { + panelFiles.clear(); + panelNames.clear(); + int count = 0; + for (String fileName : Arrays.asList(panelsf.list())) { + panelFiles.add(YamlConfiguration.loadConfiguration(new File(panelsf + File.separator + fileName))); + for (String tempName : panelFiles.get(count).getConfigurationSection("panels").getKeys(false)) { + panelNames.add(new String[]{tempName, Integer.toString(count)}); + } + count += 1; + } + } catch (NullPointerException noPanels) { + this.getServer().getConsoleSender().sendMessage("[CommandPanels] No panels found to load!"); + } + } + + public void debug(Exception e) { + if (debug) { + e.printStackTrace(); + } + } + + public void helpMessage(CommandSender p) { + String tag = config.getString("config.format.tag") + " "; + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Commands:")); + p.sendMessage(ChatColor.GOLD + "/cp [player:item] [player] " + ChatColor.WHITE + "Open a command panel."); + if (p.hasPermission("commandpanel.reload")) { + p.sendMessage(ChatColor.GOLD + "/cpr " + ChatColor.WHITE + "Reloads plugin config."); + } + p.sendMessage(ChatColor.GOLD + "/cpc " + ChatColor.WHITE + "Close current GUI."); + if (p.hasPermission("commandpanel.generate")) { + p.sendMessage(ChatColor.GOLD + "/cpg " + ChatColor.WHITE + "Generate GUI from popup menu."); + } + if (p.hasPermission("commandpanel.version")) { + p.sendMessage(ChatColor.GOLD + "/cpv " + ChatColor.WHITE + "Display the current version."); + } + if (p.hasPermission("commandpanel.edit")) { + p.sendMessage(ChatColor.GOLD + "/cpe [panel] " + ChatColor.WHITE + "Edit a panel with the Panel Editor."); + } + if (p.hasPermission("commandpanel.list")) { + p.sendMessage(ChatColor.GOLD + "/cpl " + ChatColor.WHITE + "Lists the currently loaded panels."); + } + if (p.hasPermission("commandpanel.debug")) { + p.sendMessage(ChatColor.GOLD + "/cpd " + ChatColor.WHITE + "Enable and Disable debug mode globally."); + } + } + + public final Map colourCodes = new HashMap() {{ + put("AQUA", Color.AQUA); + put("BLUE", Color.BLUE); + put("GRAY", Color.GRAY); + put("GREEN", Color.GREEN); + put("RED", Color.RED); + put("WHITE", Color.WHITE); + put("BLACK", Color.BLACK); + put("FUCHSIA", Color.FUCHSIA); + put("LIME", Color.LIME); + put("MAROON", Color.MAROON); + put("NAVY", Color.NAVY); + put("OLIVE", Color.OLIVE); + put("ORANGE", Color.ORANGE); + put("PURPLE", Color.PURPLE); + put("SILVER", Color.SILVER); + put("TEAL", Color.TEAL); + put("YELLOW", Color.YELLOW); + }}; + + public void openEditorGui(Player p, int pageChange) { + reloadPanelFiles(); + Inventory i = Bukkit.createInventory((InventoryHolder) null, 54, "Command Panels Editor"); + ArrayList panelNames = new ArrayList(); //all panels from ALL files (panel names) + ArrayList panelTitles = new ArrayList(); //all panels from ALL files (panel titles) + ArrayList panelItems = new ArrayList(); //all panels from ALL files (panel materials) + try { + for (YamlConfiguration temp : panelFiles) { //will loop through all the files in folder + String key; + if (!checkPanels(temp)) { + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); ) { + key = (String) var10.next(); + panelNames.add(ChatColor.translateAlternateColorCodes('&', key)); + panelTitles.add(ChatColor.translateAlternateColorCodes('&', temp.getString("panels." + key + ".title"))); + if (temp.contains("panels." + key + ".open-with-item.material")) { + panelItems.add(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material"))); + } else { + panelItems.add(Material.FILLED_MAP); + } + } + } + } catch (Exception fail) { + //could not fetch all panel names (probably no panels exist) + debug(fail); + return; + } + + int pageNumber = 1; + if (p.getOpenInventory().getTitle().equals("Command Panels Editor")) { + pageNumber = Integer.parseInt(ChatColor.stripColor(p.getOpenInventory().getItem(49).getItemMeta().getDisplayName()).replace("Page ", "")); + } + //will add the difference + pageNumber = pageNumber + pageChange; + if (pageNumber <= 0) { + //double check page number IS NOT under 1 + pageNumber = 1; + } + //get amount of pages total + int pagesAmount = (int) Math.ceil(panelNames.size() / 45.0); + //make all the bottom bar items + ItemStack temp; + temp = new ItemStack(Material.SUNFLOWER, 1); + setName(temp, ChatColor.WHITE + "Page " + pageNumber, null, p, true); + i.setItem(49, temp); + temp = new ItemStack(Material.BARRIER, 1); + setName(temp, ChatColor.RED + "Exit Menu", null, p, true); + i.setItem(45, temp); + temp = new ItemStack(Material.BOOK, 1); + List lore = new ArrayList(); + lore.add(ChatColor.GRAY + "- Click on a panel to edit items."); + lore.add(ChatColor.GRAY + "- Right click on a panel to edit settings."); + lore.add(ChatColor.GRAY + "- To edit an item in a panel, shift click"); + lore.add(ChatColor.GRAY + " on the item of choice."); + setName(temp, ChatColor.WHITE + "Panel Editor", lore, p, true); + i.setItem(53, temp); + if (pageNumber != 1) { + //only show previous page button if number is not one + temp = new ItemStack(Material.PAPER, 1); + setName(temp, ChatColor.WHITE + "Previous Page", null, p, true); + i.setItem(48, temp); + } + if (pageNumber < pagesAmount) { + //if page number is under pages amount + temp = new ItemStack(Material.PAPER, 1); + setName(temp, ChatColor.WHITE + "Next Page", null, p, true); + i.setItem(50, temp); + } + int count = 0; + int slot = 0; + for (String panelName : panelNames) { + //count is +1 because count starts at 0 not 1 + if ((pageNumber * 45 - 45) < (count + 1) && (pageNumber * 45) > (count)) { + temp = new ItemStack(panelItems.get(count), 1); + setName(temp, ChatColor.WHITE + panelName, null, p, true); + i.setItem(slot, temp); + slot += 1; + } + count += 1; + } + p.openInventory(i); + } + + public void openPanelSettings(Player p, String panelName, YamlConfiguration cf) { + reloadPanelFiles(); + Inventory i = Bukkit.createInventory((InventoryHolder) null, 27, "Panel Settings: " + panelName); + List lore = new ArrayList(); + ItemStack temp; + //remove if the player already had a string from previously + for (int o = 0; editorInputStrings.size() > o; o++) { + if (editorInputStrings.get(o)[0].equals(p.getName())) { + editorInputStrings.remove(o); + o = o - 1; + } + } + //make all the items + temp = new ItemStack(Material.WRITABLE_BOOK, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Permission required to open panel"); + lore.add(ChatColor.GRAY + "commandpanel.panel.[insert]"); + if (cf.contains("panels." + panelName + ".perm")) { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + "commandpanel.panel." + cf.getString("panels." + panelName + ".perm")); + } + setName(temp, ChatColor.WHITE + "Panel Permission", lore, p,true); + i.setItem(1, temp); + + temp = new ItemStack(Material.NAME_TAG, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Title of the Panel"); + if (cf.contains("panels." + panelName + ".title")) { + lore.add(ChatColor.WHITE + "------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".title")); + } + setName(temp, ChatColor.WHITE + "Panel Title", lore, p,true); + i.setItem(3, temp); + + temp = new ItemStack(Material.JUKEBOX, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Sound when opening panel"); + if (cf.contains("panels." + panelName + ".sound-on-open")) { + lore.add(ChatColor.WHITE + "------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".sound-on-open").toUpperCase()); + } + setName(temp, ChatColor.WHITE + "Panel Sound", lore, p,true); + i.setItem(5, temp); + + temp = new ItemStack(Material.IRON_DOOR, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Custom command to open panel"); + if (cf.contains("panels." + panelName + ".command")) { + lore.add(ChatColor.WHITE + "----------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".command")); + } + setName(temp, ChatColor.WHITE + "Panel Command", lore, p,true); + i.setItem(7, temp); + + temp = new ItemStack(Material.LAVA_BUCKET, 1); + lore.clear(); + lore.add(ChatColor.DARK_RED + "Permanently delete Panel"); + setName(temp, ChatColor.RED + "Delete Panel", lore, p,true); + i.setItem(21, temp); + + temp = new ItemStack(Material.PISTON, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "How many rows the panel will be"); + lore.add(ChatColor.GRAY + "choose an integer from 1 to 6"); + setName(temp, ChatColor.WHITE + "Panel Rows", lore, p,true); + i.setItem(23, temp); + + temp = new ItemStack(Material.BLACK_STAINED_GLASS, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Fill empty slots with an item"); + if (cf.contains("panels." + panelName + ".empty")) { + lore.add(ChatColor.WHITE + "-----------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".empty").toUpperCase()); + } + setName(temp, ChatColor.WHITE + "Panel Empty Item", lore, p,true); + i.setItem(13, temp); + + temp = new ItemStack(Material.COMMAND_BLOCK, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Execute commands when opening"); + lore.add(ChatColor.GRAY + "- Left click to add command"); + lore.add(ChatColor.GRAY + "- Right click to remove command"); + if (cf.contains("panels." + panelName + ".commands-on-open")) { + lore.add(ChatColor.WHITE + "-----------------------------"); + int count = 1; + for (String tempLore : cf.getStringList("panels." + panelName + ".commands-on-open")) { + lore.add(ChatColor.WHITE + Integer.toString(count) + ") " + tempLore); + count += 1; + } + } + setName(temp, ChatColor.WHITE + "Panel Commands", lore, p,true); + i.setItem(15, temp); + + temp = new ItemStack(Material.ITEM_FRAME, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Code name to open panel"); + lore.add(ChatColor.GRAY + "/cp [name]"); + lore.add(ChatColor.WHITE + "-----------------------"); + lore.add(ChatColor.WHITE + panelName); + setName(temp, ChatColor.WHITE + "Panel Name", lore, p,true); + i.setItem(11, temp); + + temp = new ItemStack(Material.BARRIER, 1); + setName(temp, ChatColor.RED + "Back", null, p,true); + i.setItem(18, temp); + + p.openInventory(i); + } + + public void openItemSettings(Player p, String panelName, YamlConfiguration cf, int itemNumber) { + reloadPanelFiles(); + Inventory i = Bukkit.createInventory((InventoryHolder) null, 36, "Item Settings: " + panelName); + List lore = new ArrayList(); + ItemStack temp; + //remove if the player already had a string from previously + for (int o = 0; editorInputStrings.size() > o; o++) { + if (editorInputStrings.get(o)[0].equals(p.getName())) { + editorInputStrings.remove(o); + o = o - 1; + } + } + //make all the items + temp = new ItemStack(Material.NAME_TAG, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Display name of the item in the Panel"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".name")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".name").equals("")) { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".item." + itemNumber + ".name")); + } + } + setName(temp, ChatColor.WHITE + "Item Name", lore, p,true); + i.setItem(1, temp); + + temp = new ItemStack(Material.COMMAND_BLOCK, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Execute commands when item is clicked"); + lore.add(ChatColor.GRAY + "- Left click to add command"); + lore.add(ChatColor.GRAY + "- Right click to remove command"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".commands")) { + lore.add(ChatColor.WHITE + "-----------------------------"); + int count = 1; + for (String tempLore : cf.getStringList("panels." + panelName + ".item." + itemNumber + ".commands")) { + lore.add(ChatColor.WHITE + Integer.toString(count) + ") " + tempLore); + count += 1; + } + } + setName(temp, ChatColor.WHITE + "Item Commands", lore, p,true); + i.setItem(3, temp); + + temp = new ItemStack(Material.EXPERIENCE_BOTTLE, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Display enchantment of the item in the Panel"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".enchanted")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".name").equals("")) { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".item." + itemNumber + ".enchanted")); + } + } else { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + "false"); + } + setName(temp, ChatColor.WHITE + "Item Enchantment", lore, p,true); + i.setItem(5, temp); + + temp = new ItemStack(Material.POTION, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Display potion effect of the item in the Panel"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".potion")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".potion").equals("")) { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".item." + itemNumber + ".potion")); + } + } + setName(temp, ChatColor.WHITE + "Item Potion Effect", lore, p,true); + i.setItem(7, temp); + + temp = new ItemStack(Material.SPRUCE_SIGN, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Display a lore under the item name"); + lore.add(ChatColor.GRAY + "- Left click to add lore line"); + lore.add(ChatColor.GRAY + "- Right click to remove lore line"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".lore")) { + lore.add(ChatColor.WHITE + "-----------------------------"); + int count = 1; + for (String tempLore : cf.getStringList("panels." + panelName + ".item." + itemNumber + ".lore")) { + lore.add(ChatColor.WHITE + Integer.toString(count) + ") " + tempLore); + count += 1; + } + } + setName(temp, ChatColor.WHITE + "Item Lores", lore, p, true); + i.setItem(19, temp); + + temp = new ItemStack(Material.ITEM_FRAME, 2); + lore.clear(); + lore.add(ChatColor.GRAY + "How many of the item will be stacked"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".stack")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".stack").equals("")) { + try { + temp.setAmount(Integer.parseInt(cf.getString("panels." + panelName + ".item." + itemNumber + ".stack"))); + } catch (Exception ex) { + } + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".item." + itemNumber + ".stack")); + } + } + setName(temp, ChatColor.WHITE + "Item Stack Size", lore, p, true); + i.setItem(21, temp); + + temp = new ItemStack(Material.ANVIL, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Add Custom Model Data here"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".customdata")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".customdata").equals("")) { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".item." + itemNumber + ".customdata")); + } + } + setName(temp, ChatColor.WHITE + "Custom Model Data", lore, p, true); + i.setItem(23, temp); + + temp = new ItemStack(Material.LEATHER_HELMET, 1); + lore.clear(); + lore.add(ChatColor.GRAY + "Choose a colour for the armor"); + lore.add(ChatColor.GRAY + "use r,g,b or a spigot API color"); + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".leatherarmor")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".leatherarmor").equals("")) { + lore.add(ChatColor.WHITE + "--------------------------------"); + lore.add(ChatColor.WHITE + cf.getString("panels." + panelName + ".item." + itemNumber + ".leatherarmor")); + } + } + setName(temp, ChatColor.WHITE + "Leather Armor Colour", lore, p, true); + i.setItem(25, temp); + + temp = new ItemStack(Material.BARRIER, 1); + setName(temp, ChatColor.RED + "Back", null, p, true); + i.setItem(27, temp); + + if(cf.getString("panels." + panelName + ".item." + itemNumber + ".material").startsWith("cps=")){ + temp = new ItemStack(Material.PLAYER_HEAD, 1); + if(cf.getString("panels." + panelName + ".item." + itemNumber + ".material").equalsIgnoreCase("cps= self")){ + //if self + SkullMeta meta = (SkullMeta) temp.getItemMeta(); + try { + meta.setOwningPlayer(Bukkit.getOfflinePlayer(p.getUniqueId())); + } catch (Exception var23) { + debug(var23); + } + temp.setItemMeta(meta); + }else{ + //custom head + temp = this.getItem(cf.getString("panels." + panelName + ".item." + itemNumber + ".material").replace("cps=", "").trim()); + } + }else if (cf.getString("panels." + panelName + ".item." + itemNumber + ".material").startsWith("%cp-player-online-")){ + //leave default for the find material tag + temp = new ItemStack(Material.PLAYER_HEAD, 1); + }else if (cf.getString("panels." + panelName + ".item." + itemNumber + ".material").startsWith("hdb=")){ + //head database head + temp = new ItemStack(Material.PLAYER_HEAD, 1); + if (this.getServer().getPluginManager().isPluginEnabled("HeadDatabase")) { + HeadDatabaseAPI api; + api = new HeadDatabaseAPI(); + try { + temp = api.getItemHead(cf.getString("panels." + panelName + ".item." + itemNumber + ".material").replace("hdb=", "").trim()); + } catch (Exception var22) { + debug(var22); + } + } + }else{ + temp = new ItemStack(Material.matchMaterial(cf.getString("panels." + panelName + ".item." + itemNumber + ".material")), 1); + } + try { + temp.setAmount(Integer.parseInt(cf.getString("panels." + panelName + ".item." + itemNumber + ".stack"))); + } catch (Exception ex) { + //skip + } + if (cf.contains("panels." + panelName + ".item." + itemNumber + ".enchanted")) { + if (!cf.getString("panels." + panelName + ".item." + itemNumber + ".enchanted").equals("false")) { + ItemMeta EnchantMeta; + EnchantMeta = temp.getItemMeta(); + EnchantMeta.addEnchant(Enchantment.KNOCKBACK, 1, true); + EnchantMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + temp.setItemMeta(EnchantMeta); + } + } + lore.clear(); + lore.add(ChatColor.GRAY + "Click to set custom material"); + lore.add(ChatColor.GRAY + "typically for custom heads"); + setName(temp, ChatColor.WHITE + "Item Slot " + itemNumber + " Preview", lore, p, true); + i.setItem(35, temp); + + p.openInventory(i); + } + + public Reader getReaderFromStream(InputStream initialStream) throws IOException { + //this reads the encrypted resource files in the jar file + byte[] buffer = IOUtils.toByteArray(initialStream); + Reader targetReader = new CharSequenceReader(new String(buffer)); + return targetReader; + } +} diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanel.java b/src/me/rockyhawk/commandPanels/commands/commandpanel.java new file mode 100644 index 0000000..bf4b7dd --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanel.java @@ -0,0 +1,578 @@ +package me.rockyhawk.commandPanels.commands; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.inventory.ItemStack; + +import java.util.*; + +public class commandpanel implements CommandExecutor { + commandpanels plugin; + + public commandpanel(commandpanels pl) { + this.plugin = pl; + } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + YamlConfiguration cf = null; //this is the file to use for any panel.* requests + String panels = ""; + ArrayList apanels = new ArrayList(); //all panels from all files (titles of panels) + ArrayList opanels = new ArrayList(); //all panels from all files (raw names of panels) + boolean found = false; + //below is going to go through the files and find the right one + if (args.length != 0) { //check to make sure the person hasn't just left it empty + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + if(!plugin.checkPanels(temp)){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + ": Panel with syntax error found!")); + return true; + } + for (String key : temp.getConfigurationSection("panels").getKeys(false)) { + apanels.add(temp.getString("panels." + key + ".title")); + opanels.add(key); + if (args[0].equalsIgnoreCase(key)){ + found = true; + panels = key; + cf = temp; + } + } + } + }else{ + plugin.helpMessage(sender); + return true; + } + if(!found){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + return true; + } + //below will start the command, once it got the right file and panel + if (cmd.getName().equalsIgnoreCase("cp") || cmd.getName().equalsIgnoreCase("commandpanel") || cmd.getName().equalsIgnoreCase("cpanel")) { + //if command executed from console + if(!(sender instanceof Player)) { + if(args.length == 2){ + if(!args[1].equals("item")){ + boolean nfound = true; + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = panels.split("\\s")[i]; + nfound = false; + } + } + Player sp; + try { + sp = plugin.getServer().getPlayer(args[1]); + }catch(Exception e){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + return true; + } + if (nfound) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(sp, plugin.config.getString("config.format.nopanel")))); + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return true; + }else if (!checkconfig(panels, sp, cf)) { + //if the config is missing an element (message will be sent to user via the public boolean) + return true; + } + if (sender.hasPermission("commandpanel.panel." + cf.getString("panels." + panels + ".perm"))) { + if(sender.hasPermission("commandpanel.other")) { + try { + if (cf.contains("panels." + panels + ".disabled-worlds")) { + List disabledWorlds = (List) cf.getList("panels." + panels + ".disabled-worlds"); + if (disabledWorlds.contains(sp.getWorld().getName())) { + //panel cannot be used in the players world! + if (plugin.config.getString("config.disabled-world-message").equalsIgnoreCase("true")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Panel is disabled in players world!")); + } + return true; + } + } + }catch(NullPointerException offlinePlayer){ + //SKIP because player is offline + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + return true; + } + try { + if (cf.contains("panels." + panels + ".sound-on-open")) { + //play sound when panel is opened + if(!cf.getString("panels." + panels + ".sound-on-open").equalsIgnoreCase("off")) { + try { + sp.playSound(sp.getLocation(), Sound.valueOf(cf.getString("panels." + panels + ".sound-on-open").toUpperCase()), 1F, 1F); + } catch (Exception s) { + sp.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + plugin.papi(sp, plugin.config.getString("config.format.error") + " " + "sound-on-open: " + cf.getString("panels." + panels + ".sound-on-open")))); + } + } + } + if (cf.contains("panels." + panels + ".commands-on-open")) { + //execute commands on panel open + try { + List commands = (List) cf.getList("panels." + panels + ".commands-on-open"); + for (int i = 0; commands.size() - 1 >= i; i++) { + int val = plugin.commandPayWall(sp,commands.get(i)); + if(val == 0){ + break; + } + if(val == 2){ + plugin.commandTags(sp, commands.get(i)); + } + } + }catch(Exception s){ + sp.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + plugin.papi(sp, plugin.config.getString("config.format.error") + " " + "commands-on-open: " + cf.getString("panels." + panels + ".commands-on-open")))); + } + } + plugin.openGui(panels, sp, cf,1,0); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Panel Opened for " + sp.getDisplayName())); + } catch (Exception r) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + } + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + } + return true; + } + + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(sp, plugin.config.getString("config.format.perms")))); + return true; + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cp [item/edit] [player]")); + return true; + } + }else if(args.length == 3){ + if (args[1].equals("item")) { + boolean nfound = true; + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = panels.split("\\s")[i]; + nfound = false; + } + } + Player sp; + try { + sp = plugin.getServer().getPlayer(args[1]); + }catch(Exception e){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + return true; + } + if (nfound) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(sp, plugin.config.getString("config.format.nopanel")))); + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return true; + } + + if (sender.hasPermission("commandpanel.item." + cf.getString("panels." + panels + ".perm")) && cf.contains("panels." + panels + ".open-with-item")) { + if(cf.contains("panels." + panels + ".disabled-worlds")){ + List disabledWorlds = (List) cf.getList("panels." + panels + ".disabled-worlds"); + if(disabledWorlds.contains(sp.getWorld().getName())){ + //panel cannot be used in the players world! + if(plugin.config.getString("config.disabled-world-message").equalsIgnoreCase("true")){ + sp.sendMessage(ChatColor.RED + "Panel is disabled in this world!"); + } + return true; + } + } + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(cf.getString("panels." + panels + ".open-with-item.material")), 1); + }catch(Exception n){ + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(sp, plugin.config.getString("config.format.error") + " open-with-item: material"))); + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " open-with-item: material")); + } + return true; + } + plugin.setName(s, cf.getString("panels." + panels + ".open-with-item.name"), cf.getList("panels." + panels + ".open-with-item.lore"),sp,true); + if(sender.hasPermission("commandpanel.other")) { + try { + plugin.getServer().getPlayer(args[2]).getInventory().addItem(s); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Item Given to " + plugin.getServer().getPlayer(args[2]).getDisplayName())); + } catch (Exception r) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + } + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + } + return true; + } + if (!cf.contains("panels." + panels + ".open-with-item")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(sp, plugin.config.getString("config.format.noitem")))); + return true; + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.noitem"))); + return true; + } + } + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(sp, plugin.config.getString("config.format.perms")))); + return true; + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cp item [player]")); + return true; + } + } else { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Please execute command directed to a Player!")); + return true; + } + } + Player p = (Player) sender; + //names is a list of the titles for the Panels + Set oset = new HashSet(opanels); + if (oset.size() < opanels.size()) { + //there are duplicate panel names + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + " panels: You cannot have duplicate panel names!"))); + if(plugin.debug){ + ArrayList opanelsTemp = new ArrayList(); + for(String tempName : opanels){ + if(opanelsTemp.contains(tempName)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + " The duplicate panel is: " + tempName)); + return true; + } + opanelsTemp.add(tempName); + } + } + return true; + } + Set set = new HashSet(apanels); + if (set.size() < apanels.size()) { + //there are duplicate panel titles + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + " title: You cannot have duplicate title names!"))); + if(plugin.debug){ + ArrayList apanelsTemp = new ArrayList(); + for(String tempName : apanels){ + if(apanelsTemp.contains(tempName)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + " The duplicate title is: " + tempName)); + return true; + } + apanelsTemp.add(tempName); + } + } + return true; + } + + if (args.length == 1) { + boolean nfound = true; + + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = panels.split("\\s")[i]; + nfound = false; + } + } + if (nfound) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.nopanel")))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return true; + }else if (!checkconfig(panels, p, cf)) { + //if the config is missing an element (message will be sent to user via the public boolean) + return true; + } + if (p.hasPermission("commandpanel.panel." + cf.getString("panels." + panels + ".perm"))) { + if(cf.contains("panels." + panels + ".disabled-worlds")){ + List disabledWorlds = (List) cf.getList("panels." + panels + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + //panel cannot be used in the players world! + if(plugin.config.getString("config.disabled-world-message").equalsIgnoreCase("true")){ + p.sendMessage(ChatColor.RED + "Panel is disabled in this world!"); + } + return true; + } + } + if (cf.contains("panels." + panels + ".sound-on-open")) { + //play sound when panel is opened + if(!cf.getString("panels." + panels + ".sound-on-open").equalsIgnoreCase("off")) { + try { + p.playSound(p.getLocation(), Sound.valueOf(cf.getString("panels." + panels + ".sound-on-open").toUpperCase()), 1F, 1F); + } catch (Exception s) { + plugin.debug(s); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + plugin.papi(p, plugin.config.getString("config.format.error") + " " + "sound-on-open: " + cf.getString("panels." + panels + ".sound-on-open")))); + } + } + } + if (cf.contains("panels." + panels + ".commands-on-open")) { + //execute commands on panel open + try { + List commands = (List) cf.getList("panels." + panels + ".commands-on-open"); + for (int i = 0; commands.size() - 1 >= i; i++) { + int val = plugin.commandPayWall(p,commands.get(i)); + if(val == 0){ + break; + } + if(val == 2){ + plugin.commandTags(p, commands.get(i)); + } + } + }catch(Exception s){ + plugin.debug(s); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + plugin.papi(p, plugin.config.getString("config.format.error") + " " + "commands-on-open: " + cf.getString("panels." + panels + ".commands-on-open")))); + } + } + plugin.openGui(panels, p, cf, 1,0); + return true; + } + + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.perms")))); + return true; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + if (args.length == 2) { + if (args[1].equals("item")) { + boolean nfound = true; + + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = panels.split("\\s")[i]; + nfound = false; + } + } + + if (nfound) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.nopanel")))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return true; + } + + if (p.hasPermission("commandpanel.item." + cf.getString("panels." + panels + ".perm")) && cf.contains("panels." + panels + ".open-with-item")) { + if(cf.contains("panels." + panels + ".disabled-worlds")){ + List disabledWorlds = (List) cf.getList("panels." + panels + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + //panel cannot be used in the players world! + if(plugin.config.getString("config.disabled-world-message").equalsIgnoreCase("true")){ + p.sendMessage(ChatColor.RED + "Panel is disabled in this world!"); + } + return true; + } + } + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(cf.getString("panels." + panels + ".open-with-item.material")), 1); + }catch(Exception n){ + plugin.debug(n); + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " open-with-item: material"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " open-with-item: material")); + } + return true; + } + plugin.setName(s, cf.getString("panels." + panels + ".open-with-item.name"), cf.getList("panels." + panels + ".open-with-item.lore"),p,true); + if(cf.contains("panels." + panels + ".open-with-item.stationary")) { + p.getInventory().setItem(Integer.parseInt(cf.getString("panels." + panels + ".open-with-item.stationary")), s); + }else{ + p.getInventory().addItem(s); + } + return true; + } + if (!cf.contains("panels." + panels + ".open-with-item")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.noitem")))); + return true; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.noitem"))); + return true; + } + } + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.perms")))); + return true; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + }else { //player name here eg /cp example RockyHawk to get rockyhawk to open panel + boolean nfound = true; + + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = args[0]; + nfound = false; + } + } + if (nfound) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.nopanel")))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return true; + }else if (!checkconfig(panels, p, cf)) { + //if the config is missing an element (message will be sent to user via the public boolean) + return true; + } + if (p.hasPermission("commandpanel.panel." + cf.getString("panels." + panels + ".perm"))) { + if(p.hasPermission("commandpanel.other")) { + if(cf.contains("panels." + panels + ".disabled-worlds")){ + List disabledWorlds = (List) cf.getList("panels." + panels + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + //panel cannot be used in the players world! + if(plugin.config.getString("config.disabled-world-message").equalsIgnoreCase("true")){ + p.sendMessage(ChatColor.RED + "Panel is disabled in this world!"); + } + return true; + } + } + try { + plugin.openGui(panels, plugin.getServer().getPlayer(args[1]), cf,1,0); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Panel Opened for " + plugin.getServer().getPlayer(args[1]).getDisplayName())); + } catch (Exception r) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + } + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + } + return true; + } + + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.perms")))); + return true; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + } + if (args.length == 3) { + //if the command is /cp example item to give other player item + if (args[1].equals("item")) { + boolean nfound = true; + + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = panels.split("\\s")[i]; + nfound = false; + } + } + + if (nfound) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.nopanel")))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return true; + } + + if (p.hasPermission("commandpanel.item." + cf.getString("panels." + panels + ".perm")) && cf.contains("panels." + panels + ".open-with-item")) { + if(cf.contains("panels." + panels + ".disabled-worlds")){ + List disabledWorlds = (List) cf.getList("panels." + panels + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + //panel cannot be used in the players world! + if(plugin.config.getString("config.disabled-world-message").equalsIgnoreCase("true")){ + p.sendMessage(ChatColor.RED + "Panel is disabled in this world!"); + } + return true; + } + } + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(cf.getString("panels." + panels + ".open-with-item.material")), 1); + }catch(Exception n){ + plugin.debug(n); + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " open-with-item: material"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " open-with-item: material")); + } + return true; + } + plugin.setName(s, cf.getString("panels." + panels + ".open-with-item.name"), cf.getList("panels." + panels + ".open-with-item.lore"),p,true); + if(p.hasPermission("commandpanel.other")) { + try { + if(cf.contains("panels." + panels + ".open-with-item.stationary")) { + p.getInventory().setItem(Integer.parseInt(cf.getString("panels." + panels + ".open-with-item.stationary")), s); + }else{ + p.getInventory().addItem(s); + } + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Item Given to " + plugin.getServer().getPlayer(args[2]).getDisplayName())); + } catch (Exception r) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.notitem"))); + } + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + } + return true; + } + if (!cf.contains("panels." + panels + ".open-with-item")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.noitem")))); + return true; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.noitem"))); + return true; + } + } + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.perms")))); + return true; + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cp [player:item] [player]")); + return true; + } + + boolean checkconfig(String panels, Player p, YamlConfiguration pconfig) { + //if it is missing a section specified it will return false + String tag = plugin.config.getString("config.format.tag") + " "; + if(!pconfig.contains("panels." + panels)) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.nopanel")))); + return false; + } + if(!pconfig.contains("panels." + panels + ".perm")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + " perm: Missing config section!"))); + return false; + } + if(!pconfig.contains("panels." + panels + ".rows")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + " rows: Missing config section!"))); + return false; + } + if(!pconfig.contains("panels." + panels + ".title")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + " title: Missing config section!"))); + return false; + } + if(!pconfig.contains("panels." + panels + ".item")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + " item: Missing config section!"))); + return false; + } + return true; + } +} diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanelclose.java b/src/me/rockyhawk/commandPanels/commands/commandpanelclose.java new file mode 100644 index 0000000..745e55c --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanelclose.java @@ -0,0 +1,32 @@ +package me.rockyhawk.commandPanels.commands; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +public class commandpanelclose implements CommandExecutor { + commandpanels plugin; + public commandpanelclose(commandpanels pl) { this.plugin = pl; } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + if(!(sender instanceof Player)) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Please execute command as a Player!")); + return true; + } + Player p = (Player)sender; + + if (cmd.getName().equalsIgnoreCase("cpc") || cmd.getName().equalsIgnoreCase("commandpanelclose") && sender instanceof Player || cmd.getName().equalsIgnoreCase("cpanelc") && sender instanceof Player) { + p.closeInventory(); + return true; + } + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpc")); + return true; + } +} diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanelcustom.java b/src/me/rockyhawk/commandPanels/commands/commandpanelcustom.java new file mode 100644 index 0000000..0e35b7a --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanelcustom.java @@ -0,0 +1,82 @@ +package me.rockyhawk.commandPanels.commands; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.*; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +public class commandpanelcustom implements Listener { + commandpanels plugin; + public commandpanelcustom(commandpanels pl) { + this.plugin = pl; + } + @EventHandler + public void PlayerCommand(PlayerCommandPreprocessEvent e) { + String panels; + String tag = plugin.config.getString("config.format.tag") + " "; + Player p = (Player)e.getPlayer(); + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + ArrayList filenames = new ArrayList(Arrays.asList(panelsf.list())); + YamlConfiguration cf; //this is the file to use for any panel.* requests + ArrayList apanels = new ArrayList(); //all panels from all files (panel names) + String tpanels; //tpanels is the temp to check through the files + String panel = null; + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + ": File with no Panels found!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + ": File with no Panels found!")); + } + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + apanels.add(key); + } + tpanels = tpanels.trim(); + //check if the requested panel is in the file (then set the config to that panel file) + for(int i = 0; i < tpanels.split("\\s").length;i++){ + if(temp.contains("panels." + tpanels.split("\\s")[i] + ".command")) { + for(int c = 0; c < temp.getString("panels." + tpanels.split("\\s")[i] + ".command").split("\\s").length;c++) { + if (("/" + temp.getString("panels." + tpanels.split("\\s")[i] + ".command").split("\\s")[c]).equalsIgnoreCase(e.getMessage())) { + panels = tpanels; + panels = panels.trim(); + panel = panels.split("\\s")[i]; + break; + } + } + } + } + } + if(panel == null){ + return; + } + e.setCancelled(true); + try { + Bukkit.dispatchCommand(p, ChatColor.translateAlternateColorCodes('&', "commandpanel " + panel)); + }catch(Exception er){ + //do nothing + p.sendMessage(ChatColor.translateAlternateColorCodes('&',plugin.papi(p,tag + ChatColor.RED + "Error opening panel!"))); + } + } +} diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanelsdebug.java b/src/me/rockyhawk/commandPanels/commands/commandpanelsdebug.java new file mode 100644 index 0000000..5bbe9c3 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanelsdebug.java @@ -0,0 +1,39 @@ +package me.rockyhawk.commandPanels.commands; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; + +public class commandpanelsdebug implements CommandExecutor { + commandpanels plugin; + public commandpanelsdebug(commandpanels pl) { this.plugin = pl; } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + if (label.equalsIgnoreCase("cpd") || label.equalsIgnoreCase("commandpanelsdebug") || label.equalsIgnoreCase("cpaneld")) { + if (sender.hasPermission("commandpanel.debug")) { + if (args.length == 0) { + //command /cpd + plugin.debug = !plugin.debug; + if(plugin.debug){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Debug Mode Enabled!")); + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Debug Mode Disabled!")); + } + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpd")); + } + return true; + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpd")); + return true; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanelslist.java b/src/me/rockyhawk/commandPanels/commands/commandpanelslist.java new file mode 100644 index 0000000..17d4fd7 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanelslist.java @@ -0,0 +1,94 @@ +package me.rockyhawk.commandPanels.commands; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.EventHandler; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + + +public class commandpanelslist implements CommandExecutor { + commandpanels plugin; + public commandpanelslist(commandpanels pl) { this.plugin = pl; } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + if (label.equalsIgnoreCase("cpl") || label.equalsIgnoreCase("commandpanellist") || label.equalsIgnoreCase("cpanell")) { + if (sender.hasPermission("commandpanel.list")) { + //command /cpl + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + //check to make sure the panels folder isn't empty + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "No panels found!")); + return true; + } + }catch(Exception b){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "No panels found!")); + return true; + } + ArrayList filenames = new ArrayList(Arrays.asList(panelsf.list())); + ArrayList apanels = new ArrayList(); //all panels from all files (panel names) + String tpanels; //tpanels is the temp to check through the files + for (int f = 0; filenames.size() > f; f++) { //will loop through all the files in folder + String key; + YamlConfiguration temp; + tpanels = ""; + temp = YamlConfiguration.loadConfiguration(new File(panelsf + File.separator + filenames.get(f))); + apanels.add("%file%" + filenames.get(f)); + if(!plugin.checkPanels(temp)){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + ": File with no Panels found!")); + return true; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + apanels.add(key); + } + } + int page = 1; + int skip = 0; + if(args.length == 1){ + try { + page = Integer.parseInt(args[0]); + skip = page*9-9; + }catch (Exception e){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Inaccessible Page")); + } + } + for (int f = skip; apanels.size() > f; f++) { + if(!apanels.get(f).contains("%file%")){ + skip++; + }else{ + break; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.DARK_AQUA + "Panels: (Page " + page + ")")); + for (int f = skip; apanels.size() > f; f++) { + if(apanels.get(f).contains("%file%")){ + if(skip+9 <= f){ + sender.sendMessage(ChatColor.AQUA + "Type /cpl " + (page+1) + " to read next page"); + break; + } + sender.sendMessage(ChatColor.DARK_GREEN + apanels.get(f).replaceAll("%file%","").replaceAll(".yml","")); + }else{ + sender.sendMessage(ChatColor.GREEN + "- " + apanels.get(f)); + } + } + return true; + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpl")); + return true; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanelsreload.java b/src/me/rockyhawk/commandPanels/commands/commandpanelsreload.java new file mode 100644 index 0000000..44057f4 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanelsreload.java @@ -0,0 +1,35 @@ +package me.rockyhawk.commandPanels.commands; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.EventHandler; + +import java.io.File; + +public class commandpanelsreload implements CommandExecutor { + commandpanels plugin; + public commandpanelsreload(commandpanels pl) { this.plugin = pl; } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + if (label.equalsIgnoreCase("cpr") || label.equalsIgnoreCase("commandpanelsreload") || label.equalsIgnoreCase("cpanelr")) { + if (sender.hasPermission("commandpanel.reload")) { + plugin.config = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder() + File.separator + "config.yml")); + plugin.reloadPanelFiles(); + tag = plugin.config.getString("config.format.tag") + " "; + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.reload"))); + return true; + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpr")); + return true; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/commands/commandpanelversion.java b/src/me/rockyhawk/commandPanels/commands/commandpanelversion.java new file mode 100644 index 0000000..f3392eb --- /dev/null +++ b/src/me/rockyhawk/commandPanels/commands/commandpanelversion.java @@ -0,0 +1,34 @@ +package me.rockyhawk.commandPanels.commands; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.EventHandler; + +public class commandpanelversion implements CommandExecutor { + commandpanels plugin; + public commandpanelversion(commandpanels pl) { this.plugin = pl; } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + + if (label.equalsIgnoreCase("cpv") || label.equalsIgnoreCase("commandpanelversion") || label.equalsIgnoreCase("cpanelv")) { + if (sender.hasPermission("commandpanel.version")) { + //version command + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag)); + sender.sendMessage(ChatColor.GREEN + "Version " + ChatColor.GRAY + plugin.getDescription().getVersion()); + sender.sendMessage(ChatColor.GREEN + "Developer " + ChatColor.GRAY + "RockyHawk"); + sender.sendMessage(ChatColor.GREEN + "Command " + ChatColor.GRAY + "/cp"); + return true; + }else{ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpv")); + return true; + } +} diff --git a/src/me/rockyhawk/commandPanels/completeTabs/cpTabComplete.java b/src/me/rockyhawk/commandPanels/completeTabs/cpTabComplete.java new file mode 100644 index 0000000..a538fe4 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/completeTabs/cpTabComplete.java @@ -0,0 +1,59 @@ +package me.rockyhawk.commandPanels.completeTabs; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +public class cpTabComplete implements TabCompleter { + commandpanels plugin; + public cpTabComplete(commandpanels pl) { this.plugin = pl; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { + if(sender instanceof Player && args.length == 1){ + Player p = ((Player) sender).getPlayer(); + if(label.equalsIgnoreCase("cp") || label.equalsIgnoreCase("cpanel") || label.equalsIgnoreCase("commandpanel")){ + ArrayList apanels = new ArrayList(); //all panels + String tpanels; //tpanels is the temp to check through the files + try { + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return null; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if(!key.startsWith(args[0])){ + //this will narrow down the panels to what the user types + continue; + } + if(sender.hasPermission("commandpanel.panel." + temp.getString("panels." + key + ".perm"))) { + if(temp.contains("panels." + key + ".disabled-worlds")){ + List disabledWorlds = (List) temp.getList("panels." + key + ".disabled-worlds"); + if(!disabledWorlds.contains(p.getWorld().getName())){ + apanels.add(key); + } + }else{ + apanels.add(key); + } + } + } + //if file contains opened panel then start + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + } + return apanels; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/generatePanels/commandpanelsgenerate.java b/src/me/rockyhawk/commandPanels/generatePanels/commandpanelsgenerate.java new file mode 100644 index 0000000..086e9f4 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/generatePanels/commandpanelsgenerate.java @@ -0,0 +1,53 @@ +package me.rockyhawk.commandPanels.generatePanels; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + + +public class commandpanelsgenerate implements CommandExecutor { + commandpanels plugin; + public commandpanelsgenerate(commandpanels pl) { this.plugin = pl; } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + if(!(sender instanceof Player)) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Please execute command as a Player!")); + return true; + } + Player p = (Player) sender; + if (label.equalsIgnoreCase("cpg") || label.equalsIgnoreCase("commandpanelgenerate") || label.equalsIgnoreCase("cpanelg")) { + if (p.hasPermission("commandpanel.generate")) { + if (args.length == 1) { + //command /cpg + try { + if (Integer.parseInt(args[0]) >= 1 && Integer.parseInt(args[0]) <= 6) { + Inventory i = Bukkit.createInventory((InventoryHolder) null, Integer.parseInt(args[0]) * 9, "Generate New Panel"); + p.openInventory(i); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Please use integer from 1-6.")); + } + }catch(Exception exc){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Please use integer from 1-6.")); + } + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpg [rows]")); + } + return true; + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + } + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpg [rows]")); + return true; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/generatePanels/newGenUtils.java b/src/me/rockyhawk/commandPanels/generatePanels/newGenUtils.java new file mode 100644 index 0000000..fb66619 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/generatePanels/newGenUtils.java @@ -0,0 +1,126 @@ +package me.rockyhawk.commandPanels.generatePanels; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.*; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +public class newGenUtils implements Listener { + public YamlConfiguration tempEdit; + commandpanels plugin; + public newGenUtils(commandpanels pl) { + this.plugin = pl; + this.tempEdit = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder() + File.separator + "temp.yml")); + } + @EventHandler + public void onInventoryClose(InventoryCloseEvent e) { + String tag = plugin.config.getString("config.format.tag") + " "; + Player p = (Player)e.getPlayer(); + if (!ChatColor.stripColor(e.getView().getTitle()).equals("Generate New Panel")){ + return; + } + //reload panel files to avoid conflicts + plugin.reloadPanelFiles(); + //get all panel names (not titles) + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + Boolean pexist = true; + //pexist is true if panels exist + YamlConfiguration cf; + ArrayList apanels = new ArrayList(); //all panels from all files (panel names) + try { + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + if(!plugin.checkPanels(temp)){ + continue; + } + for (String key : temp.getConfigurationSection("panels").getKeys(false)) { + apanels.add(key); + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + pexist = false; + } + ItemStack[] cont = e.getInventory().getContents(); + boolean foundItem = false; + for(ItemStack temp : cont){ + if(temp != null){ + foundItem = true; + break; + } + } + if(!foundItem){ + //panels don't need items but I cancel on generate with no items because then players have the option to cancel if they need to + p.sendMessage(plugin.papi(p,tag + ChatColor.RED + "Cancelled Panel!")); + return; + } + YamlConfiguration file; + //String date: is what the panel and file name will be called + String date = "panel-1"; + if(pexist){ + for(int count = 1; (Arrays.asList(panelsf.list()).contains("panel-" + count + ".yml")) || (apanels.contains("panel-" + count)); count++){ + date = "panel-" + (count+1); + } + }else{ + date = "panel-1"; + } + //String date = new SimpleDateFormat("dd-HH-mm-ss").format(new Date()); + File folder = new File(plugin.getDataFolder() + File.separator + "panels"); + file = YamlConfiguration.loadConfiguration(new File(folder + File.separator + date + ".yml")); + file.addDefault("panels." + date + ".perm", "default"); + file.addDefault("panels." + date + ".rows", e.getInventory().getSize()/9); + file.addDefault("panels." + date + ".title", "&8Generated " + date); + file.addDefault("panels." + date + ".command", date); + file.addDefault("panels." + date + ".empty", "BLACK_STAINED_GLASS_PANE"); + for(int i = 0; cont.length > i; i++){ + //repeat through all the items in the chest + try{ + //make the item here + if(cont[i].getType() == Material.PLAYER_HEAD){ + if(plugin.getHeadBase64(cont[i]) != null){ + file.addDefault("panels." + date + ".item." + i + ".material", "cps= " + plugin.getHeadBase64(cont[i])); + }else{ + file.addDefault("panels." + date + ".item." + i + ".material", cont[i].getType().toString()); + } + }else { + file.addDefault("panels." + date + ".item." + i + ".material", cont[i].getType().toString()); + } + if(cont[i].getAmount() != 1){ + file.addDefault("panels." + date + ".item." + i + ".stack", cont[i].getAmount()); + } + if(!cont[i].getEnchantments().isEmpty()){ + file.addDefault("panels." + date + ".item." + i + ".enchanted", "true"); + } + try { + PotionMeta potionMeta = (PotionMeta) cont[i].getItemMeta(); + file.addDefault("panels." + date + ".item." + i + ".potion", potionMeta.getBasePotionData().getType().name()); + } catch (Exception er) { + //don't add the effect + } + file.addDefault("panels." + date + ".item." + i + ".name", cont[i].getItemMeta().getDisplayName()); + file.addDefault("panels." + date + ".item." + i + ".lore", cont[i].getItemMeta().getLore()); + }catch(Exception n){ + //skip over an item that spits an error + } + } + file.options().copyDefaults(true); + try { + file.save(new File(folder + File.separator + date + ".yml")); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Saved Generated File To: " + date + ".yml")); + } catch (IOException s) { + plugin.debug(s); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Could Not Save Generated Panel!")); + } + plugin.reloadPanelFiles(); + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/generatePanels/tabCompleteGenerate.java b/src/me/rockyhawk/commandPanels/generatePanels/tabCompleteGenerate.java new file mode 100644 index 0000000..af0d0d6 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/generatePanels/tabCompleteGenerate.java @@ -0,0 +1,34 @@ +package me.rockyhawk.commandPanels.generatePanels; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + + +public class tabCompleteGenerate implements TabCompleter { + commandpanels plugin; + public tabCompleteGenerate(commandpanels pl) { this.plugin = pl; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { + if(sender instanceof Player && args.length == 1){ + if(label.equalsIgnoreCase("cpg") || label.equalsIgnoreCase("cpanelg") || label.equalsIgnoreCase("commandpanelgenerate")){ + if(sender.hasPermission("commandpanel.generate")) { + ArrayList apanels = new ArrayList(); //all panels + apanels.add("1"); + apanels.add("2"); + apanels.add("3"); + apanels.add("4"); + apanels.add("5"); + apanels.add("6"); + return apanels; + } + } + } + return null; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/ingameEditor/cpIngameEditCommand.java b/src/me/rockyhawk/commandPanels/ingameEditor/cpIngameEditCommand.java new file mode 100644 index 0000000..9df5673 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/ingameEditor/cpIngameEditCommand.java @@ -0,0 +1,199 @@ +package me.rockyhawk.commandPanels.ingameEditor; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import java.io.File; +import java.util.*; + +public class cpIngameEditCommand implements CommandExecutor { + commandpanels plugin; + + public cpIngameEditCommand(commandpanels pl) { + this.plugin = pl; + } + + @EventHandler + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + String tag = plugin.config.getString("config.format.tag") + " "; + if(!sender.hasPermission("commandpanel.edit")){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.perms"))); + return true; + } + if(plugin.config.getString("config.ingame-editor").equalsIgnoreCase("false")){ + //this will cancel every /cpe command if ingame-editor is set to false + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Editor disabled!")); + return true; + } + if(!(sender instanceof Player)) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Please execute command as a Player!")); + return true; + } + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + ArrayList filenames = new ArrayList(Arrays.asList(panelsf.list())); + File panelscf = new File(plugin.getDataFolder() + File.separator + "panels" + File.separator + "example.yml"); //cf == correct file + YamlConfiguration cf; //this is the file to use for any panel.* requests + String panels = ""; + ArrayList apanels = new ArrayList(); //all panels from all files (titles of panels) + ArrayList opanels = new ArrayList(); //all panels from all files (raw names of panels) + String tpanels; //tpanels is the temp to check through the files + //below is going to go through the files and find the right one + if (args.length != 0) { //check to make sure the person hasn't just left it empty + for (int f = 0; filenames.size() > f; f++) { //will loop through all the files in folder + String key; + YamlConfiguration temp; + tpanels = ""; + temp = YamlConfiguration.loadConfiguration(new File(panelsf + File.separator + filenames.get(f))); + if(!plugin.checkPanels(temp)){ + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + ": File with no Panels found!")); + return true; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + apanels.add(temp.getString("panels." + key + ".title")); + opanels.add(key); + } + tpanels = tpanels.trim(); + //check if the requested panel is in the file + boolean nfound = true; + for (int i = 0; tpanels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(tpanels.split("\\s")[i])) { + tpanels = tpanels.split("\\s")[i]; + nfound = false; + } + } + //if nfound is true it was not found + if(!nfound){ + panels = tpanels; + panelscf = new File(panelsf + File.separator + filenames.get(f)); + } + } + panels = panels.trim(); + } + cf = YamlConfiguration.loadConfiguration(panelscf); + //below will start the command, once it got the right file and panel + if (cmd.getName().equalsIgnoreCase("cpe") || cmd.getName().equalsIgnoreCase("commandpaneledit") || cmd.getName().equalsIgnoreCase("cpanele")) { + Player p = (Player) sender; + //names is a list of the titles for the Panels + Set oset = new HashSet(opanels); + if (oset.size() < opanels.size()) { + //there are duplicate panel names + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " panels: You cannot have duplicate panel names!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " panels: You cannot have duplicate panel names!")); + } + if(plugin.debug){ + ArrayList opanelsTemp = new ArrayList(); + for(String tempName : opanels){ + if(opanelsTemp.contains(tempName)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + " The duplicate panel is: " + tempName)); + return true; + } + opanelsTemp.add(tempName); + } + } + return true; + } + Set set = new HashSet(apanels); + if (set.size() < apanels.size()) { + //there are duplicate panel names + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " title: You cannot have duplicate title names!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " title: You cannot have duplicate title names!")); + } + if(plugin.debug){ + ArrayList apanelsTemp = new ArrayList(); + for(String tempName : apanels){ + if(apanelsTemp.contains(tempName)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + " The duplicate title is: " + tempName)); + return true; + } + apanelsTemp.add(tempName); + } + } + return true; + } + if (args.length == 0) { + plugin.openEditorGui(p,0); + return true; + } + if (args.length == 1) { + boolean nfound = true; + + for (int i = 0; panels.split("\\s").length - 1 >= i; ++i) { + if (args[0].equalsIgnoreCase(panels.split("\\s")[i])) { + panels = panels.split("\\s")[i]; + nfound = false; + } + } + if (nfound) { + //if the panel was not found in the message + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.nopanel")))); + return true; + }else if (!checkconfig(panels, p, cf)) { + //if the config is missing an element (message will be sent to user via the public boolean) + return true; + } + //open editor window here + plugin.openGui(panels, p, cf,3,0); + return true; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Usage: /cpe ")); + return true; + } + boolean checkconfig(String panels, Player p, YamlConfiguration pconfig) { + //if it is missing a section specified it will return false + String tag = plugin.config.getString("config.format.tag") + " "; + if(!pconfig.contains("panels." + panels)) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.nopanel")))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.nopanel"))); + } + return false; + } + if(!pconfig.contains("panels." + panels + ".perm")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " perm: Missing config section!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " perm: Missing config section!")); + } + return false; + } + if(!pconfig.contains("panels." + panels + ".rows")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " rows: Missing config section!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " rows: Missing config section!")); + } + return false; + } + if(!pconfig.contains("panels." + panels + ".title")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " title: Missing config section!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " title: Missing config section!")); + } + return false; + } + if(!pconfig.contains("panels." + panels + ".item")) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.error") + " item: Missing config section!"))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.config.getString("config.format.error") + " item: Missing config section!")); + } + return false; + } + return true; + } +} diff --git a/src/me/rockyhawk/commandPanels/ingameEditor/cpTabCompleteIngame.java b/src/me/rockyhawk/commandPanels/ingameEditor/cpTabCompleteIngame.java new file mode 100644 index 0000000..0690130 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/ingameEditor/cpTabCompleteIngame.java @@ -0,0 +1,59 @@ +package me.rockyhawk.commandPanels.ingameEditor; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +public class cpTabCompleteIngame implements TabCompleter { + commandpanels plugin; + public cpTabCompleteIngame(commandpanels pl) { this.plugin = pl; } + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { + if(sender instanceof Player && args.length == 1){ + Player p = ((Player) sender).getPlayer(); + if(label.equalsIgnoreCase("cpe") || label.equalsIgnoreCase("cpanele") || label.equalsIgnoreCase("commandpaneledit")){ + ArrayList apanels = new ArrayList(); //all panels + String tpanels; //tpanels is the temp to check through the files + try { + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return null; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if(!key.startsWith(args[0])){ + //this will narrow down the panels to what the user types + continue; + } + if(sender.hasPermission("commandpanel.panel." + temp.getString("panels." + key + ".perm"))) { + if(temp.contains("panels." + key + ".disabled-worlds")){ + List disabledWorlds = (List) temp.getList("panels." + key + ".disabled-worlds"); + if(!disabledWorlds.contains(p.getWorld().getName())){ + apanels.add(key); + } + }else{ + apanels.add(key); + } + } + } + //if file contains opened panel then start + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + } + return apanels; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/ingameEditor/editorUserInput.java b/src/me/rockyhawk/commandPanels/ingameEditor/editorUserInput.java new file mode 100644 index 0000000..ef7e621 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/ingameEditor/editorUserInput.java @@ -0,0 +1,402 @@ +package me.rockyhawk.commandPanels.ingameEditor; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class editorUserInput implements Listener { + commandpanels plugin; + public editorUserInput(commandpanels pl) { + this.plugin = pl; + } + @EventHandler + public void onPlayerChatEditor(AsyncPlayerChatEvent e) { + Player p = e.getPlayer(); + for(String[] temp : plugin.editorInputStrings) { + //[0] is player name [1] is panel name [2] is section type + if (!temp[0].equals(p.getName())) { + continue; + } + e.setCancelled(true); + String panelName = temp[1]; + String panelTitle = temp[1]; + File panelFile = null; + String section = temp[2]; + YamlConfiguration cf = null; + try { + for (File tempFile : plugin.panelsf.listFiles()) { //will loop through all the files in folder + YamlConfiguration tempConf = YamlConfiguration.loadConfiguration(tempFile); + if (!plugin.checkPanels(tempConf)) { + continue; + } + for (String key : tempConf.getConfigurationSection("panels").getKeys(false)) { + if (key.equals(panelName)) { + cf = tempConf; + panelFile = tempFile; + panelTitle = ChatColor.translateAlternateColorCodes('&',tempConf.getString("panels." + key + ".title")); + break; + } + } + //if file contains opened panel then start + } + } catch (Exception fail) { + //could not fetch all panel names (probably no panels exist) + } + if(e.getMessage().equalsIgnoreCase(plugin.config.getString("config.input-cancel"))){ + plugin.editorInputStrings.remove(temp); + plugin.reloadPanelFiles(); + e.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&',plugin.config.getString("config.input-cancelled"))); + return; + } + if(section.startsWith("panel.")) { + panelSectionCheck(p, section, panelName, panelTitle, cf, panelFile, e); + }else if(section.startsWith("item.")){ + itemSectionCheck(p, section, panelName, cf, panelFile, e); + } + plugin.editorInputStrings.remove(temp); + plugin.reloadPanelFiles(); + if(section.startsWith("panel.")){ + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + plugin.openEditorGui(p, 0); //I have to do this to run regular Bukkit voids in an ASYNC Event + } + }); + }else if(section.startsWith("item.")) { + final YamlConfiguration finalCF = cf; + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + plugin.openGui(panelName, p, finalCF, 3,0); //I have to do this to run regular Bukkit voids in an ASYNC Event + } + }); + } + return; + } + } + boolean savePanelFile(YamlConfiguration cf, File panelFile){ + try { + cf.save(panelFile); + return true; + } catch (Exception io) { + plugin.debug(io); + return false; + } + } + void panelSectionCheck(Player p, String section, String panelName, String panelTitle, YamlConfiguration cf, File panelFile, AsyncPlayerChatEvent e){ + String tag = plugin.config.getString("config.format.tag") + " "; + switch (section) { + case "panel.delete": + if (e.getMessage().contains("y")) { + if(cf.getConfigurationSection("panels").getKeys(false).size() != 1){ + //if the file has more than one panel in it + cf.set("panels." + panelName, null); + if(savePanelFile(cf, panelFile)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Deleted Panel!")); + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Could Not Delete Panel!")); + } + }else { + //if the file only has one panel in it + if (panelFile.delete()) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Deleted Panel!")); + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Could Not Delete Panel!")); + } + } + } + break; + case "panel.perm": + if(e.getMessage().contains(" ")){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Permission cannot contain spaces!")); + break; + } + cf.set("panels." + panelName + ".perm", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Permission required is now " + "commandpanel.panel." + e.getMessage())); + break; + case "panel.rows": + try { + int rows = Integer.parseInt(e.getMessage()); + if (rows >= 7 || rows <= 0) { + //if the number isn't between 1-6 + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Choose an integer between 1 to 6!")); + return; + } + cf.set("panels." + panelName + ".rows", rows); + cf.save(panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set Panel to " + rows + " rows!")); + } catch (Exception io) { + plugin.debug(io); + } + break; + case "panel.title": + if(panelTitle.equals(ChatColor.translateAlternateColorCodes('&',e.getMessage()))){ + p.sendMessage(plugin.papi(p,tag + e.getMessage() + ChatColor.RED + " is in use from another panel!")); + break; + } + cf.set("panels." + panelName + ".title", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set new Title to " + ChatColor.WHITE + e.getMessage())); + break; + case "panel.name": + if(e.getMessage().contains(" ")){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Panel name cannot contain spaces!")); + break; + } + if(panelName.equals(e.getMessage())){ + p.sendMessage(plugin.papi(p,tag + ChatColor.RED + e.getMessage() + " is in use from another panel!")); + break; + } + cf.set("panels." + e.getMessage(), cf.get("panels." + panelName)); + cf.set("panels." + panelName, null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set new Name to " + e.getMessage())); + break; + case "panel.empty": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".empty", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Empty materials have been removed.")); + break; + } + String materialTemp = null; + try { + materialTemp = Material.matchMaterial(e.getMessage()).toString(); + }catch(NullPointerException ex){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + e.getMessage() + " is not a valid Material!")); + } + cf.set("panels." + panelName + ".empty", materialTemp); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set Empty material to " + materialTemp)); + break; + case "panel.sound-on-open": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".sound-on-open", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Sounds have been removed.")); + break; + } + String tempSound; + try { + tempSound = Sound.valueOf(e.getMessage()).toString(); + }catch(Exception ex){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + e.getMessage() + " is not a valid Sound!")); + return; + } + cf.set("panels." + panelName + ".sound-on-open", tempSound); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Sound when opening is now " + tempSound)); + break; + case "panel.command": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".command", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Custom commands have been removed.")); + break; + } + cf.set("panels." + panelName + ".command", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set new custom commands to " + ChatColor.WHITE + "/" + e.getMessage().trim().replace(" ", " /"))); + break; + case "panel.commands-on-open.add": + List commandsOnOpenAdd = new ArrayList<>(); + if(cf.contains("panels." + panelName + ".commands-on-open")){ + commandsOnOpenAdd = cf.getStringList("panels." + panelName + ".commands-on-open"); + } + commandsOnOpenAdd.add(e.getMessage()); + cf.set("panels." + panelName + ".commands-on-open", commandsOnOpenAdd); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Added new command: " + e.getMessage())); + break; + case "panel.commands-on-open.remove": + List commandsOnOpenRemove = new ArrayList<>(); + if(cf.contains("panels." + panelName + ".commands-on-open")){ + commandsOnOpenRemove = cf.getStringList("panels." + panelName + ".commands-on-open"); + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "No commands found to remove!")); + break; + } + try { + commandsOnOpenRemove.remove(Integer.parseInt(e.getMessage())-1); + }catch (Exception ex){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Could not find command!")); + break; + } + if(commandsOnOpenRemove.size() == 0){ + cf.set("panels." + panelName + ".commands-on-open", null); + }else{ + cf.set("panels." + panelName + ".commands-on-open", commandsOnOpenRemove); + } + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Removed command line " + e.getMessage())); + break; + } + } + void itemSectionCheck(Player p, String section, String panelName, YamlConfiguration cf, File panelFile, AsyncPlayerChatEvent e){ + String tag = plugin.config.getString("config.format.tag") + " "; + String itemSlot = section.split("\\.")[1]; + String sectionChange = section.replace("item." + itemSlot + ".",""); + switch (sectionChange) { + case "name": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".name", ""); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Name is now default.")); + break; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".name", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set new name to " + ChatColor.WHITE + e.getMessage())); + break; + case "head": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".material", "PLAYER_HEAD"); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Material is now default.")); + break; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".material", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set Material value to " + ChatColor.WHITE + e.getMessage())); + break; + case "stack": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".stack", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Item has been unstacked.")); + break; + } + try { + int rows = Integer.parseInt(e.getMessage()); + if (rows >= 65 || rows <= 0) { + //if the number isn't between 1-64 + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Choose an integer between 1 to 64!")); + return; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".stack", rows); + cf.save(panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set stack to " + rows + "!")); + } catch (Exception io) { + plugin.debug(io); + } + break; + case "enchanted": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".enchanted", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Enchantments have been removed.")); + break; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".enchanted", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set new Enchantment to " + ChatColor.WHITE + e.getMessage())); + break; + case "potion": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".potion", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Potion effects have been removed.")); + break; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".potion", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Set new Potion to " + e.getMessage().toUpperCase())); + break; + case "panel.customdata": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".customdata", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Custom Model Data has been removed.")); + break; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".customdata", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Custom Model Data set to " + e.getMessage())); + break; + case "leatherarmor": + if(e.getMessage().trim().equalsIgnoreCase("remove")){ + cf.set("panels." + panelName + ".item." + itemSlot + ".leatherarmor", null); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Leather armor colour has been removed.")); + break; + } + cf.set("panels." + panelName + ".item." + itemSlot + ".leatherarmor", e.getMessage()); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Leather armor colour set to " + e.getMessage())); + break; + case "commands.add": + List commandsOnOpenAdd = new ArrayList<>(); + if(cf.contains("panels." + panelName + ".item." + itemSlot + ".commands")){ + commandsOnOpenAdd = cf.getStringList("panels." + panelName + ".item." + itemSlot + ".commands"); + } + commandsOnOpenAdd.add(e.getMessage()); + cf.set("panels." + panelName + ".item." + itemSlot + ".commands", commandsOnOpenAdd); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Added new command: " + e.getMessage())); + break; + case "commands.remove": + List commandsOnOpenRemove = new ArrayList<>(); + if(cf.contains("panels." + panelName + ".item." + itemSlot + ".commands")){ + commandsOnOpenRemove = cf.getStringList("panels." + panelName + ".item." + itemSlot + ".commands"); + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "No commands found to remove!")); + break; + } + try { + commandsOnOpenRemove.remove(Integer.parseInt(e.getMessage())-1); + }catch (Exception ex){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Could not find command!")); + break; + } + if(commandsOnOpenRemove.size() == 0){ + cf.set("panels." + panelName + ".item." + itemSlot + ".commands", null); + }else{ + cf.set("panels." + panelName + ".item." + itemSlot + ".commands", commandsOnOpenRemove); + } + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Removed command line " + e.getMessage())); + break; + case "lore.add": + List loreOnOpenAdd = new ArrayList<>(); + if(cf.contains("panels." + panelName + ".item." + itemSlot + ".lore")){ + loreOnOpenAdd = cf.getStringList("panels." + panelName + ".item." + itemSlot + ".lore"); + } + loreOnOpenAdd.add(e.getMessage()); + cf.set("panels." + panelName + ".item." + itemSlot + ".lore", loreOnOpenAdd); + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Added new lore: " + e.getMessage())); + break; + case "lore.remove": + List loreOnOpenRemove = new ArrayList<>(); + if(cf.contains("panels." + panelName + ".item." + itemSlot + ".lore")){ + loreOnOpenRemove = cf.getStringList("panels." + panelName + ".item." + itemSlot + ".lore"); + }else{ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "No lore found to remove!")); + break; + } + try { + loreOnOpenRemove.remove(Integer.parseInt(e.getMessage())-1); + }catch (Exception ex){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.RED + "Could not find lore!")); + break; + } + if(loreOnOpenRemove.size() == 0){ + cf.set("panels." + panelName + ".item." + itemSlot + ".lore", null); + }else{ + cf.set("panels." + panelName + ".item." + itemSlot + ".lore", loreOnOpenRemove); + } + savePanelFile(cf, panelFile); + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + ChatColor.GREEN + "Removed lore line " + e.getMessage())); + break; + } + } +} diff --git a/src/me/rockyhawk/commandPanels/ingameEditor/editorUtils.java b/src/me/rockyhawk/commandPanels/ingameEditor/editorUtils.java new file mode 100644 index 0000000..a75d2ea --- /dev/null +++ b/src/me/rockyhawk/commandPanels/ingameEditor/editorUtils.java @@ -0,0 +1,648 @@ +package me.rockyhawk.commandPanels.ingameEditor; + +import me.rockyhawk.commandPanels.commandpanels; +import net.milkbowl.vault.chat.Chat; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.*; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +public class editorUtils implements Listener { + public YamlConfiguration tempEdit; + public ArrayList inventoryItemSettingsOpening = new ArrayList<>(); + commandpanels plugin; + public editorUtils(commandpanels pl) { + this.plugin = pl; + this.tempEdit = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder() + File.separator + "temp.yml")); + } + @EventHandler + public void onClickMainEdit(InventoryClickEvent e) { + Player p = (Player)e.getWhoClicked(); + //if the inventory isn't the editor main window + try { + if (e.getClickedInventory().getType() != InventoryType.CHEST) { + return; + } + }catch(NullPointerException nu){return;} + if(!p.getOpenInventory().getTitle().equals(ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&',"Command Panels Editor")))){ + return; + } + e.setCancelled(true); + if(e.getClickedInventory() != e.getView().getTopInventory()){ + return; + } + ArrayList panelNames = new ArrayList(); //all panels from ALL files (panel names) + ArrayList panelTitles = new ArrayList(); //all panels from ALL files (panel titles) + ArrayList panelYaml = new ArrayList(); //all panels from ALL files (panel yaml files) + try { + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext();) { + key = (String) var10.next(); + panelNames.add(ChatColor.translateAlternateColorCodes('&', key)); + panelTitles.add(ChatColor.translateAlternateColorCodes('&', temp.getString("panels." + key + ".title"))); + panelYaml.add(temp); + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + plugin.debug(fail); + return; + } + if(e.getSlot() == 48){ + //previous page button + try { + if (e.getCurrentItem().getType() == Material.PAPER) { + plugin.openEditorGui(p, -1); + p.updateInventory(); + return; + } + }catch(NullPointerException nu){} + } + if(e.getSlot() == 49){ + //sunflower page index + if(e.getCurrentItem().getType() == Material.SUNFLOWER){ + p.updateInventory(); + return; + } + } + if(e.getSlot() == 50){ + //next page button + try{ + if(e.getCurrentItem().getType() == Material.PAPER){ + plugin.openEditorGui(p, 1); + p.updateInventory(); + return; + } + }catch(NullPointerException nu){} + } + if(e.getSlot() == 45){ + //exit button + p.closeInventory(); + p.updateInventory(); + return; + } + if(e.getSlot() <= 44){ + //if panel slots are selected + try{ + if(e.getCurrentItem().getType() != Material.AIR){ + if(e.getClick().isLeftClick() && !e.getClick().isShiftClick()){ + //if left click + int count = 0; + for(String panelName : panelNames){ + if(panelName.equals(ChatColor.stripColor(e.getCurrentItem().getItemMeta().getDisplayName()))){ + plugin.openGui(panelName, p, panelYaml.get(count),3,0); + return; + } + count +=1; + } + }else{ + //if right click + int count = 0; + for(String panelName : panelNames){ + if(panelName.equals(ChatColor.stripColor(e.getCurrentItem().getItemMeta().getDisplayName()))){ + plugin.openPanelSettings(p,panelName,panelYaml.get(count)); + return; + } + count +=1; + } + p.updateInventory(); + } + } + }catch(NullPointerException nu){} + } + p.updateInventory(); + } + @EventHandler + public void onInventoryDrag(InventoryDragEvent e) { + Player p = (Player)e.getWhoClicked(); + if(e.getInventory().getType() != InventoryType.CHEST){ + return; + } + if(!p.getOpenInventory().getTitle().contains(ChatColor.GRAY + "Editing Panel:")){ + return; + } + String panelName = ""; //all panels from ALL files (panel names) + String fileName = ""; //all panels from ALL files (panel names) + YamlConfiguration file = new YamlConfiguration(); //all panels from ALL files (panel yaml files) + boolean found = false; + try { + //neew to loop through files to get file names + for (File tempFile : plugin.panelsf.listFiles()) { //will loop through all the files in folder + String key; + YamlConfiguration temp = YamlConfiguration.loadConfiguration(tempFile); + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext();) { + key = (String) var10.next(); + if(e.getView().getTitle().equals(ChatColor.GRAY + "Editing Panel: " + ChatColor.translateAlternateColorCodes('&', temp.getString("panels." + key + ".title")))){ + panelName = key; + fileName = tempFile.getName(); + file = temp; + found = true; + break; + } + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + plugin.debug(fail); + return; + } + if(!found){ + return; + } + //this basically just determines if something is dragged. + try { + if (tempEdit.contains("panels." + panelName + ".temp." + p.getName() + ".material")) { + if (e.getOldCursor().getType() != Material.matchMaterial(tempEdit.getString("panels." + panelName + ".temp." + p.getName() + ".material"))) { + clearTemp(p, panelName); + return; + } + } + }catch(Exception ex){ + return; + } + //I cannot use load temp because the Event type is different, also I need to loop through all the items + if(tempEdit.contains("panels." + panelName + ".temp." + p.getName())){ + try { + for (int slot : e.getInventorySlots()) { + file.set("panels." + panelName + ".item." + slot, tempEdit.get("panels." + panelName + ".temp." + p.getName())); + //stacks can't be saved to file because it is not accurate in drag drop cases + if(file.contains("panels." + panelName + ".item." + slot + ".stack")){ + file.set("panels." + panelName + ".item." + slot + ".stack",null); + } + saveFile(fileName, file, true); + } + }catch(NullPointerException nu){ + plugin.debug(nu); + } + } + } + @EventHandler + public void onInventoryEdit(InventoryClickEvent e) { + Player p = (Player)e.getWhoClicked(); + if(e.getInventory().getType() != InventoryType.CHEST){ + return; + } + if(!p.getOpenInventory().getTitle().contains(ChatColor.GRAY + "Editing Panel:")){ + return; + } + String panelName = ""; //all panels from ALL files (panel names) + File fileName = null; //all panels from ALL files (panel names) + YamlConfiguration file = new YamlConfiguration(); //all panels from ALL files (panel yaml files) + boolean found = false; + try { + //neew to loop through files to get file names + for (File tempFile : plugin.panelsf.listFiles()) { //will loop through all the files in folder + String key; + YamlConfiguration temp = YamlConfiguration.loadConfiguration(tempFile); + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext();) { + key = (String) var10.next(); + if(e.getView().getTitle().equals(ChatColor.GRAY + "Editing Panel: " + ChatColor.translateAlternateColorCodes('&', temp.getString("panels." + key + ".title")))){ + panelName = key; + fileName = tempFile; + file = temp; + found = true; + break; + } + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + plugin.debug(fail); + return; + } + if(!found){ + return; + } + //change file below + /* + All item settings will be custom saved and carried over. When inventory is closed, then figure out where items are and allocate the settings to those items... + This is so there is no errors with item amounts and also so settings can be moved around easily + + Load temp item if the item is dropped into the panel + + Save temp item if the item is picked up from inside the panel + */ + if(e.getClick().isShiftClick() && e.getClickedInventory() == e.getView().getTopInventory()){ + if(e.getCurrentItem() == null) { + return; + } + onEditPanelClose(p,e.getInventory(),e.getView()); + inventoryItemSettingsOpening.add(p.getName()); + //refresh the yaml config + file = YamlConfiguration.loadConfiguration(fileName); + plugin.openItemSettings(p,panelName,file,e.getSlot()); + return; + } + if(tempEdit.contains("panels." + panelName + ".temp." + p.getName() + ".material")) { + if(e.getCursor().getType() != Material.PLAYER_HEAD) { + //if the material doesn't match and also isn't a PLAYER_HEAD + if (e.getCursor().getType() != Material.matchMaterial(tempEdit.getString("panels." + panelName + ".temp." + p.getName() + ".material"))) { + clearTemp(p, panelName); + } + } + } + if(e.getAction() == InventoryAction.CLONE_STACK){ + saveTempItem(e, p, file, panelName); + }else if(e.getAction() == InventoryAction.PLACE_ALL){ + loadTempItem(e, p, file, fileName.getName(), panelName); + clearTemp(p, panelName); + }else if(e.getAction() == InventoryAction.COLLECT_TO_CURSOR){ + //e.setCancelled(true); + saveTempItem(e, p, file, panelName); + }else if(e.getAction() == InventoryAction.DROP_ALL_CURSOR){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.DROP_ALL_SLOT){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.DROP_ONE_CURSOR){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.DROP_ONE_SLOT){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.HOTBAR_MOVE_AND_READD){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.HOTBAR_SWAP){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.PLACE_SOME){ + loadTempItem(e, p, file, fileName.getName(), panelName); + }else if(e.getAction() == InventoryAction.SWAP_WITH_CURSOR){ + e.setCancelled(true); + }else if(e.getAction() == InventoryAction.PICKUP_ALL){ + saveTempItem(e, p, file, panelName); + }else if(e.getAction() == InventoryAction.PICKUP_HALF){ + saveTempItem(e, p, file, panelName); + }else if(e.getAction() == InventoryAction.PICKUP_ONE){ + saveTempItem(e, p, file, panelName); + }else if(e.getAction() == InventoryAction.PICKUP_SOME){ + saveTempItem(e, p, file, panelName); + }else if(e.getAction() == InventoryAction.PLACE_ONE){ + loadTempItem(e, p, file, fileName.getName(), panelName); + } + } + @EventHandler + public void onEditInventoryClose(InventoryCloseEvent e) { + if(inventoryItemSettingsOpening.contains(e.getPlayer().getName())) { + inventoryItemSettingsOpening.remove(e.getPlayer().getName()); + return; + } + onEditPanelClose((Player) e.getPlayer(), e.getInventory(), e.getView()); + } + @EventHandler + public void onPanelSettings(InventoryClickEvent e) { + Player p = (Player)e.getWhoClicked(); + String tag = plugin.config.getString("config.format.tag") + " "; + try { + if (e.getClickedInventory().getType() != InventoryType.CHEST) { + return; + } + }catch(Exception outOf){ + //skip as player clicked outside the inventory + return; + } + if(!p.getOpenInventory().getTitle().contains("Panel Settings:")){ + return; + } + e.setCancelled(true); + String panelName = ""; //all panels from ALL files (panel names) + boolean found = false; + try { + //neew to loop through files to get file names + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all configs + if(!plugin.checkPanels(temp)){ + return; + } + for (String key : temp.getConfigurationSection("panels").getKeys(false)){ + if(e.getView().getTitle().equals("Panel Settings: " + key)){ + panelName = key; + found = true; + break; + } + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + plugin.debug(fail); + return; + } + if(!found){ + return; + } + if(e.getSlot() == 1){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.perm"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Permission")); + p.closeInventory(); + } + if(e.getSlot() == 3){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.title"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Title")); + p.closeInventory(); + } + if(e.getSlot() == 5){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.sound-on-open"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Sound ID")); + p.closeInventory(); + } + if(e.getSlot() == 7){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.command"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Command")); + p.closeInventory(); + } + if(e.getSlot() == 21){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.delete"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Are you sure? (yes/no)")); + p.closeInventory(); + } + if(e.getSlot() == 23){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.rows"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter Row Amount (1 to 6)")); + p.closeInventory(); + } + if(e.getSlot() == 13){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.empty"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Material ID")); + p.closeInventory(); + } + if(e.getSlot() == 15){ + //adds abilities to add and remove lines + if(e.getClick().isLeftClick()) { + plugin.editorInputStrings.add(new String[]{p.getName(), panelName, "panel.commands-on-open.add"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Command")); + }else{ + plugin.editorInputStrings.add(new String[]{p.getName(), panelName, "panel.commands-on-open.remove"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter command line to remove (must be an integer)")); + } + p.closeInventory(); + } + if(e.getSlot() == 11){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"panel.name"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Name")); + p.closeInventory(); + } + if(e.getSlot() == 18){ + plugin.openEditorGui(p,0); + p.updateInventory(); + } + } + @EventHandler + public void onItemSettings(InventoryClickEvent e) { + Player p = (Player)e.getWhoClicked(); + String tag = plugin.config.getString("config.format.tag") + " "; + try { + if (e.getClickedInventory().getType() != InventoryType.CHEST) { + return; + } + }catch(Exception outOf){ + //skip as player clicked outside the inventory + return; + } + if(!p.getOpenInventory().getTitle().contains("Item Settings:")){ + return; + } + e.setCancelled(true); + String panelName = ""; //all panels from ALL files (panel names) + YamlConfiguration panelYaml = null; //all panels from ALL files (panel names) + boolean found = false; + try { + //neew to loop through files to get file names + for (YamlConfiguration temp : plugin.panelFiles) { //will loop through all configs + if(!plugin.checkPanels(temp)){ + return; + } + for (String key : temp.getConfigurationSection("panels").getKeys(false)){ + if(e.getView().getTitle().equals("Item Settings: " + key)){ + panelName = key; + panelYaml = temp; + found = true; + break; + } + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + plugin.debug(fail); + return; + } + if(!found){ + return; + } + int itemSlot; + try { + itemSlot = Integer.parseInt(e.getView().getTopInventory().getItem(35).getItemMeta().getDisplayName().split("\\s")[2]); + }catch(Exception ex){ + plugin.getServer().getConsoleSender().sendMessage("[CommandPanels] Could not get item slot"); + plugin.debug(ex); + return; + } + if(e.getSlot() == 1){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".name"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Item Name")); + p.closeInventory(); + } + if(e.getSlot() == 3){ + //adds abilities to add and remove lines + if(e.getClick().isLeftClick()) { + plugin.editorInputStrings.add(new String[]{p.getName(), panelName, "item." + itemSlot + ".commands.add"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Item Command")); + }else{ + plugin.editorInputStrings.add(new String[]{p.getName(), panelName, "item." + itemSlot + ".commands.remove"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter command line to remove (must be an integer)")); + } + p.closeInventory(); + } + if(e.getSlot() == 5){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".enchanted"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Item Enchantment")); + p.closeInventory(); + } + if(e.getSlot() == 7){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".potion"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Item Potion Effect")); + p.closeInventory(); + } + if(e.getSlot() == 19){ + //adds abilities to add and remove lines + if(e.getClick().isLeftClick()) { + plugin.editorInputStrings.add(new String[]{p.getName(), panelName, "item." + itemSlot + ".lore.add"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Item Lore")); + }else{ + plugin.editorInputStrings.add(new String[]{p.getName(), panelName, "item." + itemSlot + ".lore.remove"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter lore line to remove (must be an integer)")); + } + p.closeInventory(); + } + if(e.getSlot() == 21){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".stack"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Item Stack (must be an integer)")); + p.closeInventory(); + } + if(e.getSlot() == 23){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".customdata"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Custom Model Data")); + p.closeInventory(); + } + if(e.getSlot() == 25){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".leatherarmor"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Leather Armor Colour")); + p.closeInventory(); + } + if(e.getSlot() == 35){ + plugin.editorInputStrings.add(new String[]{p.getName(),panelName,"item." + itemSlot + ".head"}); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Enter New Custom Material (eg. cps= self)")); + p.closeInventory(); + } + if(e.getSlot() == 27){ + plugin.openGui(panelName, p, panelYaml,3,0); + p.updateInventory(); + } + } + public void saveTempItem(InventoryClickEvent e, Player p, YamlConfiguration file, String panelName){ + //saves item to temp, using getslot + tempEdit.set("panels." + panelName + ".temp." + p.getName(),file.get("panels." + panelName + ".item." + e.getSlot())); + saveFile("temp.yml", tempEdit, false); + } + public void loadTempItem(InventoryClickEvent e, Player p, YamlConfiguration file,String fileName, String panelName){ + //loads temp item to the current item + if(tempEdit.contains("panels." + panelName + ".temp." + p.getName())){ + file.set("panels." + panelName + ".item." + e.getSlot(),tempEdit.get("panels." + panelName + ".temp." + p.getName())); + saveFile(fileName, file, true); + } + } + public void clearTemp(Player p, String panelName){ + //empty temp item + tempEdit.set("panels." + panelName + ".temp." + p.getName(),null); + saveFile("temp.yml", tempEdit, false); + } + public void saveFile(String fileName, YamlConfiguration file, boolean inPanelsFolder){ + try { + if(inPanelsFolder){ + file.save(new File(plugin.panelsf + File.separator + fileName)); + }else{ + file.save(new File(plugin.getDataFolder() + File.separator + fileName)); + } + } catch (IOException s) { + plugin.debug(s); + } + } + public void onEditPanelClose(Player p, Inventory inv, InventoryView invView) { + String tag = plugin.config.getString("config.format.tag") + " "; + if(inv.getType() != InventoryType.CHEST){ + return; + } + if(!p.getOpenInventory().getTitle().contains(ChatColor.GRAY + "Editing Panel:")){ + return; + } + String panelName = ""; //all panels from ALL files (panel names) + String fileName = ""; //all panels from ALL files (panel names) + YamlConfiguration file = new YamlConfiguration(); //all panels from ALL files (panel yaml files) + boolean found = false; + try { + //neew to loop through files to get file names + for (File tempFile : plugin.panelsf.listFiles()) { //will loop through all the files in folder + String key; + YamlConfiguration temp = YamlConfiguration.loadConfiguration(tempFile); + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext();) { + key = (String) var10.next(); + if(invView.getTitle().equals(ChatColor.GRAY + "Editing Panel: " + ChatColor.translateAlternateColorCodes('&', temp.getString("panels." + key + ".title")))){ + panelName = key; + fileName = tempFile.getName(); + file = temp; + found = true; + break; + } + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + plugin.debug(fail); + return; + } + if(!found){ + return; + } + //save items as they appear + ItemStack cont; + for(int i = 0; inv.getSize() > i; i++){ + cont = inv.getItem(i); + //repeat through all the items in the editor + try{ + //make the item here + if(cont == null){ + //remove if items have been removed + if(file.contains("panels." + panelName + ".item." + i)){ + file.set("panels." + panelName + ".item." + i, null); + continue; + } + } + if(file.contains("panels." + panelName + ".item." + i + ".material")){ + if(file.getString("panels." + panelName + ".item." + i + ".material").contains("%") || file.getString("panels." + panelName + ".item." + i + ".material").contains("=")){ + if(cont.getType() != Material.PLAYER_HEAD){ + file.set("panels." + panelName + ".item." + i + ".material", cont.getType().toString()); + } + }else{ + file.set("panels." + panelName + ".item." + i + ".material", cont.getType().toString()); + } + }else{ + file.set("panels." + panelName + ".item." + i + ".material", cont.getType().toString()); + } + if(cont.getType() == Material.PLAYER_HEAD){ + //inject base64 here + if(plugin.getHeadBase64(cont) != null){ + file.set("panels." + panelName + ".item." + i + ".material", "cps= " + plugin.getHeadBase64(cont)); + } + } + if(cont.getAmount() != 1){ + file.set("panels." + panelName + ".item." + i + ".stack", cont.getAmount()); + } + if(!cont.getEnchantments().isEmpty()){ + file.set("panels." + panelName + ".item." + i + ".enchanted", "true"); + } + if(file.contains("panels." + panelName + ".item." + i + ".name")){ + //these will ensure &f items (blank items) will be set to &f to stay blank + if(file.getString("panels." + panelName + ".item." + i + ".name").equalsIgnoreCase("&f") || file.getString("panels." + panelName + ".item." + i + ".name").equalsIgnoreCase("§f")){ + file.set("panels." + panelName + ".item." + i + ".name", "&f"); + }else{ + file.set("panels." + panelName + ".item." + i + ".name", cont.getItemMeta().getDisplayName()); + } + }else { + file.set("panels." + panelName + ".item." + i + ".name", cont.getItemMeta().getDisplayName()); + } + file.set("panels." + panelName + ".item." + i + ".lore", cont.getItemMeta().getLore()); + }catch(Exception n){ + //skip over an item that spits an error + } + } + try { + file.save(new File(plugin.panelsf + File.separator + fileName)); + tempEdit.save(new File(plugin.getDataFolder() + File.separator + "temp.yml")); + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.GREEN + "Saved Changes!")); + } catch (IOException s) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + ChatColor.RED + "Could Not Save Changes!")); + plugin.debug(s); + } + plugin.reloadPanelFiles(); + } +} \ No newline at end of file diff --git a/src/me/rockyhawk/commandPanels/premium/commandpanelUserInput.java b/src/me/rockyhawk/commandPanels/premium/commandpanelUserInput.java new file mode 100644 index 0000000..198a737 --- /dev/null +++ b/src/me/rockyhawk/commandPanels/premium/commandpanelUserInput.java @@ -0,0 +1,42 @@ +package me.rockyhawk.commandPanels.premium; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class commandpanelUserInput implements Listener { + commandpanels plugin; + public commandpanelUserInput(commandpanels pl) { + this.plugin = pl; + } + @EventHandler + public void onPlayerChat(AsyncPlayerChatEvent e) { + for(int o = 0; plugin.userInputStrings.size() > o; o++){ + if(plugin.userInputStrings.get(o)[0].equals(e.getPlayer().getName())){ + if(e.getMessage().equalsIgnoreCase(plugin.config.getString("config.input-cancel"))){ + e.setCancelled(true); + e.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', plugin.config.getString("config.input-cancelled"))); + for(int i = 0; plugin.userInputStrings.size() > i; i++){ + if(plugin.userInputStrings.get(i)[0].equals(e.getPlayer().getName())){ + plugin.userInputStrings.remove(i); + //this is here because if one command is removed, i cannot increase by one + i=i-1; + } + } + return; + } + String command = plugin.userInputStrings.get(o)[1].replaceAll("%cp-player-input%", e.getMessage()); + plugin.userInputStrings.remove(o); + o=o-1; + e.setCancelled(true); + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + plugin.commandTags(e.getPlayer(), command); //I have to do this to run regular Bukkit voids in an ASYNC Event + } + }); + } + } + } +} diff --git a/src/me/rockyhawk/commandPanels/premium/commandpanelrefresher.java b/src/me/rockyhawk/commandPanels/premium/commandpanelrefresher.java new file mode 100644 index 0000000..c69020c --- /dev/null +++ b/src/me/rockyhawk/commandPanels/premium/commandpanelrefresher.java @@ -0,0 +1,174 @@ +package me.rockyhawk.commandPanels.premium; + +import me.rockyhawk.commandPanels.commandpanels; +import org.bukkit.*; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +public class commandpanelrefresher implements Listener { + commandpanels plugin; + public commandpanelrefresher(commandpanels pl) { + this.plugin = pl; + } + private int c = 0; + private int animatevalue = -1; + private int animatecount = 0; + @EventHandler + public void onInventoryOpen(InventoryOpenEvent e){ //Handles when Players open inventory + //I have to convert HumanEntity to a player + if (plugin.config.contains("config.refresh-panels")) { + if (plugin.config.getString("config.refresh-panels").trim().equalsIgnoreCase("false")) { + return; + } + } + HumanEntity h = e.getPlayer(); + Player p; + if (h instanceof Player) { + p = Bukkit.getPlayer(h.getName()); + }else{ + return; + } + //get all panel names (not titles) + String tag = plugin.config.getString("config.format.tag") + " "; + YamlConfiguration cf = null; + String panel = null; + String panelTitle = null; + ArrayList filenames = new ArrayList(Arrays.asList(plugin.panelsf.list())); + try { + boolean foundPanel = false; + for (int f = 0; filenames.size() > f; f++) { //will loop through all the files in folder + String key; + YamlConfiguration temp; + temp = YamlConfiguration.loadConfiguration(new File(plugin.panelsf + File.separator + filenames.get(f))); + if(!plugin.checkPanels(temp)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + ": File with no Panels found or Panel with syntax error Found!"))); + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext();) { + key = (String) var10.next(); + if(ChatColor.translateAlternateColorCodes('&',temp.getString("panels." + key + ".title")).equals(e.getView().getTitle())){ + panel = key; + panelTitle = ChatColor.translateAlternateColorCodes('&',temp.getString("panels." + key + ".title")); + cf = YamlConfiguration.loadConfiguration(new File(plugin.panelsf + File.separator + filenames.get(f))); + foundPanel= true; + break; + } + } + if(foundPanel){ + //this is to avoid the plugin to continue looking when it was already found + break; + } + } + }catch(Exception fail){ + //could not fetch all panel names (probably no panels exist) + } + if(panel == null){ + return; + } + //there is already a runnable running for this player + if(plugin.panelRunning.contains(p.getName() + ";" + panel)){ + return; + } + plugin.panelRunning.add(p.getName() + ";" + panel); + if (plugin.config.contains("config.panel-snooper")) { + if (plugin.config.getString("config.panel-snooper").trim().equalsIgnoreCase("true")) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels] " + p.getName() + " Opened " + panel); + } + } + if(cf.contains("panels." + panel + ".animatevalue")){ + animatevalue = cf.getInt("panels." + panel + ".animatevalue"); + } + final YamlConfiguration cfFinal = cf; + final String fpanel = panel; + final String fpanelTitle = panelTitle; + ItemStack panelItemList[] = plugin.openGui(fpanel, p, cf,2, -1).getContents(); + ItemStack playerItemList[] = p.getInventory().getStorageContents(); + new BukkitRunnable(){ + @Override + public void run() { + //counter counts to refresh delay (in seconds) then restarts + if(c < Double.parseDouble(plugin.config.getString("config.refresh-delay").trim())){ + c+=1; + }else{ + c=0; + } + //refresh here + if(p.getOpenInventory().getTitle().equals(fpanelTitle)){ + if(c == 0) { + //animation counter + if(animatevalue != -1) { + if (animatecount < animatevalue) { + animatecount += 1; + } else { + animatecount = 0; + } + } + try { + plugin.openGui(fpanel, p, cfFinal, 0,animatecount); + } catch (Exception e) { + //error opening gui + } + } + }else{ + if(plugin.config.getString("config.stop-sound").trim().equalsIgnoreCase("true")){ + try { + p.stopSound(Sound.valueOf(cfFinal.getString("panels." + fpanel + ".sound-on-open").toUpperCase())); + }catch(Exception sou){ + //skip + } + } + c = 0; + //check to ensure players haven't duplicated items + try { + p.updateInventory(); + for (ItemStack playerContent : p.getInventory().getStorageContents()) { + for (ItemStack panelContent : panelItemList) { + if (playerContent != null && panelContent != null) { + if (!playerContent.getType().equals(Material.matchMaterial("AIR")) && !panelContent.getType().equals(Material.matchMaterial("AIR"))) { + if (playerContent.equals(panelContent)) { + boolean isOriginal = false; + for (ItemStack playerOriginalContent : playerItemList) { + if (playerOriginalContent != null && !playerOriginalContent.getType().equals(Material.matchMaterial("AIR"))) { + if (playerContent.equals(playerOriginalContent)) { + isOriginal = true; + } + } + } + if(!isOriginal) { + p.getInventory().removeItem(playerContent); + } + } + } + } + } + } + }catch(Exception e){ + //oof + } + this.cancel(); + if(p.getOpenInventory().getTitle().equals(fpanelTitle)) { + p.closeInventory(); + } + plugin.panelRunning.remove(p.getName() + ";" + fpanel); + if (plugin.config.contains("config.panel-snooper")) { + if (plugin.config.getString("config.panel-snooper").trim().equalsIgnoreCase("true")) { + Bukkit.getConsoleSender().sendMessage("[CommandPanels] " + p.getName() + " Closed " + fpanel); + } + } + } + } + }.runTaskTimer(this.plugin, 5, 5); //20 ticks == 1 second (5 ticks = 0.25 of a second) + + } +} diff --git a/src/me/rockyhawk/commandPanels/utils.java b/src/me/rockyhawk/commandPanels/utils.java new file mode 100644 index 0000000..fd0244d --- /dev/null +++ b/src/me/rockyhawk/commandPanels/utils.java @@ -0,0 +1,689 @@ +package me.rockyhawk.commandPanels; + +import me.clip.placeholderapi.PlaceholderAPI; +import org.apache.commons.lang.ObjectUtils; +import org.bukkit.*; +import org.bukkit.block.*; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.*; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.util.*; + +public class utils implements Listener { + commandpanels plugin; + public utils(commandpanels pl) { + this.plugin = pl; + } + @EventHandler + public void onAnyClick(InventoryClickEvent e) { + //on a click when in any inventory + ItemStack clicked = e.getCurrentItem(); + Player p = (Player)e.getWhoClicked(); + //get the item clicked, then loop through panel names after action isn't nothing + if(e.getAction() == InventoryAction.NOTHING){return;} + if (e.getRawSlot() == -999) {return;} + if (e.getSlotType() != InventoryType.SlotType.QUICKBAR) {return;} + for(String[] panelName : plugin.panelNames){ + YamlConfiguration tempFile = plugin.panelFiles.get(Integer.parseInt(panelName[1])); + String tempName = panelName[0]; + if(tempFile.contains("panels." + tempName + ".open-with-item") && e.getClickedInventory().getType() == InventoryType.PLAYER) { + try{ + if (clicked.getType() == new ItemStack(Material.matchMaterial(tempFile.getString("panels." + tempName + ".open-with-item.material")), 1).getType()) { + if ((ChatColor.translateAlternateColorCodes('&', clicked.getItemMeta().getDisplayName()).equals(ChatColor.translateAlternateColorCodes('&', tempFile.getString("panels." + tempName + ".open-with-item.name"))))) { + //cancel the click item event + if (tempFile.contains("panels." + tempName + ".open-with-item.stationary")) { + if (e.getSlot() == Integer.parseInt(tempFile.getString("panels." + tempName + ".open-with-item.stationary"))) { + e.setCancelled(true); + p.updateInventory(); + Bukkit.dispatchCommand(p, "commandpanels:commandpanel " + tempName); + return; + } + } + return; + } + } + }catch(NullPointerException cancel){ + //do nothing skip item + } + } + } + } + @EventHandler + public void onPanelClick(InventoryClickEvent e) { + //when clicked on a panel + String tag = plugin.config.getString("config.format.tag") + " "; + Player p = (Player)e.getWhoClicked(); + ItemStack clicked = e.getCurrentItem(); + try { + if(e.getView().getType() != InventoryType.CHEST){ + //if it isn't a chest interface + return; + } + if(ChatColor.stripColor(e.getView().getTitle()).equals("Chest") || ChatColor.stripColor(e.getView().getTitle()).equals("Large Chest") || ChatColor.stripColor(e.getView().getTitle()).equals("Trapped Chest")){ + //if the inventory is just a chest that has no panel + return; + } + if (plugin.panelsf.list() == null || plugin.panelsf.list().length == 0) { + //if no panels are present + return; + } + }catch(Exception b){ + return; + } + ArrayList filenames = new ArrayList(Arrays.asList(plugin.panelsf.list())); + YamlConfiguration cf = null; //this is the file to use for any panel.* requests + String panel = null; + boolean foundPanel = false; + for (int f = 0; filenames.size() > f; f++) { //will loop through all the files in folder + String key; + YamlConfiguration temp; + temp = YamlConfiguration.loadConfiguration(new File(plugin.panelsf + File.separator + filenames.get(f))); + if(!plugin.checkPanels(temp)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + ": Syntax error Found or Missing certain element!"))); + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext();) { + key = (String) var10.next(); + if(ChatColor.translateAlternateColorCodes('&',temp.getString("panels." + key + ".title")).equals(e.getView().getTitle())){ + panel = key; + cf = YamlConfiguration.loadConfiguration(new File(plugin.panelsf + File.separator + filenames.get(f))); + foundPanel= true; + break; + } + } + if(foundPanel){ + //this is to avoid the plugin to continue looking when it was already found + break; + } + } + if(panel == null){ + return; + } + if(ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&',cf.getString("panels." + panel + ".title"))).equals("Command Panels Editor")){ + //cancel if it is the editor (this should never happen unless the user made a panel called Command Panels Editor for some reason) + return; + } + if(e.getSlotType().equals(InventoryType.SlotType.CONTAINER) && e.getRawSlot() <= Integer.parseInt(cf.getString("panels." + panel + ".rows"))*9-1){ + e.setCancelled(true); + p.updateInventory(); + //this loops through all the items in the panel + boolean foundSlot = false; + for(String slot : cf.getConfigurationSection("panels."+panel+".item").getKeys(false)){ + if(slot.equals(Integer.toString(e.getSlot()))){ + foundSlot = true; + } + } + if(!foundSlot){ + return; + } + String section = ""; + //this will do the noperm without any numbers + //loop through possible noperm/hasperm 1,2,3,etc + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasvalue")) { + //loop through possible hasvalue 1,2,3,etc + for (int count = 0; cf.getConfigurationSection("panels." + panel + ".item." + e.getSlot()).getKeys(false).size() > count; count++) { + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasvalue" + count)) { + boolean outputValue = true; + //outputValue will default to true + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasvalue" + count + ".output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = cf.getBoolean("panels." + panel + ".item." + e.getSlot() + ".hasvalue" + count + ".output"); + } + String value = cf.getString("panels." + panel + ".item." + e.getSlot() + ".hasvalue" + count + ".value"); + String compare = ChatColor.stripColor(plugin.papi(p,plugin.setCpPlaceholders(p,cf.getString("panels." + panel + ".item." + e.getSlot() + ".hasvalue" + count + ".compare")))); + if (compare.equals(value) == outputValue) { + //onOpen being 3 means it is the editor panel.. hasvalue items cannot be included to avoid item breaking + section = ".hasvalue" + count; + break; + } + } + } + //this will do the hasvalue without any numbers + boolean outputValue = true; + //outputValue will default to true + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasvalue.output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = cf.getBoolean("panels." + panel + ".item." + e.getSlot() + ".hasvalue.output"); + } + String value = cf.getString("panels." + panel + ".item." + e.getSlot() + ".hasvalue.value"); + String compare = ChatColor.stripColor(plugin.papi(p,plugin.setCpPlaceholders(p,cf.getString("panels." + panel + ".item." + e.getSlot() + ".hasvalue.compare")))); + if (compare.equals(value) == outputValue) { + //onOpen being 3 means it is the editor panel.. hasvalue items cannot be included to avoid item breaking + section = ".hasvalue"; + } + } + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm") && cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm.perm")) { + for(int count = 0; cf.getConfigurationSection("panels." + panel + ".item." + e.getSlot()).getKeys(false).size() > count; count++){ + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm" + count) && cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm" + count + ".perm")) { + boolean outputValue = true; + //outputValue will default to true + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm" + count + ".output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = cf.getBoolean("panels." + panel + ".item." + e.getSlot() + ".hasperm" + count + ".output"); + } + if (p.hasPermission(cf.getString("panels." + panel + ".item." + e.getSlot() + ".hasperm" + count + ".perm")) == outputValue) { + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm" + count + ".commands") && !(clicked == null)) { + section = ".hasperm" + count; + break; + } else if (clicked != null) { + return; + } + } + } + } + //this will do hasperm with no numbers + boolean outputValue = true; + //outputValue will default to true + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm" + ".output")) { + //if output is true, and values match it will be this item, vice versa + outputValue = cf.getBoolean("panels." + panel + ".item." + e.getSlot() + ".hasperm" + ".output"); + } + if (p.hasPermission(cf.getString("panels." + panel + ".item." + e.getSlot() + ".hasperm.perm")) == outputValue) { + if (cf.contains("panels." + panel + ".item." + e.getSlot() + ".hasperm.commands") && !(clicked == null)) { + section = ".hasperm"; + } else if (clicked != null) { + return; + } + } + } + //this will remove any pending user inputs, if there is already something there from a previous item + for(int o = 0; plugin.userInputStrings.size() > o; o++){ + if(plugin.userInputStrings.get(o)[0].equals(p.getName())){ + plugin.userInputStrings.remove(o); + o=o-1; + } + } + if(cf.contains("panels." + panel + ".item." + e.getSlot() + section + ".commands")) { + List commands = (List) cf.getList("panels." + panel + ".item." + e.getSlot() + section + ".commands"); + if (commands.size() != 0) { + //this will replace a sequence tag command with the commands from the sequence + List commandsAfterSequence = commands; + for (int i = 0; commands.size() - 1 >= i; i++) { + if(commands.get(i).startsWith("sequence=")){ + String locationOfSequence = commands.get(i).split("\\s")[1]; + List commandsSequence = (List) cf.getList(locationOfSequence); + commandsAfterSequence.remove(i); + commandsAfterSequence.addAll(i,commandsSequence); + } + } + commands = commandsAfterSequence; + + for (int i = 0; commands.size() - 1 >= i; i++) { + try { + if (commands.get(i).split("\\s")[0].equalsIgnoreCase("right=")) { + //if commands is for right clicking, remove the 'right=' and continue + commands.set(i, commands.get(i).replace("right=", "").trim()); + commands.set(i, commands.get(i).replace("RIGHT=", "").trim()); + if (e.isLeftClick() || (e.isShiftClick() && e.isLeftClick()) || (e.isShiftClick() && e.isRightClick())) { + continue; + } + } else if (commands.get(i).split("\\s")[0].equalsIgnoreCase("rightshift=")) { + //if commands is for right clicking, remove the 'right=' and continue + commands.set(i, commands.get(i).replace("rightshift=", "").trim()); + commands.set(i, commands.get(i).replace("RIGHTSHIFT=", "").trim()); + if (e.isLeftClick() || (!e.isShiftClick() && e.isRightClick())) { + continue; + } + } + if (commands.get(i).split("\\s")[0].equalsIgnoreCase("left=")) { + //if commands is for right clicking, remove the 'right=' and continue + commands.set(i, commands.get(i).replace("left=", "").trim()); + commands.set(i, commands.get(i).replace("LEFT=", "").trim()); + if (e.isRightClick() || (e.isShiftClick() && e.isRightClick()) || (e.isShiftClick() && e.isLeftClick())) { + continue; + } + } else if (commands.get(i).split("\\s")[0].equalsIgnoreCase("leftshift=")) { + //if commands is for right clicking, remove the 'right=' and continue + commands.set(i, commands.get(i).replace("leftshift=", "").trim()); + commands.set(i, commands.get(i).replace("LEFTSHIFT=", "").trim()); + if (e.isRightClick() || (!e.isShiftClick() && e.isLeftClick())) { + continue; + } + } + if (!e.isLeftClick() && !e.isRightClick()) { + continue; + } + if (clicked == null) { + continue; + } + } catch (Exception click) { + //skip if you can't do this + } + try { + commands.set(i, commands.get(i).replaceAll("%cp-clicked%", clicked.getType().toString())); + } catch (Exception mate) { + commands.set(i, commands.get(i).replaceAll("%cp-clicked%", "Air")); + } + //end custom PlaceHolders + int val = plugin.commandPayWall(p,commands.get(i)); + if(val == 0){ + return; + } + if(val == 2){ + plugin.commandTags(p, commands.get(i)); + } + } + } + } + } + //stop duplicate + p.updateInventory(); + } + @EventHandler + public void onPlayerUse(PlayerInteractEvent e){ + //item right or left clicked + try { + if(e.getAction() != Action.RIGHT_CLICK_AIR && e.getAction() != Action.RIGHT_CLICK_BLOCK && e.getItem().getType() == Material.AIR){ + return; + } + if (plugin.panelsf.list() == null || plugin.panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + ItemStack clicked = e.getItem(); + Player p = e.getPlayer(); + for(String[] panelName : plugin.panelNames){ + YamlConfiguration tempFile = plugin.panelFiles.get(Integer.parseInt(panelName[1])); + String tempName = panelName[0]; + if(tempFile.contains("panels." + tempName + ".open-with-item")) { + try{ + if (clicked.getType() == new ItemStack(Material.matchMaterial(tempFile.getString("panels." + tempName + ".open-with-item.material")), 1).getType()) { + if ((ChatColor.translateAlternateColorCodes('&', clicked.getItemMeta().getDisplayName()).equals(ChatColor.translateAlternateColorCodes('&', tempFile.getString("panels." + tempName + ".open-with-item.name"))))) { + //cancel the click item event + if (tempFile.contains("panels." + tempName + ".open-with-item.stationary")) { + if (p.getInventory().getHeldItemSlot() != Integer.parseInt(tempFile.getString("panels." + tempName + ".open-with-item.stationary"))) { + return; + } + } + e.setCancelled(true); + p.updateInventory(); + Bukkit.dispatchCommand(p, "commandpanels:commandpanel " + tempName); + return; + } + } + }catch(NullPointerException cancel){ + //do nothing skip item + } + } + } + } + @EventHandler + public void onWorldChange(PlayerChangedWorldEvent e){ + /* + This world change event is added so if the player is using disabled-worlds + and they change worlds, it will check if the player can have the item + and if they can, it gives the item. This is because onRespawn doesn't + give the item to the player in all the worlds that it could automatically. + + The player will of course need a plugin to split inventories between worlds + for this to take effect. I don't want to delete the item on the wrong world + because then it might overwrite one of their actual slots upon rejoining the enabled world. + */ + Player p = e.getPlayer(); + try { + if (plugin.panelsf.list() == null || plugin.panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + YamlConfiguration cf; //this is the file to use for any panel.* requests + String tpanels; //tpanels is the temp to check through the files + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if(temp.contains("panels." + key + ".disabled-worlds")){ + List disabledWorlds = (List) temp.getList("panels." + key + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + continue; + } + } + if (p.hasPermission("commandpanel.panel." + temp.getString("panels." + key + ".perm")) && temp.contains("panels." + key + ".open-with-item")) { + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1); + }catch(Exception n){ + return; + } + plugin.setName(s, temp.getString("panels." + key + ".open-with-item.name"), temp.getList("panels." + key + ".open-with-item.lore"),p,true); + if(temp.contains("panels." + key + ".open-with-item.stationary")) { + if (0 <= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")) && 8 >= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))) { + p.getInventory().setItem(Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")), s); + } + } + } + } + } + } + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent e){ + Player p = e.getPlayer(); + try { + if (plugin.panelsf.list() == null || plugin.panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + YamlConfiguration cf; //this is the file to use for any panel.* requests + String tpanels; //tpanels is the temp to check through the files + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if(temp.contains("panels." + key + ".disabled-worlds")){ + List disabledWorlds = (List) temp.getList("panels." + key + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + continue; + } + } + if (p.hasPermission("commandpanel.panel." + temp.getString("panels." + key + ".perm")) && temp.contains("panels." + key + ".open-with-item")) { + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1); + }catch(Exception n){ + return; + } + plugin.setName(s, temp.getString("panels." + key + ".open-with-item.name"), temp.getList("panels." + key + ".open-with-item.lore"),p,true); + if(temp.contains("panels." + key + ".open-with-item.stationary") && 0 <= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")) && 8 >= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))){ + p.getInventory().setItem(Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")), s); + } + } + } + } + } + @EventHandler + public void onPlayerDeath(PlayerDeathEvent e){ + Player p = (Player)e.getEntity(); + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + YamlConfiguration cf; //this is the file to use for any panel.* requests + String tpanels; //tpanels is the temp to check through the files + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if (p.hasPermission("commandpanel.panel." + temp.getString("panels." + key + ".perm")) && temp.contains("panels." + key + ".open-with-item")) { + if(temp.contains("panels." + key + ".open-with-item.stationary")){ + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1); + }catch(Exception n){ + return; + } + plugin.setName(s, temp.getString("panels." + key + ".open-with-item.name"), temp.getList("panels." + key + ".open-with-item.lore"),p,true); + e.getDrops().remove(s); + } + } + } + } + } + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e){ + Player p = e.getPlayer(); + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + String tag = plugin.config.getString("config.format.tag") + " "; + if(p.isOp() || p.hasPermission("*.*")){ + if(plugin.update) { + p.sendMessage(ChatColor.WHITE + "CommandPanels " + ChatColor.DARK_RED + "is not running the latest version! A new version is available at"); + p.sendMessage(ChatColor.RED + "https://www.spigotmc.org/resources/command-panels-custom-guis.67788/"); + } + } + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + String tpanels; //tpanels is the temp to check through the files + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + p.sendMessage(ChatColor.translateAlternateColorCodes('&',tag + plugin.papi(p, plugin.config.getString("config.format.error") + ": Missing required component in panel!"))); + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if (p.hasPermission("commandpanel.panel." + temp.getString("panels." + key + ".perm")) && temp.contains("panels." + key + ".open-with-item")) { + if(temp.contains("panels." + key + ".disabled-worlds")){ + List disabledWorlds = (List) temp.getList("panels." + key + ".disabled-worlds"); + if(disabledWorlds.contains(p.getWorld().getName())){ + continue; + } + } + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1); + }catch(Exception n){ + continue; + } + plugin.setName(s, temp.getString("panels." + key + ".open-with-item.name"), temp.getList("panels." + key + ".open-with-item.lore"),p,true); + if(temp.contains("panels." + key + ".open-with-item.stationary") && 0 <= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")) && 8 >= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))){ + p.getInventory().setItem(Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")), s); + } + }else{ + //if the player has an item that they have no permission for, remove it + ItemStack s; + try { + s = new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1); + }catch(Exception n){ + continue; + } + plugin.setName(s, temp.getString("panels." + key + ".open-with-item.name"), temp.getList("panels." + key + ".open-with-item.lore"),p,true); + if(temp.contains("panels." + key + ".open-with-item.stationary") && 0 <= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")) && 8 >= Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))){ + try { + if (p.getInventory().getItem(Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))).isSimilar(s)) { + p.getInventory().setItem(Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary")), null); + } + }catch(NullPointerException nex){ + //skip as player has no item in slot + } + } + } + } + } + } + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent e){ + //if item dropped + Player p = e.getPlayer(); + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + YamlConfiguration cf; //this is the file to use for any panel.* requests + String tpanels; //tpanels is the temp to check through the files + ItemStack clicked = e.getItemDrop().getItemStack(); + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + for(String ekey : temp.getConfigurationSection("panels").getKeys(false)){ + if(temp.contains("panels." + key + ".open-with-item")){ + if(clicked.getType() != Material.AIR) { + //if loop has material first to stop 1.12.2 from spitting errors + //try and catch loop to stop errors with the same material type but different name + try { + if (clicked.getType() == new ItemStack(Material.matchMaterial(temp.getString("panels." + ekey + ".open-with-item.material")), 1).getType()) { + if ((ChatColor.translateAlternateColorCodes('&',clicked.getItemMeta().getDisplayName()).equals(ChatColor.translateAlternateColorCodes('&',temp.getString("panels." + ekey + ".open-with-item.name"))))) { + //cancel the click item event + if(temp.contains("panels." + key + ".open-with-item.stationary")){ + if(p.getInventory().getHeldItemSlot() == Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))){ + e.setCancelled(true); + return; + } + } + } + } + }catch(Exception n){ + //do nothing + } + } + } + } + } + } + } + @EventHandler + public void onPlayerSwapHandItemsEvent​(PlayerSwapHandItemsEvent e){ + Player p = e.getPlayer(); + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + YamlConfiguration cf; //this is the file to use for any panel.* requests + String tpanels; //tpanels is the temp to check through the files + ItemStack clicked = e.getOffHandItem(); + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if(temp.contains("panels." + key + ".open-with-item")){ + if(clicked.getType() != Material.AIR) { + ItemStack s = clicked; + //if loop has material first to stop 1.12.2 from spitting errors + //try and catch loop to stop errors with the same material type but different name + try { + if (s.getType() == new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1).getType()) { + if ((ChatColor.translateAlternateColorCodes('&',s.getItemMeta().getDisplayName()).equals(ChatColor.translateAlternateColorCodes('&',temp.getString("panels." + key + ".open-with-item.name"))))) { + //cancel the click item event + if(temp.contains("panels." + key + ".open-with-item.stationary")){ + if(p.getInventory().getHeldItemSlot() == Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))){ + e.setCancelled(true); + } + } + return; + } + } + }catch(NullPointerException n){ + //do nothing + }catch(IllegalArgumentException i){ + //do nothing + } + } + } + } + } + } + @EventHandler + public void onInteract(PlayerInteractEvent e){ + String tag = plugin.config.getString("config.format.tag") + " "; + if(e.getAction() == Action.RIGHT_CLICK_BLOCK) { + Block block = e.getClickedBlock(); + Player p = e.getPlayer(); + if (block.getType().toString().contains("SIGN")) { + Sign sign = (Sign) block.getState(); + if (ChatColor.stripColor(sign.getLine(0).trim()).equalsIgnoreCase(ChatColor.stripColor(plugin.config.getString("config.format.signtag")))) { + try { + Bukkit.dispatchCommand(p, "commandpanels:commandpanel " + ChatColor.stripColor(sign.getLine(1)).trim()); + } catch (Exception n) { + if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + PlaceholderAPI.setPlaceholders(p, plugin.config.getString("config.format.nopanel")))); + } else { + p.sendMessage(ChatColor.translateAlternateColorCodes('&', tag + plugin.config.getString("config.format.nopanel"))); + } + } + } + } + } + } + @EventHandler + public void onInteractEntity(PlayerInteractEntityEvent e){ + //cancel everything if holding item (item frames eg) + Player p = (Player)e.getPlayer(); + File panelsf = new File(plugin.getDataFolder() + File.separator + "panels"); + try { + if (panelsf.list() == null || panelsf.list().length == 0) { + return; + } + }catch(Exception b){ + return; + } + YamlConfiguration cf; //this is the file to use for any panel.* requests + String tpanels; //tpanels is the temp to check through the files + ItemStack clicked = e.getPlayer().getInventory().getItemInMainHand(); + for(YamlConfiguration temp : plugin.panelFiles) { //will loop through all the files in folder + String key; + tpanels = ""; + if(!plugin.checkPanels(temp)){ + return; + } + for (Iterator var10 = temp.getConfigurationSection("panels").getKeys(false).iterator(); var10.hasNext(); tpanels = tpanels + key + " ") { + key = (String) var10.next(); + if (temp.contains("panels." + key + ".open-with-item")) { + if (clicked.getType() != Material.AIR) { + ItemStack s = clicked; + //if loop has material first to stop 1.12.2 from spitting errors + //try and catch loop to stop errors with the same material type but different name + try { + if (s.getType() == new ItemStack(Material.matchMaterial(temp.getString("panels." + key + ".open-with-item.material")), 1).getType()) { + if ((ChatColor.translateAlternateColorCodes('&', s.getItemMeta().getDisplayName()).equals(ChatColor.translateAlternateColorCodes('&', temp.getString("panels." + key + ".open-with-item.name"))))) { + //cancel the click item event + if (temp.contains("panels." + key + ".open-with-item.stationary")) { + if (p.getInventory().getHeldItemSlot() == Integer.parseInt(temp.getString("panels." + key + ".open-with-item.stationary"))) { + e.setCancelled(true); + } + } + return; + } + } + } catch (NullPointerException n) { + //do nothing + } catch (IllegalArgumentException i) { + //do nothing + } + } + } + } + } + } +}