From c700ccbe7044fc2448dc096d34d3d43f778b9178 Mon Sep 17 00:00:00 2001
From: mfnalex <1122571+mfnalex@users.noreply.github.com>
Date: Sat, 9 Oct 2021 19:46:07 +0200
Subject: [PATCH] 12.0.0
---
CHANGELOG.md | 13 +-
pom.xml | 2 +-
.../jeff_media/chestsort/ChestSortPlugin.java | 110 +++++--
.../chestsort/commands/ChestSortCommand.java | 43 ++-
.../chestsort/commands/TabCompleter.java | 9 +-
.../de/jeff_media/chestsort/enums/Hotkey.java | 70 +++++
.../chestsort/gui/ChestSortGUIHolder.java | 20 ++
.../jeff_media/chestsort/gui/GUIListener.java | 49 +++
.../de/jeff_media/chestsort/gui/NewUI.java | 73 +++++
.../chestsort/listeners/Listener.java | 9 +-
src/main/resources/config.yml | 15 +-
src/main/resources/gui.yml | 292 ++++++++++++++++++
src/main/resources/plugin.yml | 12 +-
src/main/resources/settings.fingerprint | 1 +
14 files changed, 669 insertions(+), 49 deletions(-)
create mode 100644 src/main/java/de/jeff_media/chestsort/gui/ChestSortGUIHolder.java
create mode 100644 src/main/java/de/jeff_media/chestsort/gui/GUIListener.java
create mode 100644 src/main/java/de/jeff_media/chestsort/gui/NewUI.java
create mode 100644 src/main/resources/gui.yml
create mode 100644 src/main/resources/settings.fingerprint
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b9f6359..a569958 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,17 @@
# Changelog
-## 1.5.5
+## 12.0.0
+- GUI is now 100% customizable!
+ - Supports Custom Model Data to create vanilla-looking GUIs
+ - Change names, items, slots, lore, and basically EVERYTHING
+ - Also supports changing automatic sorting and automatic inventory sorting
+- You can now reset the settings for all players using /sort resetplayerdata
+ - This is useful when you had some hotkeys enabled by default and changed it now, without having all players individually change their settings
+
+## 11.5.6
+- Added option to disable "use-advanced-protection-plugin-detection" as it causes some troubles when other plugins blindly cast a Player object to CraftPlayer, without prior checking whether it's an instanceof CraftPlayer
+
+## 11.5.5
- Fixed furnaces being sortable using the left-click hotkey
## 11.5.4
diff --git a/pom.xml b/pom.xml
index 490395a..d11b643 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
ChestSort
https://www.chestsort.de
Allows automatic chest sorting!
- 11.5.5
+ 12.0.0
jar
diff --git a/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java b/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java
index c36cc41..7367a1d 100644
--- a/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java
+++ b/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java
@@ -37,6 +37,8 @@ import de.jeff_media.chestsort.config.ConfigUpdater;
import de.jeff_media.chestsort.config.Messages;
import de.jeff_media.chestsort.data.Category;
import de.jeff_media.chestsort.data.PlayerSetting;
+import de.jeff_media.chestsort.gui.ChestSortGUIHolder;
+import de.jeff_media.chestsort.gui.GUIListener;
import de.jeff_media.chestsort.gui.SettingsGUI;
import de.jeff_media.chestsort.handlers.ChestSortOrganizer;
import de.jeff_media.chestsort.handlers.ChestSortPermissionsHandler;
@@ -56,11 +58,13 @@ import io.papermc.lib.PaperLib;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
+import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.util.*;
@@ -95,11 +99,15 @@ public class ChestSortPlugin extends JavaPlugin {
private UpdateChecker updateChecker;
private boolean usingMatchingConfig = true;
private boolean verbose = true;
+ private YamlConfiguration guiConfig = new YamlConfiguration();
+ private int settingsFingerprint = 0;
public static ChestSortPlugin getInstance() {
return instance;
}
+ public YamlConfiguration getGuiConfig() { return guiConfig; }
+
public static double getUpdateCheckInterval() {
return updateCheckInterval;
}
@@ -125,6 +133,7 @@ public class ChestSortPlugin extends JavaPlugin {
// This saves the config.yml included in the .jar file, but it will not
// overwrite an existing config.yml
this.saveDefaultConfig();
+ createGUIConfig();
reloadConfig();
// Load disabled-worlds. If it does not exist in the config, it returns null.
@@ -139,6 +148,14 @@ public class ChestSortPlugin extends JavaPlugin {
}
+ private void createGUIConfig() {
+ File guiFile = new File(getDataFolder(), "gui.yml");
+ if(!guiFile.exists()) {
+ saveResource("gui.yml",false);
+ }
+ guiConfig = YamlConfiguration.loadConfiguration(guiFile);
+ }
+
private void createDirectories() {
// Create a playerdata folder that contains all the perPlayerSettings as .yml
File playerDataFolder = new File(getDataFolder().getPath() + File.separator + "playerdata");
@@ -411,6 +428,13 @@ public class ChestSortPlugin extends JavaPlugin {
public void load(boolean reload) {
+ settingsFingerprint = 0;
+ File fingerprintFile = new File(getDataFolder(), "settings.fingerprint");
+ if(fingerprintFile.exists()) {
+ YamlConfiguration yaml = YamlConfiguration.loadConfiguration(fingerprintFile);
+ settingsFingerprint = yaml.getInt("v",0);
+ }
+
if (reload) {
unregisterAllPlayers();
reloadConfig();
@@ -477,6 +501,7 @@ public class ChestSortPlugin extends JavaPlugin {
setEnderContainersHook(new EnderContainersHook(this));
getServer().getPluginManager().registerEvents(getListener(), this);
getServer().getPluginManager().registerEvents(getSettingsGUI(), this);
+ getServer().getPluginManager().registerEvents(new GUIListener(), this);
ChestSortCommand chestsortCommandExecutor = new ChestSortCommand(this);
TabCompleter tabCompleter = new TabCompleter();
this.getCommand("sort").setExecutor(chestsortCommandExecutor);
@@ -484,7 +509,7 @@ public class ChestSortPlugin extends JavaPlugin {
InvSortCommand invsortCommandExecutor = new InvSortCommand(this);
this.getCommand("invsort").setExecutor(invsortCommandExecutor);
this.getCommand("invsort").setTabCompleter(tabCompleter);
- this.getCommand("chestsortadmin").setExecutor(new AdminCommand(this));
+ //this.getCommand("chestsortadmin").setExecutor(new AdminCommand(this));
if (isVerbose()) {
getLogger().info("Use permissions: " + getConfig().getBoolean("use-permissions"));
@@ -546,9 +571,12 @@ public class ChestSortPlugin extends JavaPlugin {
@Override
public void onDisable() {
// We have to unregister every player to save their perPlayerSettings
- for (Player p : getServer().getOnlinePlayers()) {
- unregisterPlayer(p);
- getPermissionsHandler().removePermissions(p);
+ for (Player player : getServer().getOnlinePlayers()) {
+ if(player.getOpenInventory().getTopInventory().getHolder() instanceof ChestSortGUIHolder) {
+ player.closeInventory();
+ }
+ unregisterPlayer(player);
+ getPermissionsHandler().removePermissions(player);
}
}
@@ -624,6 +652,18 @@ public class ChestSortPlugin extends JavaPlugin {
}
+ public void incrementFingerprint() {
+ YamlConfiguration yaml = new YamlConfiguration();
+ yaml.set("v",settingsFingerprint + 1);
+ settingsFingerprint++;
+ try {
+ yaml.save(new File(getDataFolder(),"settings.fingerprint"));
+ load(true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
public void registerPlayerIfNeeded(Player p) {
// Players are stored by their UUID, so that name changes don't break player's
// settings
@@ -685,16 +725,19 @@ public class ChestSortPlugin extends JavaPlugin {
} else {
// If the file exists, check if the player has sorting enabled
// NBT Values
- activeForThisPlayer = Boolean.parseBoolean(NBTAPI.getNBT(p, "sortingEnabled", String.valueOf(playerConfig.getBoolean("sortingEnabled"))));
- invActiveForThisPlayer = Boolean.parseBoolean(NBTAPI.getNBT(p, "invSortingEnabled", String.valueOf(playerConfig.getBoolean("invSortingEnabled", getConfig().getBoolean("inv-sorting-enabled-by-default")))));
- middleClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "middleClick", String.valueOf(playerConfig.getBoolean("middleClick"))));
- shiftClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "shiftClick", String.valueOf(playerConfig.getBoolean("shiftClick"))));
- doubleClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "doubleClick", String.valueOf(playerConfig.getBoolean("doubleClick"))));
- shiftRightClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "shiftRightClick", String.valueOf(playerConfig.getBoolean("shiftRightClick"))));
- leftClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "leftClick", String.valueOf(playerConfig.getBoolean("leftClick", getConfig().getBoolean("additional-hotkeys.left-click")))));
- rightClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "rightClick", String.valueOf(playerConfig.getBoolean("rightClick", getConfig().getBoolean("additional-hotkeys.right-click")))));
- leftClickFromOutside = Boolean.parseBoolean(NBTAPI.getNBT(p, "leftClickOutside", String.valueOf(playerConfig.getBoolean("leftClickOutside", getConfig().getBoolean("left-click-to-sort-enabled-by-default")))));
- hasSeenMessage = Boolean.parseBoolean(NBTAPI.getNBT(p, "hasSeenMessage", String.valueOf("false")));
+
+ String fingerprint = getFingerprint();
+
+ activeForThisPlayer = Boolean.parseBoolean(NBTAPI.getNBT(p, "sortingEnabled" + fingerprint, String.valueOf(playerConfig.getBoolean("sortingEnabled"))));
+ invActiveForThisPlayer = Boolean.parseBoolean(NBTAPI.getNBT(p, "invSortingEnabled" + fingerprint, String.valueOf(playerConfig.getBoolean("invSortingEnabled", getConfig().getBoolean("inv-sorting-enabled-by-default")))));
+ middleClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "middleClick" + fingerprint, String.valueOf(playerConfig.getBoolean("middleClick"))));
+ shiftClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "shiftClick" + fingerprint, String.valueOf(playerConfig.getBoolean("shiftClick"))));
+ doubleClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "doubleClick" + fingerprint, String.valueOf(playerConfig.getBoolean("doubleClick"))));
+ shiftRightClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "shiftRightClick" + fingerprint, String.valueOf(playerConfig.getBoolean("shiftRightClick"))));
+ leftClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "leftClick" + fingerprint, String.valueOf(playerConfig.getBoolean("leftClick", getConfig().getBoolean("additional-hotkeys.left-click")))));
+ rightClick = Boolean.parseBoolean(NBTAPI.getNBT(p, "rightClick" + fingerprint, String.valueOf(playerConfig.getBoolean("rightClick", getConfig().getBoolean("additional-hotkeys.right-click")))));
+ leftClickFromOutside = Boolean.parseBoolean(NBTAPI.getNBT(p, "leftClickOutside" + fingerprint, String.valueOf(playerConfig.getBoolean("leftClickOutside", getConfig().getBoolean("left-click-to-sort-enabled-by-default")))));
+ hasSeenMessage = Boolean.parseBoolean(NBTAPI.getNBT(p, "hasSeenMessage" + fingerprint, String.valueOf("false")));
//System.out.println("Loading playersetting from NBT");
if(getConfig().getBoolean("show-message-again-after-logout")) {
//System.out.println("show-message-again-after-logout is true, sooo...");
@@ -722,6 +765,14 @@ public class ChestSortPlugin extends JavaPlugin {
}
}
+ private String getFingerprint() {
+ String fingerprint = "";
+ if(settingsFingerprint > 0) {
+ fingerprint = "-" + settingsFingerprint;
+ }
+ return fingerprint;
+ }
+
// Saves default category files, when enabled in the config
private void saveDefaultCategories() {
@@ -837,6 +888,8 @@ public class ChestSortPlugin extends JavaPlugin {
getConfig().addDefault("hook-generic", true);
getConfig().addDefault("prevent-sorting-null-inventories", false);
+ getConfig().addDefault("mute-protection-plugins", false);
+
getConfig().addDefault("verbose", true); // Prints some information in onEnable()
}
@@ -874,16 +927,25 @@ public class ChestSortPlugin extends JavaPlugin {
PlayerSetting setting = getPerPlayerSettings().get(p.getUniqueId().toString());
if (McVersion.isAtLeast(1,14,4)) {
- NBTAPI.addNBT(p, "sortingEnabled", String.valueOf(setting.sortingEnabled));
- NBTAPI.addNBT(p, "invSortingEnabled", String.valueOf(setting.invSortingEnabled));
- NBTAPI.addNBT(p, "hasSeenMessage", String.valueOf(setting.hasSeenMessage));
- NBTAPI.addNBT(p, "middleClick", String.valueOf(setting.middleClick));
- NBTAPI.addNBT(p, "shiftClick", String.valueOf(setting.shiftClick));
- NBTAPI.addNBT(p, "doubleClick", String.valueOf(setting.doubleClick));
- NBTAPI.addNBT(p, "shiftRightClick", String.valueOf(setting.shiftRightClick));
- NBTAPI.addNBT(p, "leftClick", String.valueOf(setting.leftClick));
- NBTAPI.addNBT(p, "rightClick", String.valueOf(setting.rightClick));
- NBTAPI.addNBT(p, "leftClickOutside", String.valueOf(setting.leftClickOutside));
+
+ for(NamespacedKey key : p.getPersistentDataContainer().getKeys()) {
+ if(key.getKey().equals(new NamespacedKey(this,"test").getKey())) {
+ p.getPersistentDataContainer().remove(key);
+ }
+ }
+
+ String fingerprint = getFingerprint();
+
+ NBTAPI.addNBT(p, "sortingEnabled" + fingerprint, String.valueOf(setting.sortingEnabled));
+ NBTAPI.addNBT(p, "invSortingEnabled" + fingerprint, String.valueOf(setting.invSortingEnabled));
+ NBTAPI.addNBT(p, "hasSeenMessage" + fingerprint, String.valueOf(setting.hasSeenMessage));
+ NBTAPI.addNBT(p, "middleClick" + fingerprint, String.valueOf(setting.middleClick));
+ NBTAPI.addNBT(p, "shiftClick" + fingerprint, String.valueOf(setting.shiftClick));
+ NBTAPI.addNBT(p, "doubleClick" + fingerprint, String.valueOf(setting.doubleClick));
+ NBTAPI.addNBT(p, "shiftRightClick" + fingerprint, String.valueOf(setting.shiftRightClick));
+ NBTAPI.addNBT(p, "leftClick" + fingerprint, String.valueOf(setting.leftClick));
+ NBTAPI.addNBT(p, "rightClick" + fingerprint, String.valueOf(setting.rightClick));
+ NBTAPI.addNBT(p, "leftClickOutside" + fingerprint, String.valueOf(setting.leftClickOutside));
} else {
File playerFile = new File(getDataFolder() + File.separator + "playerdata", p.getUniqueId() + ".yml");
diff --git a/src/main/java/de/jeff_media/chestsort/commands/ChestSortCommand.java b/src/main/java/de/jeff_media/chestsort/commands/ChestSortCommand.java
index cef3fb1..a2b9647 100644
--- a/src/main/java/de/jeff_media/chestsort/commands/ChestSortCommand.java
+++ b/src/main/java/de/jeff_media/chestsort/commands/ChestSortCommand.java
@@ -3,8 +3,10 @@ package de.jeff_media.chestsort.commands;
import de.jeff_media.chestsort.ChestSortPlugin;
import de.jeff_media.chestsort.config.Messages;
import de.jeff_media.chestsort.data.PlayerSetting;
+import de.jeff_media.chestsort.gui.NewUI;
import de.jeff_media.chestsort.handlers.Debugger;
import net.md_5.bungee.api.ChatColor;
+import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -40,6 +42,17 @@ public class ChestSortCommand implements CommandExecutor {
return true;
}
+ //System.out.println(1);
+ if(sender.hasPermission("chestsort.resetplayersettings") && args.length > 0 && args[0].equalsIgnoreCase("resetplayersettings")) {
+ for(Player online : Bukkit.getOnlinePlayers()) {
+ plugin.unregisterPlayer(online);
+ }
+ plugin.incrementFingerprint();
+ sender.sendMessage("§cAll player settings have been reset!");
+ return true;
+ }
+ //System.out.println(2);
+
// Reload command
if (args.length > 0 && args[0].equalsIgnoreCase("reload")) {
if (!sender.hasPermission("chestsort.reload")) {
@@ -92,8 +105,13 @@ public class ChestSortCommand implements CommandExecutor {
if(!p.hasPermission("chestsort.automatic")) args = new String[]{"hotkeys"};
+ if(args.length > 0 && (args[0].equalsIgnoreCase("hotkeys") || args[0].equalsIgnoreCase("hotkey"))) {
+ new NewUI(p).showGUI();
+ return true;
+ }
+
// Settings GUI
- if (args.length > 0) {
+ /*if (args.length > 0) {
if (args[0].equalsIgnoreCase("hotkey") || args[0].equalsIgnoreCase("hotkeys")) {
if (!plugin.isHotkeyGUI()) {
@@ -106,7 +124,7 @@ public class ChestSortCommand implements CommandExecutor {
return true;
}
- }
+ }*/
// Settings GUI End
PlayerSetting setting = plugin.getPerPlayerSettings().get(p.getUniqueId().toString());
@@ -115,20 +133,25 @@ public class ChestSortCommand implements CommandExecutor {
p.sendMessage(String.format(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();
+
+ if(args.length > 0) {
+ if (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) {
+ /*if (setting.sortingEnabled) {
p.sendMessage(Messages.MSG_ACTIVATED);
} else {
p.sendMessage(Messages.MSG_DEACTIVATED);
- }
+ }*/
+
+ new NewUI(p).showGUI();
return true;
}
diff --git a/src/main/java/de/jeff_media/chestsort/commands/TabCompleter.java b/src/main/java/de/jeff_media/chestsort/commands/TabCompleter.java
index 3923345..52bbc2b 100644
--- a/src/main/java/de/jeff_media/chestsort/commands/TabCompleter.java
+++ b/src/main/java/de/jeff_media/chestsort/commands/TabCompleter.java
@@ -37,7 +37,14 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
entered = args[args.length-1];
}
if(command.getName().equalsIgnoreCase("sort")) {
- return getMatchingOptions(entered,chestsortOptions);
+ List list = getMatchingOptions(entered,chestsortOptions);
+ if(sender.hasPermission("chestsort.reload")) {
+ list.add("reload");
+ }
+ if(sender.isOp()) {
+ list.add("resetplayersettings");
+ }
+ return list;
}
if(command.getName().equalsIgnoreCase("invsort")) {
return getMatchingOptions(entered,invsortOptions);
diff --git a/src/main/java/de/jeff_media/chestsort/enums/Hotkey.java b/src/main/java/de/jeff_media/chestsort/enums/Hotkey.java
index 68d7401..cabb3b9 100644
--- a/src/main/java/de/jeff_media/chestsort/enums/Hotkey.java
+++ b/src/main/java/de/jeff_media/chestsort/enums/Hotkey.java
@@ -1,16 +1,86 @@
package de.jeff_media.chestsort.enums;
+import de.jeff_media.chestsort.ChestSortPlugin;
+import de.jeff_media.chestsort.data.PlayerSetting;
+import org.bukkit.entity.Player;
+
import java.util.Locale;
public enum Hotkey {
+ AUTO_SORT, AUTO_INV_SORT,
SHIFT_CLICK,
MIDDLE_CLICK, DOUBLE_CLICK, SHIFT_RIGHT_CLICK,
OUTSIDE, LEFT_CLICK, RIGHT_CLICK;
+ private static final ChestSortPlugin main = ChestSortPlugin.getInstance();
+
+ public boolean hasPermission(Player player) {
+ if(!player.hasPermission(getPermission(this))) return false;
+ switch(this) {
+ case AUTO_SORT:
+ return main.getConfig().getBoolean("allow-automatic-sorting");
+ case AUTO_INV_SORT:
+ return main.getConfig().getBoolean("allow-automatic-inventory-sorting");
+ case SHIFT_CLICK:
+ case MIDDLE_CLICK:
+ case DOUBLE_CLICK:
+ case SHIFT_RIGHT_CLICK:
+ return main.getConfig().getBoolean("allow-sorting-hotkeys");
+ case LEFT_CLICK:
+ case RIGHT_CLICK:
+ return main.getConfig().getBoolean("allow-additional-hotkeys");
+ case OUTSIDE:
+ return main.getConfig().getBoolean("allow-left-click-to-sort");
+ default:
+ throw new IllegalArgumentException("Invalid hotkey: " + this.name());
+ }
+ }
+
public static String getPermission(Hotkey hotkey) {
+
+ if(hotkey == AUTO_SORT) {
+ return "chestsort.use";
+ }
+
+ if(hotkey == AUTO_INV_SORT) {
+ return "chestsort.use.inventory";
+ }
+
String permission = "chestsort.hotkey." + hotkey.name().toLowerCase(Locale.ROOT).replace("_", "");
//System.out.println("Permission for " + hotkey.name()+ ": " + permission);
return permission;
}
+
+ public static Hotkey fromPermission(String permission) {
+ //System.out.println("Checking permission " + permission + " and returning the proper hotkey...");
+ switch(permission) {
+ case "shiftclick": return SHIFT_CLICK;
+ case "middleclick": return MIDDLE_CLICK;
+ case "doubleclick": return DOUBLE_CLICK;
+ case "shiftrightclick": return SHIFT_RIGHT_CLICK;
+ case "leftclick": return LEFT_CLICK;
+ case "rightclick": return RIGHT_CLICK;
+ case "outside": return OUTSIDE;
+ case "autosorting": return AUTO_SORT;
+ case "autoinvsorting": return AUTO_INV_SORT;
+ default: return null;
+ }
+ }
+
+ public boolean hasEnabled(Player player) {
+ PlayerSetting setting = ChestSortPlugin.getInstance().getPlayerSetting(player);
+ switch(this) {
+ case SHIFT_CLICK: return setting.shiftClick;
+ case MIDDLE_CLICK: return setting.middleClick;
+ case DOUBLE_CLICK: return setting.doubleClick;
+ case SHIFT_RIGHT_CLICK: return setting.shiftRightClick;
+ case LEFT_CLICK: return setting.leftClick;
+ case RIGHT_CLICK: return setting.rightClick;
+ case OUTSIDE: return setting.leftClickOutside;
+ case AUTO_INV_SORT: return setting.invSortingEnabled;
+ case AUTO_SORT: return setting.sortingEnabled;
+ default: return false;
+ }
+ }
}
diff --git a/src/main/java/de/jeff_media/chestsort/gui/ChestSortGUIHolder.java b/src/main/java/de/jeff_media/chestsort/gui/ChestSortGUIHolder.java
new file mode 100644
index 0000000..469c42a
--- /dev/null
+++ b/src/main/java/de/jeff_media/chestsort/gui/ChestSortGUIHolder.java
@@ -0,0 +1,20 @@
+package de.jeff_media.chestsort.gui;
+
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.jetbrains.annotations.NotNull;
+
+public class ChestSortGUIHolder implements InventoryHolder {
+
+ private Inventory inv;
+
+ public void setInventory(Inventory inv) {
+ this.inv = inv;
+ }
+
+ @NotNull
+ @Override
+ public Inventory getInventory() {
+ return inv;
+ }
+}
diff --git a/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java b/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java
new file mode 100644
index 0000000..f8988ee
--- /dev/null
+++ b/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java
@@ -0,0 +1,49 @@
+package de.jeff_media.chestsort.gui;
+
+import de.jeff_media.chestsort.ChestSortPlugin;
+import de.jeff_media.chestsort.data.PlayerSetting;
+import org.bukkit.NamespacedKey;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.persistence.PersistentDataType;
+
+public class GUIListener implements Listener {
+
+ private static final ChestSortPlugin main = ChestSortPlugin.getInstance();
+
+ @EventHandler
+ public void onClick(InventoryClickEvent event) {
+ if(event.getView().getTopInventory().getHolder() instanceof ChestSortGUIHolder) {
+ event.setCancelled(true);
+ }
+
+ ItemStack clicked = event.getCurrentItem();
+ if(clicked == null || !clicked.hasItemMeta()) return;
+
+ if(!(event.getWhoClicked() instanceof Player)) return;
+ Player player = (Player) event.getWhoClicked();
+ PlayerSetting setting = main.getPlayerSetting(player);
+ String function = clicked.getItemMeta().getPersistentDataContainer().getOrDefault(new NamespacedKey(main,"function"), PersistentDataType.STRING,"");
+
+ //System.out.println("Click in GUI: " + function);
+
+ switch (function) {
+ case "": return;
+ case "leftclick": setting.toggleLeftClick(); break;
+ case "rightclick": setting.toggleRightClick(); break;
+ case "shiftclick": setting.toggleShiftClick(); break;
+ case "middleclick": setting.toggleMiddleClick(); break;
+ case "shiftrightclick": setting.toggleShiftRightClick(); break;
+ case "doubleclick": setting.toggleDoubleClick(); break;
+ case "outside": setting.toggleLeftClickOutside(); break;
+ case "autosorting": setting.toggleChestSorting(); break;
+ case "autoinvsorting": setting.toggleInvSorting(); break;
+ }
+
+ new NewUI(player).showGUI();
+
+ }
+}
diff --git a/src/main/java/de/jeff_media/chestsort/gui/NewUI.java b/src/main/java/de/jeff_media/chestsort/gui/NewUI.java
new file mode 100644
index 0000000..3c02a46
--- /dev/null
+++ b/src/main/java/de/jeff_media/chestsort/gui/NewUI.java
@@ -0,0 +1,73 @@
+package de.jeff_media.chestsort.gui;
+
+import de.jeff_media.chestsort.ChestSortPlugin;
+import de.jeff_media.chestsort.enums.Hotkey;
+import de.jeff_media.jefflib.ItemStackUtils;
+import de.jeff_media.jefflib.TextUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.NamespacedKey;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataType;
+
+public class NewUI {
+
+ private static final ChestSortPlugin main = ChestSortPlugin.getInstance();
+ private final YamlConfiguration conf = main.getGuiConfig();
+ private final Player player;
+
+ public NewUI(Player player) {
+ this.player = player;
+ }
+
+ private ItemStack getItem(int slot) {
+ if(conf.isConfigurationSection("slots." + slot)) {
+ return ItemStackUtils.fromConfigurationSection(conf.getConfigurationSection("slots." + slot));
+ }
+ if(conf.isString("slots." + slot)) {
+ String buttonName = conf.getString("slots." + slot);
+ //if(!player.hasPermission("chestsort.hotkey." + buttonName)) {
+ if(!Hotkey.fromPermission(buttonName).hasPermission(player)) {
+ buttonName = buttonName + "-nopermission";
+ } else {
+ boolean enabled = Hotkey.fromPermission(buttonName).hasEnabled(player);
+ //System.out.println(buttonName + " is enabled: " + enabled);
+ buttonName = buttonName + (enabled ? "-enabled" : "-disabled");
+ }
+ ItemStack button = ItemStackUtils.fromConfigurationSection(conf.getConfigurationSection("items." + buttonName));
+ //System.out.println(button);
+ if(button.hasItemMeta() && !buttonName.endsWith("-nopermission")) {
+ ItemMeta meta = button.getItemMeta();
+ assert meta != null;
+ meta.getPersistentDataContainer().set(new NamespacedKey(main,"function"),PersistentDataType.STRING, buttonName.split("-")[0]);
+ button.setItemMeta(meta);
+ }
+ return button;
+ }
+ return null;
+ }
+
+ public void showGUI() {
+
+ NewUI gui = new NewUI(player);
+
+ int size = conf.getInt("size");
+ String title = TextUtils.format(conf.getString("title"));
+
+ ChestSortGUIHolder holder = new ChestSortGUIHolder();
+ Inventory inv = Bukkit.createInventory(holder, size, title);
+ holder.setInventory(inv);
+
+ for(int i = 0; i < size; i++) {
+ ItemStack item = getItem(i);
+ inv.setItem(i, item);
+ }
+
+ player.openInventory(inv);
+
+ }
+
+}
diff --git a/src/main/java/de/jeff_media/chestsort/listeners/Listener.java b/src/main/java/de/jeff_media/chestsort/listeners/Listener.java
index 4091a28..6183d83 100644
--- a/src/main/java/de/jeff_media/chestsort/listeners/Listener.java
+++ b/src/main/java/de/jeff_media/chestsort/listeners/Listener.java
@@ -69,10 +69,11 @@ public class Listener implements org.bukkit.event.Listener {
if(CrateReloadedHook.isCrate(clickedBlock)) {
return;
}
- if(!ProtectionUtils.canInteract(event.getPlayer(), clickedBlock)) {
- //System.out.println("ChestSort: cannot interact!");
- return;
- }
+ if (!ProtectionUtils.canInteract(event.getPlayer(), clickedBlock, plugin.getConfig().getBoolean("mute-protection-plugins"))) {
+ //System.out.println("ChestSort: cannot interact!");
+ return;
+ }
+
plugin.registerPlayerIfNeeded(event.getPlayer());
PlayerSetting playerSetting = plugin.getPlayerSetting(event.getPlayer());
if(!playerSetting.leftClickOutside) return;
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 7bf1596..0f6be7a 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -14,11 +14,14 @@
####### Commands #######
###############################
-# /sort (or /chestsort) Toggle automatic sorting for containers (chests, barrels, enderchests, llamas, etc.)
+# /sort (or /chestsort) Shows the player settings GUI
# /sort on Enable automatic sorting for containers
# /sort off Disable automatic sorting for containers
# /sort hotkeys Open a GUI to change the sorting hotkeys
# /sort help Display help about the /sort (or /chestsort) command
+# /sort reload Reloads the config file
+# /sort resetplayersettings Resets every player's sorting settings. You should consider
+# running this after changing the default hotkey settings.
# /isort (or /invsort) Sort the player's inventory
# /isort hotbar Sort the player's hotbar
@@ -310,6 +313,16 @@ hook-generic: true
# it if it's the only possibility.
prevent-sorting-null-inventories: false
+##### Protection Plugins #####
+# ChestSort checks whether a player is allowed to interact with a block
+# before attempting to sort a container when using the "outside"/"left-click-block"
+# hotkey. This can result in messages from WorldGuard, CoreProtect, etc. being
+# send to the player. To avoid this, set the following setting to true.
+# This can however lead to some warnings from other plugins that do not
+# properly check a Players' class before casting it to "CraftPlayer".
+# Although this should NOT cause ANY problems, it's disabled by default.
+mute-protection-plugins: false
+
##########################
##### Sorting Method #####
##########################
diff --git a/src/main/resources/gui.yml b/src/main/resources/gui.yml
new file mode 100644
index 0000000..10fd6e1
--- /dev/null
+++ b/src/main/resources/gui.yml
@@ -0,0 +1,292 @@
+# You can customize the GUI here. Every single item is 100% customizable, including
+# their slot numbers, custom model data, custom base64 strings for heads, etc.
+
+# The default config uses Yaml Anchors so you don't have to define the same item
+# over and over again. I wrote a tiny explanation about them here:
+# https://wiki.jeff-media.com/books/general-information/page/yaml-anchors
+
+# Items can be defined using the following values:
+# material: DIAMOND
+# display-name: "My Diamond"
+# lore:
+# - "First line"
+# - "Second line, etc."
+# - "&cRed line"
+# - "<#ff0000>Red hex color"
+# - "<#ff0000>Hex gradient<#/ffffff>"
+# amount: 1
+# base64: ""
+# custom-model-data: 2
+# damage: 0
+# enchantments:
+# unbreaking: 3
+# efficiency: 5
+
+title: "<#000000>&l[<#007700>&lChest<#339933>&lSort<#000000>&l] &rSettings"
+size: 45
+items:
+ autosorting-enabled:
+ display-name: &autosorting-name "<#2e86c1>&lAutomatic Sorting<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: &base64-enabled "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNWZmMzE0MzFkNjQ1ODdmZjZlZjk4YzA2NzU4MTA2ODFmOGMxM2JmOTZmNTFkOWNiMDdlZDc4NTJiMmZmZDEifX19"
+ lore:
+ - &lore-enabled "<#229954>&lEnabled<#/7dcea0>"
+ - &autosorting-lore-1 "<#d5dbdb>Automatically sorts all chests,"
+ - &autosorting-lore-2 "<#d5dbdb>barrels etc when you use them."
+ autosorting-disabled:
+ display-name: *autosorting-name
+ material: PLAYER_HEAD
+ base64: &base64-disabled "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGU0YjhiOGQyMzYyYzg2NGUwNjIzMDE0ODdkOTRkMzI3MmE2YjU3MGFmYmY4MGMyYzViMTQ4Yzk1NDU3OWQ0NiJ9fX0="
+ lore:
+ - &lore-disabled "<#a93226>&lDisabled<#/e74c3c>"
+ - *autosorting-lore-1
+ - *autosorting-lore-2
+ autosorting-nopermission: &nopermission
+ display-name: *autosorting-name
+ material: BARRIER
+ lore:
+ - "<#a93226>No Permission<#/e74c3c>"
+
+
+ autoinvsorting-enabled:
+ display-name: &autoinvsorting-name "<#2e86c1>&lAutomatic Inventory Sorting<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &autoinvsorting-lore-1 "<#d5dbdb>Automatically sorts your player"
+ - &autoinvsorting-lore-2 "<#d5dbdb>inventory when you open it."
+ autoinvsorting-disabled:
+ display-name: *autoinvsorting-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *autoinvsorting-lore-1
+ - *autoinvsorting-lore-2
+ autoinvsorting-nopermission:
+ <<: *nopermission
+ display-name: *autoinvsorting-name
+
+
+ shiftclick-enabled:
+ display-name: &shiftclick-name "<#2e86c1>&lShift-Click<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &shiftclick-lore-1 "<#d5dbdb>Sorts an inventory using Shift-click"
+ - &shiftclick-lore-2 "<#d5dbdb>on an empty slot."
+ shiftclick-disabled:
+ display-name: *shiftclick-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *shiftclick-lore-1
+ - *shiftclick-lore-2
+ shiftclick-nopermission:
+ <<: *nopermission
+ display-name: *shiftclick-name
+
+
+ middleclick-enabled:
+ display-name: &middleclick-name "<#2e86c1>&lMiddle-Click<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &middleclick-lore-1 "<#d5dbdb>Sorts an inventory using Middle-click"
+ - &middleclick-lore-2 "<#d5dbdb>(mousewheel) on any slot."
+ middleclick-disabled:
+ display-name: *middleclick-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *middleclick-lore-1
+ - *middleclick-lore-2
+ middleclick-nopermission:
+ <<: *nopermission
+ display-name: *middleclick-name
+
+
+ doubleclick-enabled:
+ display-name: &doubleclick-name "<#2e86c1>&lDouble-Click<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &doubleclick-lore-1 "<#d5dbdb>Sorts an inventory using Double-click"
+ - &doubleclick-lore-2 "<#d5dbdb>on an empty slot."
+ doubleclick-disabled:
+ display-name: *doubleclick-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *doubleclick-lore-1
+ - *doubleclick-lore-2
+ doubleclick-nopermission:
+ <<: *nopermission
+ display-name: *doubleclick-name
+
+
+ shiftrightclick-enabled:
+ display-name: &shiftrightclick-name "<#2e86c1>&lShift-Right-Click<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &shiftrightclick-lore-1 "<#d5dbdb>Sorts an inventory using Shift-Right-click"
+ - &shiftrightclick-lore-2 "<#d5dbdb>on an empty slot."
+ shiftrightclick-disabled:
+ display-name: *shiftrightclick-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *shiftrightclick-lore-1
+ - *shiftrightclick-lore-2
+ shiftrightclick-nopermission:
+ <<: *nopermission
+ display-name: *shiftrightclick-name
+
+
+ outside-enabled:
+ display-name: &outside-name "<#2e86c1>&lLeft-Click Block<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &outside-lore-1 "<#d5dbdb>Sorts a chest, barrel etc. by"
+ - &outside-lore-2 "<#d5dbdb>left-clicking it."
+ outside-disabled:
+ display-name: *outside-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *outside-lore-1
+ - *outside-lore-2
+ outside-nopermission:
+ <<: *nopermission
+ display-name: *outside-name
+
+
+ leftclick-enabled:
+ display-name: &leftclick-name "<#2e86c1>&lFill Chest<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-enabled
+ lore:
+ - *lore-enabled
+ - &leftclick-lore-1 "<#d5dbdb>Fill a chest with matching items by"
+ - &leftclick-lore-2 "<#d5dbdb>left-clicking outside the opened inventory."
+ - &leftclick-lore-3 "<#d5dbdb>Fill a chest with all items (except your"
+ - &leftclick-lore-4 "<#d5dbdb>hotbar) by double-left-clicking outside"
+ - &leftclick-lore-5 "<#d5dbdb>the opened inventory."
+ leftclick-disabled:
+ display-name: *leftclick-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *leftclick-lore-1
+ - *leftclick-lore-2
+ - *leftclick-lore-3
+ - *leftclick-lore-4
+ - *leftclick-lore-5
+ leftclick-nopermission:
+ <<: *nopermission
+ display-name: *leftclick-name
+
+
+ rightclick-enabled:
+ display-name: &rightclick-name "<#2e86c1>Empty Chest<#/85c1e9>"
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-enabled
+ - &rightclick-lore-1 "<#d5dbdb>Take matching items from a chest by"
+ - &rightclick-lore-2 "<#d5dbdb>right-clicking outside the opened"
+ - &rightclick-lore-3 "<#d5dbdb>inventory. Take all items from a chest"
+ - &rightclick-lore-4 "<#d5dbdb>by double-left-clicking outside the"
+ - &rightclick-lore-5 "<#d5dbdb>opened inventory"
+ rightclick-disabled:
+ display-name: *rightclick-name
+ material: PLAYER_HEAD
+ base64: *base64-disabled
+ lore:
+ - *lore-disabled
+ - *rightclick-lore-1
+ - *rightclick-lore-2
+ - *rightclick-lore-3
+ - *rightclick-lore-4
+ - *rightclick-lore-5
+ rightclick-nopermission:
+ <<: *nopermission
+ display-name: *rightclick-name
+
+
+slots:
+ 0: &placeholder
+ material: BLACK_STAINED_GLASS_PANE
+ display-name: "&a" # Prevents showing the item's name
+ 1: *placeholder
+ 2: *placeholder
+ 3: *placeholder
+ 4: *placeholder
+ 5: *placeholder
+ 6: *placeholder
+ 7: *placeholder
+ 8: *placeholder
+
+ 9: *placeholder
+ 10: *placeholder
+ 11: autosorting
+ 12: *placeholder
+ 13: *placeholder
+ 14: *placeholder
+ 15: autoinvsorting
+ 16: *placeholder
+ 17: *placeholder
+
+ 18: *placeholder
+ 19: shiftclick
+ 20: *placeholder
+ 21: middleclick
+ 22: *placeholder
+ 23: doubleclick
+ 24: *placeholder
+ 25: shiftrightclick
+ 26: *placeholder
+
+ 27: *placeholder
+ 28: *placeholder
+ 29: leftclick
+ 30: *placeholder
+ 31: outside
+ 32: *placeholder
+ 33: rightclick
+ 34: *placeholder
+ 35: *placeholder
+
+ 36: *placeholder
+ 37: *placeholder
+ 38: *placeholder
+ 39: *placeholder
+ 40: *placeholder
+ 41: *placeholder
+ 42: *placeholder
+ 43: *placeholder
+ 44: *placeholder
+
+ 45: *placeholder
+ 46: *placeholder
+ 47: *placeholder
+ 48: *placeholder
+ 49: *placeholder
+ 50: *placeholder
+ 51: *placeholder
+ 52: *placeholder
+ 53: *placeholder
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 020339c..45965e8 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -15,11 +15,12 @@ commands:
sort:
description: Toggle automatic chest sorting or change your hotkey settings
usage: |
- / -- Toggle automatic chest sorting
+ / -- Shows the player setting GUI
/ on -- Enable automatic chest sorting
/ off -- Disable automatic chest sorting
- / hotkeys -- Change your hotkey settings
+ / toggle -- Toggle automatic chest sorting
/ reload -- Reloads config
+ / resetplayersettings -- Resets all players' sorting settings
/ help -- Shows help about this command
aliases: chestsort
permission: chestsort.use
@@ -35,11 +36,6 @@ commands:
/ help -- Shows help about this command
aliases: [invsort,inventorysort]
permission: chestsort.use.inventory
- chestsortadmin:
- description: Admin command for ChestSort
- usage: |
- / reset -- Reset's a player's hotkey settings
- permission: chestsort.admin
permissions:
chestsort.use:
description: Allows chest sorting
@@ -47,6 +43,8 @@ permissions:
description: Allows inventory sorting
chestsort.reload:
description: Allows to reload the config via /chestsort reload
+ chestsort.resetplayersettings:
+ description: Allows to reset every player's sorting settings
chestsort.hotkey.shiftclick:
default: true
chestsort.hotkey.middleclick:
diff --git a/src/main/resources/settings.fingerprint b/src/main/resources/settings.fingerprint
new file mode 100644
index 0000000..ae13e8c
--- /dev/null
+++ b/src/main/resources/settings.fingerprint
@@ -0,0 +1 @@
+v: 0
\ No newline at end of file