diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index 57229eb..0000000
--- a/TODO.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Todo
-## Auto updater
-Automatically use latest version
-## StackableItems
-Make it configurable whether ItemStacks > 64 items will stay unsorted, or sorted and reverted back to stacks of 64 items
--> https://www.spigotmc.org/threads/1-8-1-15-chestsort-api.334121/page-19#post-3821591
-
-## Auto-Refill
-Auto refills your hotbar with stuff from your inventory when you run out of items / a tool breaks.
-
-## MySQL
-Optional MySQL support for player configs to avoid thousands of yaml files within the playerdata folder
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index fc6bee5..703120d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,12 +9,12 @@
ChestSort
https://www.chestsort.de
Allows automatic chest sorting!
- 14.2.0
+ 14.3.0
jar
UTF-8
- 1.8
+ 21
${project.name}
${project.groupId}.chestsort.ChestSortPlugin
@@ -45,53 +45,26 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.8.1
+ 3.11.0
- ${java.version}
- ${java.version}
+ ${java.version}
org.apache.maven.plugins
maven-shade-plugin
- 3.2.4
+ 3.6.0
true
-
- com.jeff_media.jefflib
- de.jeff_media.chestsort.jefflib
-
-
-
- org.apache.maven.artifact
- de.jeff_media.chestsort.jefflib.thirdparty.org.apache.maven.artifact
-
-
-
-
- com.jeff_media.updatechecker
- de.jeff_media.chestsort.updatechecker
-
-
org.bstats
de.jeff_media.chestsort.bstats
-
- io.papermc.lib
- de.jeff_media.chestsort.paperlib
-
-
-
- com.jeff_media.morepersistentdatatypes
- com.jeff_media.chestsort.morepersistentdatatypes
-
-
@@ -108,19 +81,6 @@
META-INF/**
-
- *:*
- false
-
- de/jeff_media/jefflib/internal/nms/**
-
-
-
- *:*
-
- de/jeff_media/chestsortapi/**
-
-
@@ -146,11 +106,6 @@
-
- jeff-media-gbr
- https://repo.jeff-media.com/public/
-
-
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots/
@@ -158,7 +113,7 @@
papermc
- https://papermc.io/repo/repository/maven-public/
+ https://repo.papermc.io/repository/maven-public/
@@ -176,16 +131,6 @@
https://repo.codemc.org/repository/maven-public
-
- jeff-media-public
- https://hub.jeff-media.com/nexus/repository/jeff-media-public/
-
-
-
- pcgf-repo
- https://repo.pcgamingfreaks.at/repository/maven-everything
-
-
jitpack.io
https://jitpack.io
@@ -196,9 +141,9 @@
- org.spigotmc
- spigot-api
- 1.16.1-R0.1-SNAPSHOT
+ io.papermc.paper
+ paper-api
+ 1.21.4-R0.1-SNAPSHOT
provided
@@ -209,41 +154,6 @@
provided
-
- com.jeff_media
- SpigotUpdateChecker
- 2.2.0
- compile
-
-
-
- com.jeff_media
- MorePersistentDataTypes
- 2.3.1
- compile
-
-
-
- com.jeff-media.cesspool.modules
- yaml-commands
- 1.0-SNAPSHOT
- compile
-
-
-
- com.jeff-media.jefflib
- jefflib
- 14.2.3
- compile
-
-
-
- de.jeff_media
- InvUnload
- 4.17.1
- provided
-
-
me.clip
placeholderapi
@@ -265,19 +175,6 @@
compile
-
- at.pcgamingfreaks
- Minepacks-API
- 2.3.24
- provided
-
-
- org.jetbrains
- annotations
-
-
-
-
com.github.Slimefun
Slimefun4
@@ -285,13 +182,6 @@
provided
-
- io.papermc
- paperlib
- 1.0.8
- compile
-
-
com.github.DeadSilenceIV
AdvancedChestsAPI
diff --git a/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java b/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java
index 30d4c70..9091fcb 100644
--- a/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java
+++ b/src/main/java/de/jeff_media/chestsort/ChestSortPlugin.java
@@ -27,8 +27,6 @@
package de.jeff_media.chestsort;
-import at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksPlugin;
-import com.jeff_media.updatechecker.UpdateChecker;
import de.jeff_media.chestsort.commands.ChestSortCommand;
import de.jeff_media.chestsort.commands.InvSortCommand;
import de.jeff_media.chestsort.commands.TabCompleter;
@@ -51,11 +49,8 @@
import de.jeff_media.chestsort.listeners.ChestSortListener;
import de.jeff_media.chestsort.placeholders.Placeholders;
import de.jeff_media.chestsort.utils.Utils;
-import com.jeff_media.jefflib.JeffLib;
-import com.jeff_media.jefflib.data.McVersion;
-import com.jeff_media.jefflib.NBTAPI;
-import io.papermc.lib.PaperLib;
import org.bstats.bukkit.Metrics;
+import org.bukkit.persistence.PersistentDataType;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@@ -96,7 +91,6 @@ public class ChestSortPlugin extends JavaPlugin {
private ChestSortPermissionsHandler permissionsHandler;
private SettingsGUI settingsGUI;
private String sortingMethod;
- private UpdateChecker updateChecker;
private boolean usingMatchingConfig = true;
private boolean verbose = true;
private YamlConfiguration guiConfig = new YamlConfiguration();
@@ -323,14 +317,6 @@ public void setSortingMethod(String sortingMethod) {
this.sortingMethod = sortingMethod;
}
- public UpdateChecker getUpdateChecker() {
- return updateChecker;
- }
-
- public void setUpdateChecker(UpdateChecker updateChecker) {
- this.updateChecker = updateChecker;
- }
-
public boolean isDebug() {
return debug;
}
@@ -424,9 +410,6 @@ public void load(boolean reload) {
if (reload) {
unregisterAllPlayers();
reloadConfig();
- if (getUpdateChecker() != null) {
- getUpdateChecker().stop();
- }
}
createConfig();
@@ -446,7 +429,7 @@ public void load(boolean reload) {
&& Bukkit.getPluginManager().getPlugin("InventoryPages") != null);
setHookMinepacks(getConfig().getBoolean("hook-minepacks")
- && Bukkit.getPluginManager().getPlugin("Minepacks") instanceof MinepacksPlugin);
+ && Bukkit.getPluginManager().getPlugin("Minepacks") != null);
setHookAdvancedChests(getConfig().getBoolean("hook-advancedchests")
&& Bukkit.getPluginManager().getPlugin("AdvancedChests") != null);
@@ -472,23 +455,6 @@ public void load(boolean reload) {
new Messages();
setOrganizer(new ChestSortOrganizer(this));
setSettingsGUI(new SettingsGUI(this));
- try {
- if (Class.forName("net.md_5.bungee.api.chat.BaseComponent") != null) {
- setUpdateChecker(UpdateChecker.init(this, "https://api.jeff-media.de/chestsort/chestsort-latest-version.txt")
- .setChangelogLink("https://www.chestsort.de/changelog")
- .setDonationLink("https://paypal.me/mfnalex")
- .setDownloadLink("https://www.chestsort.de")
- .suppressUpToDateMessage(true));
- } else {
- getLogger().severe("You are using an unsupported server software! Consider switching to Spigot or Paper!");
- getLogger().severe("The Update Checker will NOT work when using CraftBukkit instead of Spigot/Paper!");
- PaperLib.suggestPaper(this);
- }
- } catch (ClassNotFoundException e) {
- getLogger().severe("You are using an unsupported server software! Consider switching to Spigot or Paper!");
- getLogger().severe("The Update Checker will NOT work when using CraftBukkit instead of Spigot/Paper!");
- PaperLib.suggestPaper(this);
- }
setListener(new ChestSortListener(this));
setHotkeyCooldown(new HashMap<>());
setPermissionsHandler(new ChestSortPermissionsHandler(this));
@@ -538,20 +504,6 @@ public void load(boolean reload) {
getLogger().info("Categories: " + getCategoryList());
}
- // TODO: Fix update checker for folia
- if (getUpdateChecker() != null) {
- if (getConfig().getString("check-for-updates", "true").equalsIgnoreCase("true")) {
- if(!usingFolia) getUpdateChecker().checkEveryXHours(getUpdateCheckInterval()).checkNow();
- } // When set to on-startup, we check right now (delay 0)
- else if (getConfig().getString("check-for-updates", "true").equalsIgnoreCase("on-startup")) {
- if(!usingFolia) getUpdateChecker().checkNow();
- }
- }
-
- if (getConfig().getString("check-for-updates").equalsIgnoreCase("false")) {
- getUpdateChecker().setNotifyOpsOnJoin(false);
- }
-
registerMetrics();
if (getConfig().getBoolean("dump")) {
@@ -583,8 +535,6 @@ public void onEnable() {
instance = this;
- JeffLib.init(this);
-
/*String tmpVersion = getServer().getClass().getPackage().getName();
setMcVersion(tmpVersion.substring(tmpVersion.lastIndexOf('.') + 1));
tmpVersion = getMcVersion().substring(getMcVersion().indexOf("_") + 1);
@@ -709,7 +659,7 @@ public void registerPlayerIfNeeded(Player p) {
boolean changed;
boolean hasSeenMessage;
- if (playerFile.exists() || !McVersion.current().isAtLeast(1,14,4)) {
+ if (playerFile.exists() || !true) {
// If the player settings file does not exist for this player, set it to the
// default value
activeForThisPlayer = playerConfig.getBoolean("sortingEnabled");
@@ -725,7 +675,7 @@ public void registerPlayerIfNeeded(Player p) {
changed = true;
- if (McVersion.current().isAtLeast(1,14,4)) {
+ if (true) {
if (playerFile.delete()) {
this.getLogger().info("Converted old .yml playerdata file to NBT tags for player " + p.getName());
} else {
@@ -738,16 +688,16 @@ public void registerPlayerIfNeeded(Player p) {
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")));
+ activeForThisPlayer = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "sortingEnabled" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("sortingEnabled"))));
+ invActiveForThisPlayer = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "invSortingEnabled" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("invSortingEnabled", getConfig().getBoolean("inv-sorting-enabled-by-default")))));
+ middleClick = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "middleClick" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("middleClick"))));
+ shiftClick = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "shiftClick" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("shiftClick"))));
+ doubleClick = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "doubleClick" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("doubleClick"))));
+ shiftRightClick = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "shiftRightClick" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("shiftRightClick"))));
+ leftClick = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "leftClick" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("leftClick", getConfig().getBoolean("additional-hotkeys.left-click")))));
+ rightClick = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "rightClick" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("rightClick", getConfig().getBoolean("additional-hotkeys.right-click")))));
+ leftClickFromOutside = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "leftClickOutside" + fingerprint), PersistentDataType.STRING, String.valueOf(playerConfig.getBoolean("leftClickOutside", getConfig().getBoolean("left-click-to-sort-enabled-by-default")))));
+ hasSeenMessage = Boolean.parseBoolean(p.getPersistentDataContainer().getOrDefault(new NamespacedKey(this, "hasSeenMessage" + fingerprint), PersistentDataType.STRING, "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...");
@@ -762,8 +712,8 @@ public void registerPlayerIfNeeded(Player p) {
// 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")) {
- if (McVersion.current().isAtLeast(1,14,4) && !playerFile.exists()) {
- NBTAPI.getNBT(p, "hasSeenMessage", String.valueOf(false));
+ if (!playerFile.exists()) {
+ newSettings.hasSeenMessage = false;
} else {
newSettings.hasSeenMessage = playerConfig.getBoolean("hasSeenMessage");
}
@@ -936,7 +886,7 @@ public void unregisterPlayer(Player p) {
if (getPerPlayerSettings().containsKey(uniqueId.toString())) {
PlayerSetting setting = getPerPlayerSettings().get(p.getUniqueId().toString());
- if (McVersion.current().isAtLeast(1,14,4)) {
+ if (true) {
for(NamespacedKey key : p.getPersistentDataContainer().getKeys()) {
if(key.getKey().equals(new NamespacedKey(this,"test").getKey())) {
@@ -946,16 +896,16 @@ public void unregisterPlayer(Player p) {
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));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "sortingEnabled" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.sortingEnabled));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "invSortingEnabled" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.invSortingEnabled));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "hasSeenMessage" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.hasSeenMessage));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "middleClick" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.middleClick));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "shiftClick" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.shiftClick));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "doubleClick" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.doubleClick));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "shiftRightClick" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.shiftRightClick));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "leftClick" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.leftClick));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "rightClick" + fingerprint), PersistentDataType.STRING, String.valueOf(setting.rightClick));
+ p.getPersistentDataContainer().set(new NamespacedKey(this, "leftClickOutside" + fingerprint), PersistentDataType.STRING, 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/AdminCommand.java b/src/main/java/de/jeff_media/chestsort/commands/AdminCommand.java
index 17cd489..20030d8 100644
--- a/src/main/java/de/jeff_media/chestsort/commands/AdminCommand.java
+++ b/src/main/java/de/jeff_media/chestsort/commands/AdminCommand.java
@@ -1,8 +1,9 @@
package de.jeff_media.chestsort.commands;
import de.jeff_media.chestsort.ChestSortPlugin;
-import com.jeff_media.jefflib.NBTAPI;
import org.bukkit.Bukkit;
+import org.bukkit.NamespacedKey;
+import org.bukkit.persistence.PersistentDataType;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@@ -73,7 +74,7 @@ private void reset(CommandSender sender, String[] args) {
};
for(String nbtTag : tags) {
- NBTAPI.removeNBT(player,nbtTag);
+ player.getPersistentDataContainer().remove(new NamespacedKey(plugin, nbtTag));
}
sender.sendMessage("Reset hotkey settings for player "+player.getName());
diff --git a/src/main/java/de/jeff_media/chestsort/config/Messages.java b/src/main/java/de/jeff_media/chestsort/config/Messages.java
index 4731ca0..4ddc49d 100644
--- a/src/main/java/de/jeff_media/chestsort/config/Messages.java
+++ b/src/main/java/de/jeff_media/chestsort/config/Messages.java
@@ -1,7 +1,7 @@
package de.jeff_media.chestsort.config;
import de.jeff_media.chestsort.ChestSortPlugin;
-import com.jeff_media.jefflib.TextUtils;
+import de.jeff_media.chestsort.utils.Utils;
import org.bukkit.ChatColor;
public class Messages {
@@ -27,60 +27,60 @@ public Messages() {
ChestSortPlugin plugin = ChestSortPlugin.getInstance();
- MSG_CONTAINER_SORTED = TextUtils.format( plugin.getConfig()
+ MSG_CONTAINER_SORTED = Utils.formatText( plugin.getConfig()
.getString("message-container-sorted","&aContainer sorted!"));
- MSG_ACTIVATED = TextUtils.format( plugin.getConfig()
+ MSG_ACTIVATED = Utils.formatText( plugin.getConfig()
.getString("message-sorting-enabled", "&7Automatic chest sorting has been &aenabled&7.&r"));
- MSG_DEACTIVATED = TextUtils.format( plugin.getConfig()
+ MSG_DEACTIVATED = Utils.formatText( plugin.getConfig()
.getString("message-sorting-disabled", "&7Automatic chest sorting has been &cdisabled&7.&r"));
- MSG_INVACTIVATED = TextUtils.format( plugin.getConfig()
+ MSG_INVACTIVATED = Utils.formatText( plugin.getConfig()
.getString("message-inv-sorting-enabled", "&7Automatic inventory sorting has been &aenabled&7.&r"));
- MSG_INVDEACTIVATED = TextUtils.format( plugin.getConfig()
+ MSG_INVDEACTIVATED = Utils.formatText( plugin.getConfig()
.getString("message-inv-sorting-disabled", "&7Automatic inventory sorting has been &cdisabled&7.&r"));
- MSG_COMMANDMESSAGE = TextUtils.format( plugin.getConfig().getString(
+ MSG_COMMANDMESSAGE = Utils.formatText( plugin.getConfig().getString(
"message-when-using-chest", "&7Hint: Type &6/chestsort&7 to enable automatic chest sorting."));
- MSG_COMMANDMESSAGE2 = TextUtils.format( plugin.getConfig().getString(
+ MSG_COMMANDMESSAGE2 = Utils.formatText( plugin.getConfig().getString(
"message-when-using-chest2", "&7Hint: Type &6/chestsort&7 to disable automatic chest sorting."));
- MSG_PLAYERSONLY = TextUtils.format( plugin.getConfig()
+ MSG_PLAYERSONLY = Utils.formatText( plugin.getConfig()
.getString("message-error-players-only", "&cError: This command can only be run by players.&r"));
- MSG_PLAYERINVSORTED = TextUtils.format(
+ MSG_PLAYERINVSORTED = Utils.formatText(
plugin.getConfig().getString("message-player-inventory-sorted", "&7Your inventory has been sorted."));
- MSG_INVALIDOPTIONS = TextUtils.format( plugin.getConfig()
+ MSG_INVALIDOPTIONS = Utils.formatText( plugin.getConfig()
.getString("message-error-invalid-options", "&cError: Unknown option %s. Valid options are %s."));
- MSG_GUI_ENABLED = TextUtils.format( plugin.getConfig()
+ MSG_GUI_ENABLED = Utils.formatText( plugin.getConfig()
.getString("message-gui-enabled","&aEnabled"));
- MSG_GUI_DISABLED = TextUtils.format( plugin.getConfig()
+ MSG_GUI_DISABLED = Utils.formatText( plugin.getConfig()
.getString("message-gui-disabled","&cDisabled"));
- MSG_GUI_MIDDLECLICK = TextUtils.format( plugin.getConfig()
+ MSG_GUI_MIDDLECLICK = Utils.formatText( plugin.getConfig()
.getString("message-gui-middle-click","Middle-Click"));
- MSG_GUI_SHIFTCLICK = TextUtils.format( plugin.getConfig()
+ MSG_GUI_SHIFTCLICK = Utils.formatText( plugin.getConfig()
.getString("message-gui-shift-click","Shift + Click"));
- MSG_GUI_DOUBLECLICK = TextUtils.format( plugin.getConfig()
+ MSG_GUI_DOUBLECLICK = Utils.formatText( plugin.getConfig()
.getString("message-gui-double-click","Double-Click"));
- MSG_GUI_LEFTCLICKOUTSIDE = TextUtils.format( plugin.getConfig()
+ MSG_GUI_LEFTCLICKOUTSIDE = Utils.formatText( plugin.getConfig()
.getString("message-gui-left-click-outside", "Left-Click"));
- MSG_GUI_SHIFTRIGHTCLICK = TextUtils.format( plugin.getConfig()
+ MSG_GUI_SHIFTRIGHTCLICK = Utils.formatText( plugin.getConfig()
.getString("message-gui-shift-right-click","Shift + Right-Click"));
- MSG_GUI_LEFTCLICK = TextUtils.format( plugin.getConfig().getString("message-gui-left-click","Fill Chest (Left-Click/Double-Left-Click)"));
+ MSG_GUI_LEFTCLICK = Utils.formatText( plugin.getConfig().getString("message-gui-left-click","Fill Chest (Left-Click/Double-Left-Click)"));
- MSG_GUI_RIGHTCLICK = TextUtils.format( plugin.getConfig().getString("message-gui-right-click","Unload Chest (Right-Click/Double-Right-Click)"));
+ MSG_GUI_RIGHTCLICK = Utils.formatText( plugin.getConfig().getString("message-gui-right-click","Unload Chest (Right-Click/Double-Right-Click)"));
MSG_ERR_HOTKEYSDISABLED = ChatColor.RED + "[ChestSort] Hotkeys have been disabled by the admin.";
}
diff --git a/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java b/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java
index 7c748d7..7756be7 100644
--- a/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java
+++ b/src/main/java/de/jeff_media/chestsort/gui/GUIListener.java
@@ -1,6 +1,5 @@
package de.jeff_media.chestsort.gui;
-import com.jeff_media.morepersistentdatatypes.DataType;
import de.jeff_media.chestsort.ChestSortPlugin;
import de.jeff_media.chestsort.data.PlayerSetting;
import de.jeff_media.chestsort.gui.tracker.CustomGUITracker;
@@ -38,8 +37,8 @@ public void onClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
PlayerSetting setting = main.getPlayerSetting(player);
String function = Objects.requireNonNull(clicked.getItemMeta()).getPersistentDataContainer().getOrDefault(new NamespacedKey(main,"function"), PersistentDataType.STRING,"");
- List userCommands = clicked.getItemMeta().getPersistentDataContainer().getOrDefault(new NamespacedKey(main,"user-commands"), DataType.asList(DataType.STRING), new ArrayList<>());
- List adminCommands = clicked.getItemMeta().getPersistentDataContainer().getOrDefault(new NamespacedKey(main,"admin-commands"), DataType.asList(DataType.STRING), new ArrayList<>());
+ List userCommands = clicked.getItemMeta().getPersistentDataContainer().getOrDefault(new NamespacedKey(main,"user-commands"), PersistentDataType.LIST.strings(), new ArrayList<>());
+ List adminCommands = clicked.getItemMeta().getPersistentDataContainer().getOrDefault(new NamespacedKey(main,"admin-commands"), PersistentDataType.LIST.strings(), new ArrayList<>());
executeCommands(player, player, userCommands);
executeCommands(player, Bukkit.getConsoleSender(), adminCommands);
diff --git a/src/main/java/de/jeff_media/chestsort/gui/NewUI.java b/src/main/java/de/jeff_media/chestsort/gui/NewUI.java
index 79b851f..701c97c 100644
--- a/src/main/java/de/jeff_media/chestsort/gui/NewUI.java
+++ b/src/main/java/de/jeff_media/chestsort/gui/NewUI.java
@@ -1,22 +1,33 @@
package de.jeff_media.chestsort.gui;
-import com.jeff_media.morepersistentdatatypes.DataType;
+import com.google.gson.JsonParser;
import de.jeff_media.chestsort.ChestSortPlugin;
import de.jeff_media.chestsort.enums.Hotkey;
-import com.jeff_media.jefflib.ItemStackUtils;
-import com.jeff_media.jefflib.TextUtils;
import de.jeff_media.chestsort.gui.tracker.CustomGUITracker;
import de.jeff_media.chestsort.gui.tracker.CustomGUIType;
+import de.jeff_media.chestsort.utils.Utils;
import org.bukkit.Bukkit;
+import org.bukkit.Material;
import org.bukkit.NamespacedKey;
+import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
+import org.bukkit.profile.PlayerProfile;
+import org.bukkit.profile.PlayerTextures;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Base64;
import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
public class NewUI {
@@ -30,31 +41,28 @@ public NewUI(Player player) {
private ItemStack getItem(int slot) {
if(conf.isConfigurationSection("slots." + slot)) {
- return ItemStackUtils.fromConfigurationSection(conf.getConfigurationSection("slots." + slot));
+ return fromConfigurationSection(conf.getConfigurationSection("slots." + slot));
}
if(conf.isString("slots." + slot)) {
String buttonName = conf.getString("slots." + slot);
- //if(!player.hasPermission("chestsort.hotkey." + buttonName)) {
Hotkey key = Hotkey.fromPermission(buttonName);
if(key != null && !Hotkey.fromPermission(buttonName).hasPermission(player)) {
buttonName = buttonName + "-nopermission";
} else {
boolean enabled = true;
if(key != null) enabled = Hotkey.fromPermission(buttonName).hasEnabled(player);
- //System.out.println(buttonName + " is enabled: " + enabled);
if(key != null) buttonName = buttonName + (enabled ? "-enabled" : "-disabled");
}
if(main.isDebug()) System.out.println("Button name: " + buttonName);
- ItemStack button = ItemStackUtils.fromConfigurationSection(conf.getConfigurationSection("items." + buttonName));
- //System.out.println(button);
+ ItemStack button = fromConfigurationSection(conf.getConfigurationSection("items." + buttonName));
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]);
List userCommands = conf.getStringList("items." + buttonName + ".commands.player");
List adminCommands = conf.getStringList("items." + buttonName + ".commands.console");
- meta.getPersistentDataContainer().set(new NamespacedKey(main,"user-commands"), DataType.asList(DataType.STRING), userCommands);
- meta.getPersistentDataContainer().set(new NamespacedKey(main,"admin-commands"), DataType.asList(DataType.STRING), adminCommands);
+ meta.getPersistentDataContainer().set(new NamespacedKey(main,"user-commands"), PersistentDataType.LIST.strings(), userCommands);
+ meta.getPersistentDataContainer().set(new NamespacedKey(main,"admin-commands"), PersistentDataType.LIST.strings(), adminCommands);
button.setItemMeta(meta);
}
return button;
@@ -64,10 +72,8 @@ private ItemStack getItem(int slot) {
public void showGUI() {
- NewUI gui = new NewUI(player);
-
int size = conf.getInt("size");
- String title = TextUtils.format(conf.getString("title"));
+ String title = Utils.formatText(conf.getString("title"));
Inventory inv = Bukkit.createInventory(null, size, title);
@@ -79,4 +85,75 @@ public void showGUI() {
CustomGUITracker.open(player, inv, CustomGUIType.NEW);
}
+ private static ItemStack fromConfigurationSection(ConfigurationSection section) {
+ if (section == null) return new ItemStack(Material.STONE);
+
+ Material material;
+ try {
+ material = Material.valueOf(section.getString("material", "STONE").toUpperCase());
+ } catch (IllegalArgumentException e) {
+ material = Material.STONE;
+ }
+
+ int amount = section.getInt("amount", 1);
+ ItemStack item = new ItemStack(material, amount);
+
+ // Apply base64 skull texture before touching ItemMeta for the first time
+ String base64 = section.getString("base64");
+ if (base64 != null && material == Material.PLAYER_HEAD) {
+ try {
+ String decoded = new String(Base64.getDecoder().decode(base64));
+ String url = JsonParser.parseString(decoded)
+ .getAsJsonObject()
+ .getAsJsonObject("textures")
+ .getAsJsonObject("SKIN")
+ .get("url").getAsString();
+ SkullMeta skullMeta = (SkullMeta) item.getItemMeta();
+ PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID());
+ PlayerTextures textures = profile.getTextures();
+ textures.setSkin(new URL(url));
+ profile.setTextures(textures);
+ skullMeta.setOwnerProfile(profile);
+ item.setItemMeta(skullMeta);
+ } catch (Exception ignored) {
+ // Invalid base64 or malformed texture JSON — leave as plain head
+ }
+ }
+
+ ItemMeta meta = item.getItemMeta();
+ if (meta == null) return item;
+
+ String displayName = section.getString("display-name");
+ if (displayName != null) {
+ meta.setDisplayName(Utils.formatText(displayName));
+ }
+
+ List loreStrings = section.getStringList("lore");
+ if (!loreStrings.isEmpty()) {
+ meta.setLore(loreStrings.stream()
+ .map(Utils::formatText)
+ .collect(Collectors.toList()));
+ }
+
+ if (section.isInt("custom-model-data")) {
+ meta.setCustomModelData(section.getInt("custom-model-data"));
+ }
+
+ if (meta instanceof Damageable && section.isInt("damage")) {
+ ((Damageable) meta).setDamage(section.getInt("damage"));
+ }
+
+ ConfigurationSection enchantSection = section.getConfigurationSection("enchantments");
+ if (enchantSection != null) {
+ for (String key : enchantSection.getKeys(false)) {
+ Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(key.toLowerCase()));
+ if (enchantment != null) {
+ meta.addEnchant(enchantment, enchantSection.getInt(key), true);
+ }
+ }
+ }
+
+ item.setItemMeta(meta);
+ return item;
+ }
}
diff --git a/src/main/java/de/jeff_media/chestsort/handlers/ChestSortOrganizer.java b/src/main/java/de/jeff_media/chestsort/handlers/ChestSortOrganizer.java
index b6e3249..5387605 100644
--- a/src/main/java/de/jeff_media/chestsort/handlers/ChestSortOrganizer.java
+++ b/src/main/java/de/jeff_media/chestsort/handlers/ChestSortOrganizer.java
@@ -397,19 +397,22 @@ public Map getSortableMap(ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta instanceof PotionMeta) {
PotionMeta potionMeta = (PotionMeta) meta;
- // Only continue if Method "getBasePotionData" exists
- Class extends PotionMeta> potionMetaClass = potionMeta.getClass();
+ // Try the new 1.20.5+ API (getBasePotionType) first, fall back to the old one
try {
- if (potionMeta.getBasePotionData() != null) {
+ org.bukkit.potion.PotionType potionType = potionMeta.getBasePotionType();
+ if (potionType != null && potionType.getPotionEffects() != null && !potionType.getPotionEffects().isEmpty()) {
+ potionEffect = "|" + potionType.getPotionEffects().get(0).getType().getName();
+ }
+ } catch (Throwable ignored) {
+ // Fall back to pre-1.20.5 API
+ try {
PotionData pdata = potionMeta.getBasePotionData();
if (pdata != null && pdata.getType() != null && pdata.getType().getEffectType() != null) {
potionEffect = "|" + pdata.getType().getEffectType().getName();
}
+ } catch (Throwable ignored2) {
}
- } catch (Throwable ignored) {
}
-
- // potionEffects = potionEffects.substring(0, potionEffects.length()-1);
}
}
diff --git a/src/main/java/de/jeff_media/chestsort/hooks/MinepacksHook.java b/src/main/java/de/jeff_media/chestsort/hooks/MinepacksHook.java
index 6e06881..819447d 100644
--- a/src/main/java/de/jeff_media/chestsort/hooks/MinepacksHook.java
+++ b/src/main/java/de/jeff_media/chestsort/hooks/MinepacksHook.java
@@ -1,63 +1,64 @@
package de.jeff_media.chestsort.hooks;
+import de.jeff_media.chestsort.ChestSortPlugin;
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
-import at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack;
-import at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksPlugin;
-import de.jeff_media.chestsort.ChestSortPlugin;
+import java.lang.reflect.Method;
public class MinepacksHook {
final ChestSortPlugin plugin;
- MinepacksPlugin minepacks = null;
- boolean skipReflection = false;
+ Plugin minepacks = null;
+ Method isBackpackItemMethod = null;
+ Class> backpackClass = null;
public MinepacksHook(ChestSortPlugin plugin) {
this.plugin = plugin;
Plugin bukkitPlugin = Bukkit.getPluginManager().getPlugin("Minepacks");
- if (plugin.isHookMinepacks() && bukkitPlugin instanceof MinepacksPlugin) {
- minepacks = (MinepacksPlugin) bukkitPlugin;
- plugin.getLogger().info("Successfully hooked into Minepacks");
+ if (plugin.isHookMinepacks() && bukkitPlugin != null) {
+ try {
+ Class.forName("at.pcgamingfreaks.Minepacks.Bukkit.API.MinepacksPlugin");
+ backpackClass = Class.forName("at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack");
+ minepacks = bukkitPlugin;
+ try {
+ isBackpackItemMethod = minepacks.getClass().getMethod("isBackpackItem", ItemStack.class);
+ } catch (NoSuchMethodException e) {
+ plugin.getLogger().warning("Minepacks version too old; hook disabled.");
+ plugin.setHookMinepacks(false);
+ }
+ if (minepacks != null) {
+ plugin.getLogger().info("Successfully hooked into Minepacks");
+ }
+ } catch (ClassNotFoundException e) {
+ plugin.getLogger().warning("Minepacks API classes not found; hook disabled.");
+ plugin.setHookMinepacks(false);
+ }
}
}
public boolean isMinepacksBackpack(ItemStack item) {
- if (minepacks == null) {
+ if (minepacks == null || isBackpackItemMethod == null) {
return false;
}
- if (skipReflection && minepacks.isBackpackItem(item)) {
- return true;
- }
-
try {
- minepacks.getClass().getMethod("isBackpackItem", ItemStack.class);
- skipReflection = true;
- if (minepacks.isBackpackItem(item)) {
- return true;
- }
- } catch (NoSuchMethodException | SecurityException e) {
- plugin.getLogger().warning(
- "You are using a version of Minepacks that is too old and does not implement every API method needed by ChestSort. Minepacks hook will be disabled.");
+ return (boolean) isBackpackItemMethod.invoke(minepacks, item);
+ } catch (Exception e) {
+ plugin.getLogger().warning("Minepacks hook error; disabling.");
minepacks = null;
plugin.setHookMinepacks(false);
+ return false;
}
-
- return false;
}
public boolean isMinepacksBackpack(Inventory inv, InventoryHolder holder) {
- if (minepacks == null) {
+ if (minepacks == null || backpackClass == null || holder == null) {
return false;
}
- if (holder == null) {
- return false;
- }
- return holder instanceof Backpack;
-
+ return backpackClass.isInstance(holder);
}
}
diff --git a/src/main/java/de/jeff_media/chestsort/listeners/ChestSortListener.java b/src/main/java/de/jeff_media/chestsort/listeners/ChestSortListener.java
index 9eba8f2..7f8de99 100644
--- a/src/main/java/de/jeff_media/chestsort/listeners/ChestSortListener.java
+++ b/src/main/java/de/jeff_media/chestsort/listeners/ChestSortListener.java
@@ -1,6 +1,5 @@
package de.jeff_media.chestsort.listeners;
-import com.jeff_media.jefflib.ProtectionUtils;
import de.jeff_media.chestsort.ChestSortPlugin;
import de.jeff_media.chestsort.api.ChestSortEvent;
import de.jeff_media.chestsort.api.ChestSortPostSortEvent;
@@ -35,6 +34,7 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
+import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
@@ -164,9 +164,9 @@ public void onLeftClickChest(PlayerInteractEvent event) {
}
if (plugin.getConfig().getBoolean("mute-protection-plugins")) {
- if (!ProtectionUtils.canBreak(event.getPlayer(),
- clickedBlock.getLocation()/*, plugin.getConfig().getBoolean("mute-protection-plugins")*/)) {
- //System.out.println("ChestSort: cannot interact!");
+ BlockBreakEvent breakTest = new BlockBreakEvent(clickedBlock, event.getPlayer());
+ Bukkit.getPluginManager().callEvent(breakTest);
+ if (breakTest.isCancelled()) {
return;
}
}
@@ -372,6 +372,12 @@ public void onChestClose(InventoryCloseEvent event) {
return;
}
+ // For ender chests, sort the player's actual ender chest inventory directly
+ if (inventory.getType() == InventoryType.ENDER_CHEST) {
+ plugin.getOrganizer().sortInventory(p.getEnderChest());
+ return;
+ }
+
// Normal container inventories can be sorted completely
plugin.getOrganizer().sortInventory(inventory);
}
@@ -573,18 +579,19 @@ public void onEnderChestOpen(InventoryOpenEvent event) {
return;
}
- // Check if this is an EnderChest (is there a smarter way?)
- if (!inventory.equals(p.getEnderChest())) {
+ // Check if this is a vanilla EnderChest by inventory type
+ if (inventory.getType() != InventoryType.ENDER_CHEST) {
return;
}
if (isReadyToSort(p)) {
// Finally call the Organizer to sort the inventory
+ // Use p.getEnderChest() directly to ensure we sort the actual backing inventory
plugin.getLgr().logSort(p, Logger.SortCause.EC_OPEN);
- plugin.getOrganizer().sortInventory(inventory);
+ plugin.getOrganizer().sortInventory(p.getEnderChest());
}
}
@@ -638,10 +645,11 @@ public void onHotkey(InventoryClickEvent event) {
}
- // Possible fix for #57
+ // Possible fix for #57 — but ender chests also have the player as holder, so exclude them
if (!isAPICall &&
(holder != null && holder == p &&
- clicked != p.getInventory())) {
+ clicked != p.getInventory() &&
+ clicked.getType() != InventoryType.ENDER_CHEST)) {
return;
}
@@ -824,11 +832,11 @@ public void onAdditionalHotkeys(InventoryClickEvent event) {
advancedChestsHook.isAnAdvancedChest(inventory);
// Possible fix for #57
- if (holder == null && !view.getTopInventory().equals(player.getEnderChest()) &&
+ if (holder == null && view.getTopInventory().getType() != InventoryType.ENDER_CHEST &&
!isAdvancedChest) {
return;
}
- if (holder == player && inventory != player.getInventory()) {
+ if (holder == player && inventory != player.getInventory() && inventory.getType() != InventoryType.ENDER_CHEST) {
return;
}
// End Possible fix for #57
@@ -840,7 +848,7 @@ public void onAdditionalHotkeys(InventoryClickEvent event) {
!inventory.getType().name().equalsIgnoreCase("SHULKER_BOX") &&
(holder == null ||
!holder.getClass().toString().endsWith(".CraftBarrel")) &&
- inventory != player.getEnderChest() && !(holder instanceof ISortable)) {
+ inventory.getType() != InventoryType.ENDER_CHEST && !(holder instanceof ISortable)) {
return;
}
diff --git a/src/main/java/de/jeff_media/chestsort/utils/Utils.java b/src/main/java/de/jeff_media/chestsort/utils/Utils.java
index ba91fa0..ad09dc1 100644
--- a/src/main/java/de/jeff_media/chestsort/utils/Utils.java
+++ b/src/main/java/de/jeff_media/chestsort/utils/Utils.java
@@ -5,13 +5,41 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import de.jeff_media.chestsort.ChestSortPlugin;
+import org.bukkit.ChatColor;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public class Utils {
+ private static final Pattern HEX_PATTERN = Pattern.compile("<#([0-9a-fA-F]{6})>");
+
+ /**
+ * Converts a string with legacy & colour codes and <#rrggbb> hex colour
+ * tags into a Bukkit-formatted string (§ codes).
+ */
+ public static String formatText(String text) {
+ if (text == null) return "";
+ // Strip gradient-end tags like <#/85c1e9>
+ text = text.replaceAll("<#/[0-9a-fA-F]{6}>", "");
+ // Convert <#rrggbb> to Spigot §x§r§r§g§g§b§b hex format
+ Matcher matcher = HEX_PATTERN.matcher(text);
+ StringBuffer sb = new StringBuffer();
+ while (matcher.find()) {
+ String hex = matcher.group(1);
+ StringBuilder spigotHex = new StringBuilder("§x");
+ for (char c : hex.toCharArray()) {
+ spigotHex.append('§').append(c);
+ }
+ matcher.appendReplacement(sb, Matcher.quoteReplacement(spigotHex.toString()));
+ }
+ matcher.appendTail(sb);
+ return ChatColor.translateAlternateColorCodes('&', sb.toString());
+ }
+
public static ItemStack[] getStorageContents(Inventory inv) {
return inv.getStorageContents();
}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 9173527..4ffa21a 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,16 +1,16 @@
main: ${spigot.main}
name: ${project.name}
version: ${project.version}
-api-version: "1.13"
+api-version: "1.21"
description: "${project.description}"
folia-supported: true
authors:
- mfnalex
- JEFF Media GbR
+ - SamsSide
website: ${project.url}
prefix: ${spigot.prefix}
database: false
-loadbefore: [InvUnload]
softdepend: [CrackShot,InventoryPages,Minepacks,PlaceholderAPI,AdvancedChests,ShulkerPacks]
commands:
sort: