diff --git a/CHANGELOG.md b/CHANGELOG.md index 3447bbc..d988d69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 7.7-pre1 +- Moved /invsort command to separate class +- Moved registerPlayerIfNeeded from Listener to main class +- Save player configs only if they have changed + ## 7.6.1 - Changed description for hotkeys in config.yml - Updated French translation diff --git a/pom.xml b/pom.xml index de864a3..2609a3c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ de.jeffclan JeffChestSort - 7.6.1 + 7.7-pre1 jar JeffChestSort diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortChestSortCommand.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortChestSortCommand.java new file mode 100644 index 0000000..deb458b --- /dev/null +++ b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortChestSortCommand.java @@ -0,0 +1,92 @@ +package de.jeffclan.JeffChestSort; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import de.jeffclan.JeffChestSort.JeffChestSortPlayerSetting; +import de.jeffclan.JeffChestSort.JeffChestSortPlugin; + +public class JeffChestSortChestSortCommand implements CommandExecutor { + + JeffChestSortPlugin plugin; + + JeffChestSortChestSortCommand(JeffChestSortPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + + // This command toggles automatic chest sorting for the player that runs the command + if (!command.getName().equalsIgnoreCase("chestsort")) { + return false; + } + + if (!(sender instanceof Player)) { + + if(args.length!=0) { + if(args[0].equalsIgnoreCase("debug")) { + plugin.debug=true; + plugin.getLogger().info("ChestSort debug mode enabled."); + return true; + } + } + + sender.sendMessage(plugin.messages.MSG_PLAYERSONLY); + return true; + } + + Player p = (Player) sender; + + // fix for Spigot's stupid /reload function + plugin.registerPlayerIfNeeded(p); + + // Settings GUI + if(args.length>0) { + if(args[0].equalsIgnoreCase("hotkey") || args[0].equalsIgnoreCase("hotkeys")) { + +// if(plugin.hotkeyGUI==false) { +// p.sendMessage(plugin.messages.MSG_ERR_HOTKEYSDISABLED); +// return true; +// } + + plugin.settingsGUI.openGUI(p); + + return true; + } + + } + // Settings GUI End + + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString()); + + if(args.length>0 + && !args[0].equalsIgnoreCase("toggle") + && !args[0].equalsIgnoreCase("on") + && !args[0].equalsIgnoreCase("off")) { + p.sendMessage(String.format(plugin.messages.MSG_INVALIDOPTIONS,"\""+args[0]+"\"","\"toggle\", \"on\", \"off\", \"hotkeys\"")); + return true; + } + if(args.length==0 || args[0].equalsIgnoreCase("toggle")) { + setting.toggleChestSorting(); + } + else if(args[0].equalsIgnoreCase("on")) { + setting.enableChestSorting(); + } + else if(args[0].equalsIgnoreCase("off")) { + setting.disableChestSorting(); + } + setting.hasSeenMessage=true; + + if (setting.sortingEnabled) { + p.sendMessage(plugin.messages.MSG_ACTIVATED); + } else { + p.sendMessage(plugin.messages.MSG_DEACTIVATED); + } + + return true; + } + +} diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortCommandExecutor.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortCommandExecutor.java deleted file mode 100644 index 2c7bb04..0000000 --- a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortCommandExecutor.java +++ /dev/null @@ -1,149 +0,0 @@ -package de.jeffclan.JeffChestSort; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class JeffChestSortCommandExecutor implements CommandExecutor { - - JeffChestSortPlugin plugin; - - JeffChestSortCommandExecutor(JeffChestSortPlugin plugin) { - this.plugin = plugin; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - - // This command toggles automatic chest sorting for the player that runs the command - if (command.getName().equalsIgnoreCase("chestsort")) { - - if (!(sender instanceof Player)) { - - if(args.length!=0) { - if(args[0].equalsIgnoreCase("debug")) { - plugin.debug=true; - sender.sendMessage("ChestSort debug mode enabled."); - return true; - } else if(args[0].equalsIgnoreCase("reload")) { - // TODO: EXPERIMENTAL - plugin.onDisable(); - plugin.onEnable(); - - } - } - - sender.sendMessage(plugin.messages.MSG_PLAYERSONLY); - return true; - } - - Player p = (Player) sender; - - // fix for Spigot's stupid /reload function - plugin.listener.registerPlayerIfNeeded(p); - - // Settings GUI - if(args.length>0) { - if(args[0].equalsIgnoreCase("hotkey") || args[0].equalsIgnoreCase("hotkeys")) { - -// if(plugin.hotkeyGUI==false) { -// p.sendMessage(plugin.messages.MSG_ERR_HOTKEYSDISABLED); -// return true; -// } - - plugin.settingsGUI.openGUI(p); - - return true; - } - - } - // Settings GUI End - - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); - - if(args.length>0 - && !args[0].equalsIgnoreCase("toggle") - && !args[0].equalsIgnoreCase("on") - && !args[0].equalsIgnoreCase("off")) { - p.sendMessage(String.format(plugin.messages.MSG_INVALIDOPTIONS,"\""+args[0]+"\"","\"toggle\", \"on\", \"off\", \"hotkeys\"")); - return true; - } - if(args.length==0 || args[0].equalsIgnoreCase("toggle")) { - setting.sortingEnabled = !setting.sortingEnabled; - } - else if(args[0].equalsIgnoreCase("on")) { - setting.sortingEnabled = true; - } - else if(args[0].equalsIgnoreCase("off")) { - setting.sortingEnabled = false; - } - setting.hasSeenMessage=true; - - if (setting.sortingEnabled) { - p.sendMessage(plugin.messages.MSG_ACTIVATED); - } else { - p.sendMessage(plugin.messages.MSG_DEACTIVATED); - } - - return true; - - } else if(command.getName().equalsIgnoreCase("invsort")) { - // This command sorts the player's inventory - - if (!(sender instanceof Player)) { - sender.sendMessage(plugin.messages.MSG_PLAYERSONLY); - return true; - } - - Player p = (Player) sender; - - int start = 9; - int end = 35; - - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); - - if(args.length>0) { - if(args[0].equalsIgnoreCase("all")) { - start=0; - end=35; - } else if(args[0].equalsIgnoreCase("hotbar")) { - start=0; - end=8; - } else if(args[0].equalsIgnoreCase("inv")) { - start=9; - end=35; - } else if(args[0].equalsIgnoreCase("on")) { - setting.invSortingEnabled = true; - p.sendMessage(plugin.messages.MSG_INVACTIVATED); - return true; - } else if(args[0].equalsIgnoreCase("off")) { - setting.invSortingEnabled = false; - p.sendMessage(plugin.messages.MSG_INVDEACTIVATED); - return true; - } else if(args[0].equalsIgnoreCase("toggle")) { - setting.invSortingEnabled = !setting.invSortingEnabled; - if(setting.invSortingEnabled) { - p.sendMessage(plugin.messages.MSG_INVACTIVATED); - } else { - p.sendMessage(plugin.messages.MSG_INVDEACTIVATED); - } - return true; - } - else { - p.sendMessage(String.format(plugin.messages.MSG_INVALIDOPTIONS,"\""+args[0]+"\"","\"on\", \"off\", \"toggle\", \"inv\", \"hotbar\", \"all\"")); - return true; - } - } - - plugin.sortInventory(p.getInventory(), start, end); - p.sendMessage(plugin.messages.MSG_PLAYERINVSORTED); - - return true; - - } - - return false; - } - -} diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortInvSortCommand.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortInvSortCommand.java new file mode 100644 index 0000000..5a7fcc4 --- /dev/null +++ b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortInvSortCommand.java @@ -0,0 +1,76 @@ +package de.jeffclan.JeffChestSort; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class JeffChestSortInvSortCommand implements CommandExecutor { + + JeffChestSortPlugin plugin; + + JeffChestSortInvSortCommand(JeffChestSortPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + + // This command toggles automatic chest sorting for the player that runs the command + if (!command.getName().equalsIgnoreCase("invsort")) { + return false; + } + + if (!(sender instanceof Player)) { + sender.sendMessage(plugin.messages.MSG_PLAYERSONLY); + return true; + } + + Player p = (Player) sender; + + int start = 9; + int end = 35; + + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString()); + + if(args.length>0) { + if(args[0].equalsIgnoreCase("all")) { + start=0; + end=35; + } else if(args[0].equalsIgnoreCase("hotbar")) { + start=0; + end=8; + } else if(args[0].equalsIgnoreCase("inv")) { + start=9; + end=35; + } else if(args[0].equalsIgnoreCase("on")) { + setting.enableInvSorting(); + p.sendMessage(plugin.messages.MSG_INVACTIVATED); + return true; + } else if(args[0].equalsIgnoreCase("off")) { + setting.disableInvSorting(); + p.sendMessage(plugin.messages.MSG_INVDEACTIVATED); + return true; + } else if(args[0].equalsIgnoreCase("toggle")) { + setting.toggleInvSorting(); + if(setting.invSortingEnabled) { + p.sendMessage(plugin.messages.MSG_INVACTIVATED); + } else { + p.sendMessage(plugin.messages.MSG_INVDEACTIVATED); + } + return true; + } + else { + p.sendMessage(String.format(plugin.messages.MSG_INVALIDOPTIONS,"\""+args[0]+"\"","\"on\", \"off\", \"toggle\", \"inv\", \"hotbar\", \"all\"")); + return true; + } + } + + plugin.sortInventory(p.getInventory(), start, end); + p.sendMessage(plugin.messages.MSG_PLAYERINVSORTED); + + return true; + + } + +} diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortListener.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortListener.java index 8caf208..fddfbdf 100644 --- a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortListener.java +++ b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortListener.java @@ -1,13 +1,9 @@ package de.jeffclan.JeffChestSort; -import java.io.File; -import java.util.UUID; - import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Chest; import org.bukkit.block.DoubleChest; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -38,11 +34,6 @@ public class JeffChestSortListener implements Listener { // DEBUG // To enable debug mode, put debug: true into your config.yml - // Checking for my username because I always forget to comment this out before - // releases - // if (event.getPlayer().getName().equalsIgnoreCase("mfnalex")) { - // plugin.debug = true; - // } // OPs will get an update notice if a new update is available if (event.getPlayer().isOp()) { @@ -50,67 +41,10 @@ public class JeffChestSortListener implements Listener { } // Put player into our perPlayerSettings map - registerPlayerIfNeeded(event.getPlayer()); + plugin.registerPlayerIfNeeded(event.getPlayer()); } - // Put player into our perPlayerSettings map - void registerPlayerIfNeeded(Player p) { - // Players are stored by their UUID, so that name changes don't break player's - // settings - UUID uniqueId = p.getUniqueId(); - - // Add player to map only if they aren't registered already - if (!plugin.PerPlayerSettings.containsKey(uniqueId.toString())) { - - // Player settings are stored in a file named after the player's UUID - File playerFile = new File(plugin.getDataFolder() + File.separator + "playerdata", - p.getUniqueId().toString() + ".yml"); - YamlConfiguration playerConfig = YamlConfiguration.loadConfiguration(playerFile); - - playerConfig.addDefault("invSortingEnabled", plugin.getConfig().getBoolean("inv-sorting-enabled-by-default")); - playerConfig.addDefault("middleClick", plugin.getConfig().getBoolean("hotkeys.middle-click")); - playerConfig.addDefault("shiftClick", plugin.getConfig().getBoolean("hotkeys.shift-click")); - playerConfig.addDefault("doubleClick", plugin.getConfig().getBoolean("hotkeys.double-click")); - playerConfig.addDefault("shiftRightClick", plugin.getConfig().getBoolean("hotkeys.shift-right-click")); - - boolean activeForThisPlayer = false; - boolean invActiveForThisPlayer = false; - boolean middleClick, shiftClick, doubleClick, shiftRightClick; - - if (!playerFile.exists()) { - // If the player settings file does not exist for this player, set it to the - // default value - activeForThisPlayer = plugin.getConfig().getBoolean("sorting-enabled-by-default"); - invActiveForThisPlayer = plugin.getConfig().getBoolean("inv-sorting-enabled-by-default"); - middleClick = plugin.getConfig().getBoolean("hotkeys.middle-click"); - shiftClick = plugin.getConfig().getBoolean("hotkeys.shift-click"); - doubleClick = plugin.getConfig().getBoolean("hotkeys.double-click"); - shiftRightClick = plugin.getConfig().getBoolean("hotkeys.shift-right-click"); - } else { - // If the file exists, check if the player has sorting enabled - activeForThisPlayer = playerConfig.getBoolean("sortingEnabled"); - invActiveForThisPlayer = playerConfig.getBoolean("invSortingEnabled"); - middleClick = playerConfig.getBoolean("middleClick"); - shiftClick = playerConfig.getBoolean("shiftClick"); - doubleClick = playerConfig.getBoolean("doubleClick"); - shiftRightClick = playerConfig.getBoolean("shiftRightClick"); - } - - JeffChestSortPlayerSetting newSettings = new JeffChestSortPlayerSetting(activeForThisPlayer,invActiveForThisPlayer,middleClick,shiftClick,doubleClick,shiftRightClick); - - // when "show-message-again-after-logout" is enabled, we don't care if the - // player already saw the message - if (!plugin.getConfig().getBoolean("show-message-again-after-logout")) { - newSettings.hasSeenMessage = playerConfig.getBoolean("hasSeenMessage"); - } - - // Finally add the PlayerSetting object to the map - plugin.PerPlayerSettings.put(uniqueId.toString(), newSettings); - - } - } - @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { plugin.unregisterPlayer(event.getPlayer()); @@ -127,9 +61,9 @@ public class JeffChestSortListener implements Listener { Player p = (Player) event.getInventory().getHolder(); if(!p.hasPermission("chestsort.use.inventory")) return; - registerPlayerIfNeeded(p); + plugin.registerPlayerIfNeeded(p); - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString()); if(!setting.invSortingEnabled) return; plugin.organizer.sortInventory(p.getInventory(),9,35); @@ -251,12 +185,12 @@ public class JeffChestSortListener implements Listener { } // Fixes exception when using Spigot's stupid /reload command - registerPlayerIfNeeded(p); + plugin.registerPlayerIfNeeded(p); // Get the current player's settings // We do not immediately cancel when sorting is disabled because we might want // to show the hint message - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString()); // Show "how to enable ChestSort" message when ALL of the following criteria are // met: @@ -323,7 +257,7 @@ public class JeffChestSortListener implements Listener { Player p = (Player) event.getWhoClicked(); - registerPlayerIfNeeded(p); + plugin.registerPlayerIfNeeded(p); if(!plugin.getConfig().getBoolean("allow-hotkeys")) { return; @@ -349,7 +283,7 @@ public class JeffChestSortListener implements Listener { boolean sort = false; - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString()); // Do not sort the GUI inventory if(event.getClickedInventory() == setting.guiInventory) { @@ -439,55 +373,5 @@ public class JeffChestSortListener implements Listener { } } } - - @EventHandler - void onGUIInteract(InventoryClickEvent event) { - if(plugin.hotkeyGUI==false) { - return; - } - if(!(event.getWhoClicked() instanceof Player)) { - return; - } - Player p = (Player) event.getWhoClicked(); - registerPlayerIfNeeded(p); - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(p.getUniqueId().toString()); - - if(setting.guiInventory==null) { - return; - } - - if(event.getClickedInventory()==null) { - return; - } - if(!event.getClickedInventory().equals(setting.guiInventory)) { - return; - } - - // We only get this far if the player has clicked inside his GUI inventory - event.setCancelled(true); - if(event.getClick() != ClickType.LEFT) { - return; - } - - if(event.getSlot() == JeffChestSortSettingsGUI.slotMiddleClick) { - setting.middleClick = !setting.middleClick; - plugin.settingsGUI.openGUI(p); - return; - } - else if(event.getSlot() == JeffChestSortSettingsGUI.slotShiftClick) { - setting.shiftClick = !setting.shiftClick; - plugin.settingsGUI.openGUI(p); - return; - } else if(event.getSlot() == JeffChestSortSettingsGUI.slotDoubleClick) { - setting.doubleClick = !setting.doubleClick; - plugin.settingsGUI.openGUI(p); - return; - } else if(event.getSlot() == JeffChestSortSettingsGUI.slotShiftRightClick) { - setting.shiftRightClick = !setting.shiftRightClick; - plugin.settingsGUI.openGUI(p); - return; - } - - } } diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlayerSetting.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlayerSetting.java index 3af47a3..5a8fcbd 100644 --- a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlayerSetting.java +++ b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlayerSetting.java @@ -22,14 +22,59 @@ public class JeffChestSortPlayerSetting { // Did we already show the message how to activate sorting? boolean hasSeenMessage = false; + + // Do we have to save these settings? + boolean changed = false; - JeffChestSortPlayerSetting(boolean sortingEnabled, boolean invSortingEnabled, boolean middleClick, boolean shiftClick, boolean doubleClick, boolean shiftRightClick) { + JeffChestSortPlayerSetting(boolean sortingEnabled, boolean invSortingEnabled, boolean middleClick, boolean shiftClick, boolean doubleClick, boolean shiftRightClick, boolean changed) { this.sortingEnabled = sortingEnabled; this.middleClick = middleClick; this.shiftClick = shiftClick; this.doubleClick = doubleClick; this.shiftRightClick = shiftRightClick; this.invSortingEnabled = invSortingEnabled; + this.changed = changed; + } + + void toggleMiddleClick() { + middleClick = !middleClick; + changed = true; + } + void toggleShiftClick() { + shiftClick = !shiftClick; + changed = true; + } + void toggleDoubleClick() { + doubleClick = !doubleClick; + changed = true; + } + void toggleShiftRightClick() { + shiftRightClick = !shiftRightClick; + changed = true; + } + void enableChestSorting() { + sortingEnabled = true; + changed = true; + } + void disableChestSorting() { + sortingEnabled = false; + changed = true; + } + void toggleChestSorting() { + sortingEnabled = !sortingEnabled; + changed = true; + } + void enableInvSorting() { + invSortingEnabled = true; + changed = true; + } + void disableInvSorting() { + invSortingEnabled = false; + changed = true; + } + void toggleInvSorting() { + invSortingEnabled = !invSortingEnabled; + changed = true; } } diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlugin.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlugin.java index 643c1f2..5f2e76c 100644 --- a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlugin.java +++ b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortPlugin.java @@ -1,6 +1,3 @@ -package de.jeffclan.JeffChestSort; - -import java.io.BufferedWriter; /* @@ -18,9 +15,6 @@ import java.io.BufferedWriter; Please DO NOT post bug reports or feature requests in the review section at SpigotMC.org. Thank you. - NOTE: The project has been converted to maven by Azzurite (thanks again). You will need to - `mvn install` to create a working .jar. - ============================================================================================= TECHNICAL INFORMATION: @@ -32,6 +26,9 @@ import java.io.BufferedWriter; */ +package de.jeffclan.JeffChestSort; + +import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; @@ -47,7 +44,6 @@ import java.util.UUID; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -59,7 +55,7 @@ import de.jeffclan.utils.Utils; public class JeffChestSortPlugin extends JavaPlugin { // We need a map to store each player's settings - Map PerPlayerSettings = new HashMap(); + Map perPlayerSettings = new HashMap(); JeffChestSortMessages messages; JeffChestSortOrganizer organizer; JeffChestSortUpdateChecker updateChecker; @@ -69,7 +65,7 @@ public class JeffChestSortPlugin extends JavaPlugin { ArrayList disabledWorlds; int currentConfigVersion = 22; boolean usingMatchingConfig = true; - boolean debug = false; + protected boolean debug = false; boolean verbose = true; boolean hotkeyGUI = true; @@ -163,7 +159,6 @@ public class JeffChestSortPlugin extends JavaPlugin { getConfig().addDefault("hook-crackshot", true); getConfig().addDefault("hook-crackshot-prefix", "crackshot_weapon"); - getConfig().addDefault("hook-inventorypages", true); getConfig().addDefault("verbose", true); // Prints some information in onEnable() @@ -193,31 +188,6 @@ public class JeffChestSortPlugin extends JavaPlugin { getLogger().warning("=============================================="); } - private void renameConfigIfTooOld() { - getLogger().warning("========================================================"); - getLogger().warning("You are using a config file that has been generated"); - getLogger().warning("prior to ChestSort version 2.0.0."); - getLogger().warning("To allow everyone to use the new features, your config"); - getLogger().warning("has been renamed to config.old.yml and a new one has"); - getLogger().warning("been generated. Please examine the new config file to"); - getLogger().warning("see the new possibilities and adjust your settings."); - getLogger().warning("========================================================"); - - File configFile = new File(getDataFolder().getAbsolutePath() + File.separator + "config.yml"); - File oldConfigFile = new File(getDataFolder().getAbsolutePath() + File.separator + "config.old.yml"); - if (oldConfigFile.getAbsoluteFile().exists()) { - oldConfigFile.getAbsoluteFile().delete(); - } - configFile.getAbsoluteFile().renameTo(oldConfigFile.getAbsoluteFile()); - saveDefaultConfig(); - try { - getConfig().load(configFile.getAbsoluteFile()); - } catch (IOException | InvalidConfigurationException e) { - getLogger().warning("Could not load freshly generated config file!"); - e.printStackTrace(); - } - } - @Override public void onDisable() { // We have to unregister every player to save their perPlayerSettings @@ -233,12 +203,6 @@ public class JeffChestSortPlugin extends JavaPlugin { mcVersion = tmpVersion.substring(tmpVersion.lastIndexOf('.') + 1); tmpVersion = mcVersion.substring(mcVersion.indexOf("_")+1); mcMinorVersion = Integer.parseInt(tmpVersion.substring(0,tmpVersion.indexOf("_"))); - - //getLogger().info("Running MC version 1."+mcMinorVersion); -// if(mcMinorVersion < 9) { -// getLogger().info("You are running a Minecraft version below 1.9. Hotkey GUI will be disabled."); -// hotkeyGUI = false; -// } // Create the config file, including checks for old config versions, and load // the default values for unset options @@ -281,19 +245,25 @@ public class JeffChestSortPlugin extends JavaPlugin { // the Organizer to sort inventories when a player closes a chest, shulkerbox or // barrel inventory listener = new JeffChestSortListener(this); + + //hotbarRefiller = new JeffChestSortHotbarRefiller(this); // The sorting method will determine how stuff is sorted sortingMethod = getConfig().getString("sorting-method"); // Register the events for our Listener getServer().getPluginManager().registerEvents(listener, this); + + // Register events for the GUI interaction + getServer().getPluginManager().registerEvents(settingsGUI, this); // Create the CommandExecutor, register commands and set their TabCompleter - JeffChestSortCommandExecutor commandExecutor = new JeffChestSortCommandExecutor(this); + JeffChestSortChestSortCommand chestsortCommandExecutor = new JeffChestSortChestSortCommand(this); JeffChestSortTabCompleter tabCompleter = new JeffChestSortTabCompleter(); - this.getCommand("chestsort").setExecutor(commandExecutor); + this.getCommand("chestsort").setExecutor(chestsortCommandExecutor); this.getCommand("chestsort").setTabCompleter(tabCompleter); - this.getCommand("invsort").setExecutor(commandExecutor); + JeffChestSortInvSortCommand invsortCommandExecutor = new JeffChestSortInvSortCommand(this); + this.getCommand("invsort").setExecutor(invsortCommandExecutor); this.getCommand("invsort").setTabCompleter(tabCompleter); // Does anyone actually need this? @@ -315,7 +285,6 @@ public class JeffChestSortPlugin extends JavaPlugin { } // Check for updates (async, of course) - // When set to true, we check for updates right now, and every 24 hours (see // updateCheckInterval) if (getConfig().getString("check-for-updates", "true").equalsIgnoreCase("true")) { @@ -333,6 +302,8 @@ public class JeffChestSortPlugin extends JavaPlugin { registerMetrics(); + // When dump is set to true in config.yml, we dump all items with their categories + // to find out which items are still missing in the category files if(getConfig().getBoolean("dump")) { try { dump(); @@ -341,7 +312,6 @@ public class JeffChestSortPlugin extends JavaPlugin { e.printStackTrace(); } } - } private String getCategoryList() { @@ -483,13 +453,13 @@ public class JeffChestSortPlugin extends JavaPlugin { // server ;) I am sometimes getting stacktraces although it is clearly stated // that /reload is NOT // supported. So, here is a quick fix - if (PerPlayerSettings == null) { - PerPlayerSettings = new HashMap(); + if (perPlayerSettings == null) { + perPlayerSettings = new HashMap(); } - listener.registerPlayerIfNeeded(p); + listener.plugin.registerPlayerIfNeeded(p); // End of quick fix - return PerPlayerSettings.get(p.getUniqueId().toString()).sortingEnabled; + return perPlayerSettings.get(p.getUniqueId().toString()).sortingEnabled; } // Unregister a player and save their settings in the playerdata folder @@ -501,8 +471,9 @@ public class JeffChestSortPlugin extends JavaPlugin { // When using /reload or some other obscure features, it can happen that players // are online // but not registered. So, we only continue when the player has been registered - if (PerPlayerSettings.containsKey(uniqueId.toString())) { - JeffChestSortPlayerSetting setting = PerPlayerSettings.get(p.getUniqueId().toString()); + if (perPlayerSettings.containsKey(uniqueId.toString())) { + JeffChestSortPlayerSetting setting = perPlayerSettings.get(p.getUniqueId().toString()); + File playerFile = new File(getDataFolder() + File.separator + "playerdata", p.getUniqueId().toString() + ".yml"); YamlConfiguration playerConfig = YamlConfiguration.loadConfiguration(playerFile); @@ -514,12 +485,18 @@ public class JeffChestSortPlugin extends JavaPlugin { playerConfig.set("doubleClick",setting.doubleClick); playerConfig.set("shiftRightClick",setting.shiftRightClick); try { - playerConfig.save(playerFile); + // Only saved if the config has been changed + if(setting.changed) { + if(debug) { + getLogger().info("PlayerSettings for "+p.getName()+" have changed, saving to file."); + } + playerConfig.save(playerFile); + } } catch (IOException e) { e.printStackTrace(); } - PerPlayerSettings.remove(uniqueId.toString()); + perPlayerSettings.remove(uniqueId.toString()); } } @@ -535,4 +512,68 @@ public class JeffChestSortPlugin extends JavaPlugin { bw.close(); } + void registerPlayerIfNeeded(Player p) { + // Players are stored by their UUID, so that name changes don't break player's + // settings + UUID uniqueId = p.getUniqueId(); + + // Add player to map only if they aren't registered already + if (!perPlayerSettings.containsKey(uniqueId.toString())) { + + // Player settings are stored in a file named after the player's UUID + File playerFile = new File(getDataFolder() + File.separator + "playerdata", + p.getUniqueId().toString() + ".yml"); + YamlConfiguration playerConfig = YamlConfiguration.loadConfiguration(playerFile); + + playerConfig.addDefault("invSortingEnabled", getConfig().getBoolean("inv-sorting-enabled-by-default")); + playerConfig.addDefault("middleClick", getConfig().getBoolean("hotkeys.middle-click")); + playerConfig.addDefault("shiftClick", getConfig().getBoolean("hotkeys.shift-click")); + playerConfig.addDefault("doubleClick", getConfig().getBoolean("hotkeys.double-click")); + playerConfig.addDefault("shiftRightClick", getConfig().getBoolean("hotkeys.shift-right-click")); + + boolean activeForThisPlayer = false; + boolean invActiveForThisPlayer = false; + boolean middleClick, shiftClick, doubleClick, shiftRightClick; + boolean changed = false; + + if (!playerFile.exists()) { + // If the player settings file does not exist for this player, set it to the + // default value + activeForThisPlayer = getConfig().getBoolean("sorting-enabled-by-default"); + invActiveForThisPlayer = getConfig().getBoolean("inv-sorting-enabled-by-default"); + middleClick = getConfig().getBoolean("hotkeys.middle-click"); + shiftClick = getConfig().getBoolean("hotkeys.shift-click"); + doubleClick = getConfig().getBoolean("hotkeys.double-click"); + shiftRightClick = getConfig().getBoolean("hotkeys.shift-right-click"); + + if(debug) { + getLogger().info("Player "+p.getName()+" does not have player settings yet, using default values."); + } + + // Because this is new a file, we have to save it on shutdown/disconnect + changed=true; + } else { + // If the file exists, check if the player has sorting enabled + activeForThisPlayer = playerConfig.getBoolean("sortingEnabled"); + invActiveForThisPlayer = playerConfig.getBoolean("invSortingEnabled"); + middleClick = playerConfig.getBoolean("middleClick"); + shiftClick = playerConfig.getBoolean("shiftClick"); + doubleClick = playerConfig.getBoolean("doubleClick"); + shiftRightClick = playerConfig.getBoolean("shiftRightClick"); + } + + JeffChestSortPlayerSetting newSettings = new JeffChestSortPlayerSetting(activeForThisPlayer,invActiveForThisPlayer,middleClick,shiftClick,doubleClick,shiftRightClick,changed); + + // when "show-message-again-after-logout" is enabled, we don't care if the + // player already saw the message + if (!getConfig().getBoolean("show-message-again-after-logout")) { + newSettings.hasSeenMessage = playerConfig.getBoolean("hasSeenMessage"); + } + + // Finally add the PlayerSetting object to the map + perPlayerSettings.put(uniqueId.toString(), newSettings); + + } + } + } diff --git a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortSettingsGUI.java b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortSettingsGUI.java index 487eeb7..6ee61d9 100644 --- a/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortSettingsGUI.java +++ b/src/main/java/de/jeffclan/JeffChestSort/JeffChestSortSettingsGUI.java @@ -4,12 +4,16 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -public class JeffChestSortSettingsGUI { +public class JeffChestSortSettingsGUI implements Listener { JeffChestSortPlugin plugin; @@ -32,17 +36,6 @@ public class JeffChestSortSettingsGUI { ItemStack getItem(boolean active, Hotkey hotkey) { ItemStack is = null; String suffix; - //Material green = Material.getMaterial("GREEN_WOOL"); - //Material red = Material.getMaterial("RED_WOOL"); - //Material green = Material.GREEN_WOOL; - //Material red = Material.RED_WOOL; - -// if(green==null || red==null) { -// //plugin.getLogger().warning("Using unsupported Minecraft version"); -// green = Material.EMERALD_BLOCK; -// red = Material.REDSTONE_BLOCK; -// //return null; -// } if(active) { is = new ItemStack(green); @@ -80,13 +73,7 @@ public class JeffChestSortSettingsGUI { void openGUI(Player player) { Inventory inventory = createGUI("ChestSort", player); - JeffChestSortPlayerSetting setting = plugin.PerPlayerSettings.get(player.getUniqueId().toString()); - - // Test if running 1.13 or later -// if(Material.getMaterial("GREEN_WOOL") == null) { -// player.sendMessage(plugin.messages.MSG_ERR_HOTKEYSDISABLED); -// return; -// } + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(player.getUniqueId().toString()); inventory.setItem(slotMiddleClick, getItem(setting.middleClick,Hotkey.MiddleClick)); inventory.setItem(slotShiftClick, getItem(setting.shiftClick,Hotkey.ShiftClick)); @@ -101,4 +88,54 @@ public class JeffChestSortSettingsGUI { Inventory inventory = Bukkit.createInventory(inventoryHolder, InventoryType.CHEST, name); return inventory; } + + @EventHandler + void onGUIInteract(InventoryClickEvent event) { + if(plugin.hotkeyGUI==false) { + return; + } + if(!(event.getWhoClicked() instanceof Player)) { + return; + } + Player p = (Player) event.getWhoClicked(); + plugin.listener.plugin.registerPlayerIfNeeded(p); + JeffChestSortPlayerSetting setting = plugin.perPlayerSettings.get(p.getUniqueId().toString()); + + if(setting.guiInventory==null) { + return; + } + + if(event.getClickedInventory()==null) { + return; + } + if(!event.getClickedInventory().equals(setting.guiInventory)) { + return; + } + + // We only get this far if the player has clicked inside his GUI inventory + event.setCancelled(true); + if(event.getClick() != ClickType.LEFT) { + return; + } + + if(event.getSlot() == JeffChestSortSettingsGUI.slotMiddleClick) { + setting.toggleMiddleClick(); + plugin.settingsGUI.openGUI(p); + return; + } + else if(event.getSlot() == JeffChestSortSettingsGUI.slotShiftClick) { + setting.toggleShiftClick(); + plugin.settingsGUI.openGUI(p); + return; + } else if(event.getSlot() == JeffChestSortSettingsGUI.slotDoubleClick) { + setting.toggleDoubleClick(); + plugin.settingsGUI.openGUI(p); + return; + } else if(event.getSlot() == JeffChestSortSettingsGUI.slotShiftRightClick) { + setting.toggleShiftRightClick(); + plugin.settingsGUI.openGUI(p); + return; + } + + } } diff --git a/src/main/java/de/jeffclan/JeffChestSort/MetricsLite.java b/src/main/java/de/jeffclan/JeffChestSort/MetricsLite.java deleted file mode 100644 index f4c47a0..0000000 --- a/src/main/java/de/jeffclan/JeffChestSort/MetricsLite.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Copyright 2011-2013 Tyler Blair. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and contributors and should not be interpreted as representing official policies, - * either expressed or implied, of anybody else. - */ - -package de.jeffclan.JeffChestSort; - -import org.bukkit.Bukkit; -import org.bukkit.Server; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.scheduler.BukkitTask; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Method; -import java.net.Proxy; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.util.Collection; -import java.util.UUID; -import java.util.logging.Level; -import java.util.zip.GZIPOutputStream; - -public class MetricsLite { - - /** - * The current revision number - */ - private final static int REVISION = 7; - - /** - * The base url of the metrics domain - */ - private static final String BASE_URL = "http://report.mcstats.org"; - - /** - * The url used to report a server's status - */ - private static final String REPORT_URL = "/plugin/%s"; - - /** - * Interval of time to ping (in minutes) - */ - private final static int PING_INTERVAL = 15; - - /** - * The plugin this metrics submits for - */ - private final Plugin plugin; - - /** - * The plugin configuration file - */ - private final YamlConfiguration configuration; - - /** - * The plugin configuration file - */ - private final File configurationFile; - - /** - * Unique server id - */ - private final String guid; - - /** - * Debug mode - */ - private final boolean debug; - - /** - * Lock for synchronization - */ - private final Object optOutLock = new Object(); - - /** - * Id of the scheduled task - */ - private volatile BukkitTask task = null; - - public MetricsLite(Plugin plugin) throws IOException { - if (plugin == null) { - throw new IllegalArgumentException("Plugin cannot be null"); - } - - this.plugin = plugin; - - // load the config - configurationFile = getConfigFile(); - configuration = YamlConfiguration.loadConfiguration(configurationFile); - - // add some defaults - configuration.addDefault("opt-out", false); - configuration.addDefault("guid", UUID.randomUUID().toString()); - configuration.addDefault("debug", false); - - // Do we need to create the file? - if (configuration.get("guid", null) == null) { - configuration.options().header("http://mcstats.org").copyDefaults(true); - configuration.save(configurationFile); - } - - // Load the guid then - guid = configuration.getString("guid"); - debug = configuration.getBoolean("debug", false); - } - - /** - * Start measuring statistics. This will immediately create an async repeating task as the plugin and send - * the initial data to the metrics backend, and then after that it will post in increments of - * PING_INTERVAL * 1200 ticks. - * - * @return True if statistics measuring is running, otherwise false. - */ - public boolean start() { - synchronized (optOutLock) { - // Did we opt out? - if (isOptOut()) { - return false; - } - - // Is metrics already running? - if (task != null) { - return true; - } - - // Begin hitting the server with glorious data - task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() { - - private boolean firstPost = true; - - public void run() { - try { - // This has to be synchronized or it can collide with the disable method. - synchronized (optOutLock) { - // Disable Task, if it is running and the server owner decided to opt-out - if (isOptOut() && task != null) { - task.cancel(); - task = null; - } - } - - // We use the inverse of firstPost because if it is the first time we are posting, - // it is not a interval ping, so it evaluates to FALSE - // Each time thereafter it will evaluate to TRUE, i.e PING! - postPlugin(!firstPost); - - // After the first post we set firstPost to false - // Each post thereafter will be a ping - firstPost = false; - } catch (IOException e) { - if (debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage()); - } - } - } - }, 0, PING_INTERVAL * 1200); - - return true; - } - } - - /** - * Has the server owner denied plugin metrics? - * - * @return true if metrics should be opted out of it - */ - public boolean isOptOut() { - synchronized (optOutLock) { - try { - // Reload the metrics file - configuration.load(getConfigFile()); - } catch (IOException ex) { - if (debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); - } - return true; - } catch (InvalidConfigurationException ex) { - if (debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); - } - return true; - } - return configuration.getBoolean("opt-out", false); - } - } - - /** - * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task. - * - * @throws java.io.IOException - */ - public void enable() throws IOException { - // This has to be synchronized or it can collide with the check in the task. - synchronized (optOutLock) { - // Check if the server owner has already set opt-out, if not, set it. - if (isOptOut()) { - configuration.set("opt-out", false); - configuration.save(configurationFile); - } - - // Enable Task, if it is not running - if (task == null) { - start(); - } - } - } - - /** - * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task. - * - * @throws java.io.IOException - */ - public void disable() throws IOException { - // This has to be synchronized or it can collide with the check in the task. - synchronized (optOutLock) { - // Check if the server owner has already set opt-out, if not, set it. - if (!isOptOut()) { - configuration.set("opt-out", true); - configuration.save(configurationFile); - } - - // Disable Task, if it is running - if (task != null) { - task.cancel(); - task = null; - } - } - } - - /** - * Gets the File object of the config file that should be used to store data such as the GUID and opt-out status - * - * @return the File object for the config file - */ - public File getConfigFile() { - // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use - // is to abuse the plugin object we already have - // plugin.getDataFolder() => base/plugins/PluginA/ - // pluginsFolder => base/plugins/ - // The base is not necessarily relative to the startup directory. - File pluginsFolder = plugin.getDataFolder().getParentFile(); - - // return => base/plugins/PluginMetrics/config.yml - return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml"); - } - - /** - * Gets the online player (backwards compatibility) - * - * @return online player amount - */ - private int getOnlinePlayers() { - try { - Method onlinePlayerMethod = Server.class.getMethod("getOnlinePlayers"); - if(onlinePlayerMethod.getReturnType().equals(Collection.class)) { - return ((Collection)onlinePlayerMethod.invoke(Bukkit.getServer())).size(); - } else { - return ((Player[])onlinePlayerMethod.invoke(Bukkit.getServer())).length; - } - } catch (Exception ex) { - if (debug) { - Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); - } - } - - return 0; - } - - /** - * Generic method that posts a plugin to the metrics website - */ - private void postPlugin(boolean isPing) throws IOException { - // Server software specific section - PluginDescriptionFile description = plugin.getDescription(); - String pluginName = description.getName(); - boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled - String pluginVersion = description.getVersion(); - String serverVersion = Bukkit.getVersion(); - int playersOnline = this.getOnlinePlayers(); - - // END server software specific section -- all code below does not use any code outside of this class / Java - - // Construct the post data - StringBuilder json = new StringBuilder(1024); - json.append('{'); - - // The plugin's description file containg all of the plugin data such as name, version, author, etc - appendJSONPair(json, "guid", guid); - appendJSONPair(json, "plugin_version", pluginVersion); - appendJSONPair(json, "server_version", serverVersion); - appendJSONPair(json, "players_online", Integer.toString(playersOnline)); - - // New data as of R6 - String osname = System.getProperty("os.name"); - String osarch = System.getProperty("os.arch"); - String osversion = System.getProperty("os.version"); - String java_version = System.getProperty("java.version"); - int coreCount = Runtime.getRuntime().availableProcessors(); - - // normalize os arch .. amd64 -> x86_64 - if (osarch.equals("amd64")) { - osarch = "x86_64"; - } - - appendJSONPair(json, "osname", osname); - appendJSONPair(json, "osarch", osarch); - appendJSONPair(json, "osversion", osversion); - appendJSONPair(json, "cores", Integer.toString(coreCount)); - appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0"); - appendJSONPair(json, "java_version", java_version); - - // If we're pinging, append it - if (isPing) { - appendJSONPair(json, "ping", "1"); - } - - // close json - json.append('}'); - - // Create the url - URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName))); - - // Connect to the website - URLConnection connection; - - // Mineshafter creates a socks proxy, so we can safely bypass it - // It does not reroute POST requests so we need to go around it - if (isMineshafterPresent()) { - connection = url.openConnection(Proxy.NO_PROXY); - } else { - connection = url.openConnection(); - } - - - byte[] uncompressed = json.toString().getBytes(); - byte[] compressed = gzip(json.toString()); - - // Headers - connection.addRequestProperty("User-Agent", "MCStats/" + REVISION); - connection.addRequestProperty("Content-Type", "application/json"); - connection.addRequestProperty("Content-Encoding", "gzip"); - connection.addRequestProperty("Content-Length", Integer.toString(compressed.length)); - connection.addRequestProperty("Accept", "application/json"); - connection.addRequestProperty("Connection", "close"); - - connection.setDoOutput(true); - - if (debug) { - System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length); - } - - // Write the data - OutputStream os = connection.getOutputStream(); - os.write(compressed); - os.flush(); - - // Now read the response - final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String response = reader.readLine(); - - // close resources - os.close(); - reader.close(); - - if (response == null || response.startsWith("ERR") || response.startsWith("7")) { - if (response == null) { - response = "null"; - } else if (response.startsWith("7")) { - response = response.substring(response.startsWith("7,") ? 2 : 1); - } - - throw new IOException(response); - } - } - - /** - * GZip compress a string of bytes - * - * @param input - * @return - */ - public static byte[] gzip(String input) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - GZIPOutputStream gzos = null; - - try { - gzos = new GZIPOutputStream(baos); - gzos.write(input.getBytes("UTF-8")); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (gzos != null) try { - gzos.close(); - } catch (IOException ignore) { - } - } - - return baos.toByteArray(); - } - - /** - * Check if mineshafter is present. If it is, we need to bypass it to send POST requests - * - * @return true if mineshafter is installed on the server - */ - private boolean isMineshafterPresent() { - try { - Class.forName("mineshafter.MineServer"); - return true; - } catch (Exception e) { - return false; - } - } - - /** - * Appends a json encoded key/value pair to the given string builder. - * - * @param json - * @param key - * @param value - * @throws UnsupportedEncodingException - */ - private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException { - boolean isValueNumeric = false; - - try { - if (value.equals("0") || !value.endsWith("0")) { - Double.parseDouble(value); - isValueNumeric = true; - } - } catch (NumberFormatException e) { - isValueNumeric = false; - } - - if (json.charAt(json.length() - 1) != '{') { - json.append(','); - } - - json.append(escapeJSON(key)); - json.append(':'); - - if (isValueNumeric) { - json.append(value); - } else { - json.append(escapeJSON(value)); - } - } - - /** - * Escape a string to create a valid JSON string - * - * @param text - * @return - */ - private static String escapeJSON(String text) { - StringBuilder builder = new StringBuilder(); - - builder.append('"'); - for (int index = 0; index < text.length(); index++) { - char chr = text.charAt(index); - - switch (chr) { - case '"': - case '\\': - builder.append('\\'); - builder.append(chr); - break; - case '\b': - builder.append("\\b"); - break; - case '\t': - builder.append("\\t"); - break; - case '\n': - builder.append("\\n"); - break; - case '\r': - builder.append("\\r"); - break; - default: - if (chr < ' ') { - String t = "000" + Integer.toHexString(chr); - builder.append("\\u" + t.substring(t.length() - 4)); - } else { - builder.append(chr); - } - break; - } - } - builder.append('"'); - - return builder.toString(); - } - - /** - * Encode text as UTF-8 - * - * @param text the text to encode - * @return the encoded text, as UTF-8 - */ - private static String urlEncode(final String text) throws UnsupportedEncodingException { - return URLEncoder.encode(text, "UTF-8"); - } - -} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ddb41ae..b23a43b 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ main: de.jeffclan.JeffChestSort.JeffChestSortPlugin name: ChestSort -version: 7.6.1 +version: 7.7-pre1 api-version: 1.13 description: Allows automatic chest sorting author: mfnalex @@ -12,16 +12,22 @@ softdepend: [CrackShot, InventoryPages] commands: chestsort: description: Toggle automatic chest sorting. - usage: / + usage: / [on|off|toggle] aliases: sort permission: chestsort.use invsort: - description: Sorts the player's inventory. When no option is specified, only the regular inventory (excluding the hotbar) is sorted. - usage: / [inv|hotbar|all] + description: Toggle automatic inventory sorting or sorts the player's inventory. When no option is specified, only the regular inventory (excluding the hotbar) is sorted. + usage: / [on|off|toggle|inv|hotbar|all] aliases: [isort,inventorysort] permission: chestsort.use.inventory + refill: + description: Allows auto-refilling items in the hotbar + usage: / [on|off|toggle] + permission: chestsort.use.refill permissions: chestsort.use: description: Allows chest sorting chestsort.use.inventory: description: Allows inventory sorting + chestsort.use.refill: + description: Allows auto-refilling the hotbar \ No newline at end of file