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