From 72dfa8d80b749c288279c312ceb06fad99130107 Mon Sep 17 00:00:00 2001 From: tommasov03 Date: Sat, 25 Jul 2026 15:27:16 +0000 Subject: [PATCH 1/2] Update XSeries to 13.7.1 and relocate its package to fix plugin conflicts XMaterial's static initializer threw NumberFormatException while parsing newer Minecraft version strings (up to 26.2), which the old bundled XSeries 6.0.1 couldn't handle. Because the com.cryptomorin.xseries package was shaded unrelocated, Bukkit's cross-plugin class resolution let other plugins (e.g. UltraCoinFlip) pick up HomeGUI's broken XMaterial class via Class.forName, crashing their enable and disabling their commands too. Bumping to XSeries 13.7.1 (tested against Spigot 26.2) restores support for the full 1.8-26.2 range, and relocating the shaded package to com.technovision.homegui.libs.xseries isolates it so it can no longer leak into or collide with other plugins' classloading. --- pom.xml | 10 ++++++++-- src/main/resources/plugin.yml | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c75b4d3..a88b027 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.technovision homegui - 1.3 + 1.5 jar Homegui @@ -40,6 +40,12 @@ false + + + com.cryptomorin.xseries + com.technovision.homegui.libs.xseries + + @@ -78,7 +84,7 @@ com.github.cryptomorin XSeries - 6.0.1 + 13.7.1 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3e66fce..19f1aa0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: HomeGUI -version: 1.4 +version: 1.5 main: com.technovision.homegui.Homegui api-version: 1.13 depend: [Essentials] From b424132d5b4dd97c0ceed65cf6f29e8c5047d5b4 Mon Sep 17 00:00:00 2001 From: tommasov03 Date: Sat, 25 Jul 2026 15:40:26 +0000 Subject: [PATCH 2/2] Fix item-loss/dupe exploit in GUI inventories and reduce redundant disk I/O InventoryClickEvent was only cancelled when the clicked slot held an item, and InventoryDragEvent was never handled at all, so a player could drag or click a real item into an empty HomeGUI/ChangeIconGUI slot; with no InventoryCloseEvent to return it, the item was simply lost. Both GUIs now cancel every click and drag unconditionally. Also removed the per-home YAML file reload in PlayerDataReader.getItem (it was reading the player's icon data file from disk once per home in the /home GUI) in favor of loading it once per GUI open, hoisted the repeated config lookups out of HomeGUI's item loop, guarded against a null Material lookup that could NPE, and simplified the redundant modulo loop in calculateSize(). --- .../homegui/events/HomeEvents.java | 18 ++++++++++++++---- .../com/technovision/homegui/gui/HomeGUI.java | 15 +++++++-------- .../homegui/playerdata/PlayerDataReader.java | 18 +++++++++++------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/technovision/homegui/events/HomeEvents.java b/src/main/java/com/technovision/homegui/events/HomeEvents.java index 88487de..f36bacb 100644 --- a/src/main/java/com/technovision/homegui/events/HomeEvents.java +++ b/src/main/java/com/technovision/homegui/events/HomeEvents.java @@ -10,19 +10,29 @@ import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.InventoryHolder; public class HomeEvents implements Listener { + @EventHandler + public void onGuiDrag(InventoryDragEvent event) { + InventoryHolder holder = event.getInventory().getHolder(); + if (holder instanceof HomeGUI || holder instanceof ChangeIconGUI) { + event.setCancelled(true); + } + } + @EventHandler public void onGuiActivation(InventoryClickEvent event){ if (event.getInventory().getHolder() instanceof HomeGUI) { if (event.getClickedInventory() == null) { return; } + event.setCancelled(true); Player player = (Player) event.getWhoClicked(); + if (event.getClickedInventory().getType() == InventoryType.PLAYER) { return; } if (event.getCurrentItem() != null) { if (event.getCurrentItem().getType() == Material.AIR) { return; } - event.setCancelled(true); - if (event.getClickedInventory().getType() == InventoryType.PLAYER) { return; } String playerID = player.getUniqueId().toString(); int slotNum = event.getSlot(); String name = HomeGUI.allHomes.get(playerID).get(slotNum).getName(); @@ -44,11 +54,11 @@ public void onGuiActivation(InventoryClickEvent event){ } } else if (event.getInventory().getHolder() instanceof ChangeIconGUI) { if (event.getClickedInventory() == null) { return; } + event.setCancelled(true); Player player = (Player) event.getWhoClicked(); + if (event.getClickedInventory().getType() == InventoryType.PLAYER) { return; } if (event.getCurrentItem() != null) { if (event.getCurrentItem().getType() == Material.AIR) { return; } - event.setCancelled(true); - if (event.getClickedInventory().getType() == InventoryType.PLAYER) { return; } if (event.isLeftClick()) { String itemName = getFriendlyName(event.getCurrentItem().getType()); String playerID = event.getWhoClicked().getUniqueId().toString(); diff --git a/src/main/java/com/technovision/homegui/gui/HomeGUI.java b/src/main/java/com/technovision/homegui/gui/HomeGUI.java index b4d578f..9d26d04 100644 --- a/src/main/java/com/technovision/homegui/gui/HomeGUI.java +++ b/src/main/java/com/technovision/homegui/gui/HomeGUI.java @@ -4,6 +4,7 @@ import com.technovision.homegui.playerdata.EssentialsReader; import com.technovision.homegui.playerdata.Home; import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; @@ -34,21 +35,19 @@ private int calculateSize() { if (size == 0) {return 9;} if (size >= 54) { return 54; } if (size % 9 == 0) { return size; } - int count = 0; - for (int i = size%9; i>0; i--) { - count++; - } - return (size - count) + 9; + return (size - (size % 9)) + 9; } private void initItems(String playerID) { + YamlConfiguration iconConfig = Homegui.dataReader.loadConfig(playerID); + String nameColor = Homegui.PLUGIN.getConfig().getString("home-color").replace("&", "§"); + List loreTemplate = Homegui.PLUGIN.getConfig().getStringList("home-lore"); String name; for (Home home : homes) { name = home.getName().substring(0, 1).toUpperCase() + home.getName().substring(1); - ItemStack item = Homegui.dataReader.getItem(playerID, home.getName()); - String nameColor = Homegui.PLUGIN.getConfig().getString("home-color").replace("&", "§"); + ItemStack item = Homegui.dataReader.getItem(iconConfig, home.getName()); name = nameColor + name; - List lore = Homegui.PLUGIN.getConfig().getStringList("home-lore"); + List lore = new ArrayList<>(loreTemplate); String location = "§f " + home.getX() + "x§7,§f " + home.getY() + "y§7,§f " + home.getZ() + "z"; for (int i = 0; i < lore.size(); i++) { String newLine = lore.get(i).replace("{location}", location); diff --git a/src/main/java/com/technovision/homegui/playerdata/PlayerDataReader.java b/src/main/java/com/technovision/homegui/playerdata/PlayerDataReader.java index 0f1b224..b9070a9 100644 --- a/src/main/java/com/technovision/homegui/playerdata/PlayerDataReader.java +++ b/src/main/java/com/technovision/homegui/playerdata/PlayerDataReader.java @@ -49,20 +49,24 @@ public void write(String playerUUID, String key, Material icon) { } } - public ItemStack getItem(String playerUUID, String homeName) { + public YamlConfiguration loadConfig(String playerUUID) { File dataFile = getFile(playerUUID); - if (dataFile.exists()) { - YamlConfiguration dataFileConfig = YamlConfiguration.loadConfiguration(dataFile); - if (dataFileConfig.contains(homeName)) { - String name = dataFileConfig.get(homeName).toString(); + return dataFile.exists() ? YamlConfiguration.loadConfiguration(dataFile) : null; + } + + public ItemStack getItem(YamlConfiguration dataFileConfig, String homeName) { + if (dataFileConfig != null && dataFileConfig.contains(homeName)) { + String name = dataFileConfig.get(homeName).toString(); + Material material = Material.getMaterial(name); + if (material != null) { XMaterial item; - String materialName = Material.getMaterial(name).toString(); + String materialName = material.toString(); if (materialName.equalsIgnoreCase("PISTON_MOVING_PIECE")) { item = XMaterial.PISTON; } else if (materialName.equalsIgnoreCase("BED")) { item = XMaterial.RED_BED; } else { - item = XMaterial.matchXMaterial(Material.getMaterial(name)); + item = XMaterial.matchXMaterial(material); } return item.parseItem(); }