From 63f99b3309d79699ce19841ccc85be2185f1f6e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:16:23 +0000 Subject: [PATCH 1/4] Fix rule config snapshot usage and reload rule chain Agent-Logs-Url: https://github.com/Alexteens24/DynamicKeepInv/sessions/f4ca5fc6-a29f-4788-ab89-b1e94d4672a9 Co-authored-by: Alexteens24 <207885348+Alexteens24@users.noreply.github.com> --- .../dynamickeepinv/CommandDispatcher.java | 1 + .../xyz/superez/dynamickeepinv/DKIConfig.java | 6 ++ .../dynamickeepinv/DynamicKeepInvPlugin.java | 4 + .../rules/BypassPermissionRule.java | 2 +- .../dynamickeepinv/rules/DeathCauseRule.java | 9 ++- .../dynamickeepinv/rules/ProtectionRule.java | 74 +++++++++---------- .../dynamickeepinv/rules/WorldTimeRule.java | 18 ++--- 7 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java b/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java index 95e3c83..616d21f 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java +++ b/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java @@ -60,6 +60,7 @@ public boolean dispatch(CommandSender sender, Command command, String label, Str plugin.reloadConfig(); plugin.loadMessages(); plugin.reloadIntegrations(); + plugin.reloadRuleManager(); plugin.reloadPendingDeathManager(); plugin.reloadStatsSystem(); if (plugin.getConfig().getBoolean("enabled", true)) { diff --git a/src/main/java/xyz/superez/dynamickeepinv/DKIConfig.java b/src/main/java/xyz/superez/dynamickeepinv/DKIConfig.java index 640fdb8..3a1d7da 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/DKIConfig.java +++ b/src/main/java/xyz/superez/dynamickeepinv/DKIConfig.java @@ -100,6 +100,9 @@ public class DKIConfig { public final boolean worldGuardOwnRegionKeepXp; public final boolean worldGuardOtherRegionKeepItems; public final boolean worldGuardOtherRegionKeepXp; + public final boolean worldGuardWildernessEnabled; + public final boolean worldGuardWildernessKeepItems; + public final boolean worldGuardWildernessKeepXp; // --- Integrations: Towny --- public final boolean townyEnabled; @@ -221,6 +224,9 @@ public DKIConfig(FileConfiguration cfg) { worldGuardOwnRegionKeepXp = cfg.getBoolean("integrations.worldguard.in-own-region.keep-xp", true); worldGuardOtherRegionKeepItems = cfg.getBoolean("integrations.worldguard.in-other-region.keep-items",false); worldGuardOtherRegionKeepXp = cfg.getBoolean("integrations.worldguard.in-other-region.keep-xp", false); + worldGuardWildernessEnabled = cfg.getBoolean("integrations.worldguard.wilderness.enabled", false); + worldGuardWildernessKeepItems = cfg.getBoolean("integrations.worldguard.wilderness.keep-items", false); + worldGuardWildernessKeepXp = cfg.getBoolean("integrations.worldguard.wilderness.keep-xp", false); // Towny townyEnabled = cfg.getBoolean("integrations.towny.enabled", false); diff --git a/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java b/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java index a6abf4a..46c6f06 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java +++ b/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java @@ -585,6 +585,10 @@ private void setupRuleManager() { ruleManager.registerRule(new WorldTimeRule()); } + void reloadRuleManager() { + setupRuleManager(); + } + public RuleManager getRuleManager() { return ruleManager; } diff --git a/src/main/java/xyz/superez/dynamickeepinv/rules/BypassPermissionRule.java b/src/main/java/xyz/superez/dynamickeepinv/rules/BypassPermissionRule.java index 557981f..505512f 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/rules/BypassPermissionRule.java +++ b/src/main/java/xyz/superez/dynamickeepinv/rules/BypassPermissionRule.java @@ -8,7 +8,7 @@ public class BypassPermissionRule implements DeathRule { @Override public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) { - if (!plugin.getConfig().getBoolean("rules.bypass-permission", true)) { + if (!plugin.getDKIConfig().bypassPermissionEnabled) { return null; } diff --git a/src/main/java/xyz/superez/dynamickeepinv/rules/DeathCauseRule.java b/src/main/java/xyz/superez/dynamickeepinv/rules/DeathCauseRule.java index bd3c139..71e83fe 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/rules/DeathCauseRule.java +++ b/src/main/java/xyz/superez/dynamickeepinv/rules/DeathCauseRule.java @@ -2,22 +2,23 @@ import org.bukkit.entity.Player; import org.bukkit.event.entity.PlayerDeathEvent; +import xyz.superez.dynamickeepinv.DKIConfig; import xyz.superez.dynamickeepinv.DynamicKeepInvPlugin; public class DeathCauseRule implements DeathRule { @Override public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) { - if (!plugin.getConfig().getBoolean("rules.death-cause.enabled", false)) { + DKIConfig cfg = plugin.getDKIConfig(); + if (!cfg.deathCauseEnabled) { return null; } Player player = event.getEntity(); boolean isPvp = player.getKiller() != null; - String causePath = isPvp ? "rules.death-cause.pvp" : "rules.death-cause.pve"; - boolean keepItems = plugin.getConfig().getBoolean(causePath + ".keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean(causePath + ".keep-xp", false); + boolean keepItems = isPvp ? cfg.pvpKeepItems : cfg.pveKeepItems; + boolean keepXp = isPvp ? cfg.pvpKeepXp : cfg.pveKeepXp; String reason = isPvp ? RuleReasons.PVP : RuleReasons.PVE; return new RuleResult(keepItems, keepXp, reason); diff --git a/src/main/java/xyz/superez/dynamickeepinv/rules/ProtectionRule.java b/src/main/java/xyz/superez/dynamickeepinv/rules/ProtectionRule.java index 84486d9..3b102a3 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/rules/ProtectionRule.java +++ b/src/main/java/xyz/superez/dynamickeepinv/rules/ProtectionRule.java @@ -3,6 +3,7 @@ import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.entity.PlayerDeathEvent; +import xyz.superez.dynamickeepinv.DKIConfig; import xyz.superez.dynamickeepinv.DynamicKeepInvPlugin; import xyz.superez.dynamickeepinv.hooks.GriefPreventionHook; import xyz.superez.dynamickeepinv.hooks.LandsHook; @@ -13,14 +14,15 @@ public class ProtectionRule implements DeathRule { @Override public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) { + DKIConfig cfg = plugin.getDKIConfig(); Player player = event.getEntity(); Location location = player.getLocation(); // 1. Check Lands - if (plugin.isLandsEnabled() && plugin.getConfig().getBoolean("integrations.lands.enabled", false)) { + if (plugin.isLandsEnabled() && cfg.landsEnabled) { LandsHook lands = plugin.getLandsHook(); boolean inLand = lands.isInLand(location); - boolean overrideLands = plugin.getConfig().getBoolean("integrations.lands.override-lands", false); + boolean overrideLands = cfg.landsOverride; if (inLand) { if (!overrideLands) { @@ -28,21 +30,17 @@ public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) } boolean isOwnLand = lands.isInOwnLand(player); - String configPath = isOwnLand ? "integrations.lands.in-own-land" : "integrations.lands.in-other-land"; - - if (plugin.getConfig().contains(configPath)) { - boolean keepItems = plugin.getConfig().getBoolean(configPath + ".keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean(configPath + ".keep-xp", false); - String reason = isOwnLand ? RuleReasons.LANDS_OWN : RuleReasons.LANDS_OTHER; - return new RuleResult(keepItems, keepXp, reason); - } + boolean keepItems = isOwnLand ? cfg.landsOwnKeepItems : cfg.landsOtherKeepItems; + boolean keepXp = isOwnLand ? cfg.landsOwnKeepXp : cfg.landsOtherKeepXp; + String reason = isOwnLand ? RuleReasons.LANDS_OWN : RuleReasons.LANDS_OTHER; + return new RuleResult(keepItems, keepXp, reason); } else { // Wilderness - if (plugin.getConfig().getBoolean("integrations.lands.wilderness.enabled", false)) { - boolean useDeathCause = plugin.getConfig().getBoolean("integrations.lands.wilderness.use-death-cause", false); + if (cfg.landsWildernessEnabled) { + boolean useDeathCause = cfg.landsWildernessUseDeathCause; if (!useDeathCause) { - boolean keepItems = plugin.getConfig().getBoolean("integrations.lands.wilderness.keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean("integrations.lands.wilderness.keep-xp", false); + boolean keepItems = cfg.landsWildernessKeepItems; + boolean keepXp = cfg.landsWildernessKeepXp; return new RuleResult(keepItems, keepXp, RuleReasons.LANDS_WILDERNESS); } // If useDeathCause is true, we return null to let DeathCauseRule handle it. @@ -51,24 +49,20 @@ public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) } // 2. Check GriefPrevention - if (plugin.isGriefPreventionEnabled() && plugin.getConfig().getBoolean("integrations.griefprevention.enabled", false)) { + if (plugin.isGriefPreventionEnabled() && cfg.gpEnabled) { GriefPreventionHook gp = plugin.getGriefPreventionHook(); if (gp.isInClaim(location)) { boolean isOwnClaim = gp.isInOwnClaim(player); - String configPath = isOwnClaim ? "integrations.griefprevention.in-own-claim" : "integrations.griefprevention.in-other-claim"; - - if (plugin.getConfig().contains(configPath)) { - boolean keepItems = plugin.getConfig().getBoolean(configPath + ".keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean(configPath + ".keep-xp", false); - String reason = isOwnClaim ? RuleReasons.GP_OWN : RuleReasons.GP_OTHER; - return new RuleResult(keepItems, keepXp, reason); - } + boolean keepItems = isOwnClaim ? cfg.gpOwnKeepItems : cfg.gpOtherKeepItems; + boolean keepXp = isOwnClaim ? cfg.gpOwnKeepXp : cfg.gpOtherKeepXp; + String reason = isOwnClaim ? RuleReasons.GP_OWN : RuleReasons.GP_OTHER; + return new RuleResult(keepItems, keepXp, reason); } else { - if (plugin.getConfig().getBoolean("integrations.griefprevention.wilderness.enabled", false)) { - boolean useDeathCause = plugin.getConfig().getBoolean("integrations.griefprevention.wilderness.use-death-cause", false); + if (cfg.gpWildernessEnabled) { + boolean useDeathCause = cfg.gpWildernessUseDeathCause; if (!useDeathCause) { - boolean keepItems = plugin.getConfig().getBoolean("integrations.griefprevention.wilderness.keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean("integrations.griefprevention.wilderness.keep-xp", false); + boolean keepItems = cfg.gpWildernessKeepItems; + boolean keepXp = cfg.gpWildernessKeepXp; return new RuleResult(keepItems, keepXp, RuleReasons.GP_WILDERNESS); } } @@ -76,38 +70,36 @@ public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) } // 3. Check WorldGuard - if (plugin.isWorldGuardEnabled() && plugin.getConfig().getBoolean("integrations.worldguard.enabled", false)) { + if (plugin.isWorldGuardEnabled() && cfg.worldGuardEnabled) { WorldGuardHook wg = plugin.getWorldGuardHook(); if (wg.isInRegion(location)) { boolean isOwnRegion = wg.isInOwnRegion(player); - String configPath = isOwnRegion ? "integrations.worldguard.in-own-region" : "integrations.worldguard.in-other-region"; - boolean keepItems = plugin.getConfig().getBoolean(configPath + ".keep-items", isOwnRegion); - boolean keepXp = plugin.getConfig().getBoolean(configPath + ".keep-xp", isOwnRegion); + boolean keepItems = isOwnRegion ? cfg.worldGuardOwnRegionKeepItems : cfg.worldGuardOtherRegionKeepItems; + boolean keepXp = isOwnRegion ? cfg.worldGuardOwnRegionKeepXp : cfg.worldGuardOtherRegionKeepXp; String reason = isOwnRegion ? RuleReasons.WG_OWN : RuleReasons.WG_OTHER; return new RuleResult(keepItems, keepXp, reason); } else { - if (plugin.getConfig().getBoolean("integrations.worldguard.wilderness.enabled", false)) { - boolean keepItems = plugin.getConfig().getBoolean("integrations.worldguard.wilderness.keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean("integrations.worldguard.wilderness.keep-xp", false); + if (cfg.worldGuardWildernessEnabled) { + boolean keepItems = cfg.worldGuardWildernessKeepItems; + boolean keepXp = cfg.worldGuardWildernessKeepXp; return new RuleResult(keepItems, keepXp, RuleReasons.WG_WILDERNESS); } } } // 4. Check Towny - if (plugin.isTownyEnabled() && plugin.getConfig().getBoolean("integrations.towny.enabled", false)) { + if (plugin.isTownyEnabled() && cfg.townyEnabled) { TownyHook towny = plugin.getTownyHook(); if (towny.isInTown(location)) { boolean isResident = towny.isInOwnTown(player); - String configPath = isResident ? "integrations.towny.in-own-town" : "integrations.towny.in-other-town"; - boolean keepItems = plugin.getConfig().getBoolean(configPath + ".keep-items", isResident); - boolean keepXp = plugin.getConfig().getBoolean(configPath + ".keep-xp", isResident); + boolean keepItems = isResident ? cfg.townyOwnTownKeepItems : cfg.townyOtherTownKeepItems; + boolean keepXp = isResident ? cfg.townyOwnTownKeepXp : cfg.townyOtherTownKeepXp; String reason = isResident ? RuleReasons.TOWNY_OWN : RuleReasons.TOWNY_OTHER; return new RuleResult(keepItems, keepXp, reason); } else { - if (plugin.getConfig().getBoolean("integrations.towny.wilderness.enabled", false)) { - boolean keepItems = plugin.getConfig().getBoolean("integrations.towny.wilderness.keep-items", false); - boolean keepXp = plugin.getConfig().getBoolean("integrations.towny.wilderness.keep-xp", false); + if (cfg.townyWildernessEnabled) { + boolean keepItems = cfg.townyWildernessKeepItems; + boolean keepXp = cfg.townyWildernessKeepXp; return new RuleResult(keepItems, keepXp, RuleReasons.TOWNY_WILDERNESS); } } diff --git a/src/main/java/xyz/superez/dynamickeepinv/rules/WorldTimeRule.java b/src/main/java/xyz/superez/dynamickeepinv/rules/WorldTimeRule.java index fff5f60..08f6837 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/rules/WorldTimeRule.java +++ b/src/main/java/xyz/superez/dynamickeepinv/rules/WorldTimeRule.java @@ -2,29 +2,29 @@ import org.bukkit.World; import org.bukkit.event.entity.PlayerDeathEvent; +import xyz.superez.dynamickeepinv.DKIConfig; import xyz.superez.dynamickeepinv.DynamicKeepInvPlugin; public class WorldTimeRule implements DeathRule { @Override public RuleResult evaluate(PlayerDeathEvent event, DynamicKeepInvPlugin plugin) { + DKIConfig cfg = plugin.getDKIConfig(); World world = event.getEntity().getWorld(); long time = world.getTime(); - long dayStart = plugin.getConfig().getLong("time.day-start", 0); - long nightStart = plugin.getConfig().getLong("time.night-start", 13000); + long dayStart = cfg.dayStart; + long nightStart = cfg.nightStart; boolean isDay = plugin.isTimeInRange(time, dayStart, nightStart); String baseReason = isDay ? RuleReasons.TIME_DAY : RuleReasons.TIME_NIGHT; - String settingPath = isDay ? "rules.day" : "rules.night"; - boolean defaultKeepItems = getWorldKeepInventory(plugin, world, isDay); - boolean keepItems = plugin.getConfig().getBoolean(settingPath + ".keep-items", defaultKeepItems); - boolean keepXp = plugin.getConfig().getBoolean(settingPath + ".keep-xp", defaultKeepItems); + boolean keepItems = getWorldKeepInventory(plugin, cfg, world, isDay); + boolean keepXp = isDay ? cfg.dayKeepXp : cfg.nightKeepXp; return new RuleResult(keepItems, keepXp, baseReason); } - private boolean getWorldKeepInventory(DynamicKeepInvPlugin plugin, World world, boolean isDay) { + private boolean getWorldKeepInventory(DynamicKeepInvPlugin plugin, DKIConfig cfg, World world, boolean isDay) { String worldName = world.getName(); String worldPath = "worlds.overrides." + worldName; @@ -36,9 +36,7 @@ private boolean getWorldKeepInventory(DynamicKeepInvPlugin plugin, World world, } // Fallback to global settings - return isDay - ? plugin.getConfig().getBoolean("rules.day.keep-items", true) - : plugin.getConfig().getBoolean("rules.night.keep-items", false); + return isDay ? cfg.dayKeepItems : cfg.nightKeepItems; } @Override From 0157650ec5440dc00f29998d32e151b29f7fa4c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:24:31 +0000 Subject: [PATCH 2/4] Fix GUI mode config checks and pending XP save condition Agent-Logs-Url: https://github.com/Alexteens24/DynamicKeepInv/sessions/120bce4f-3272-4bd6-ada6-0999a42603f2 Co-authored-by: Alexteens24 <207885348+Alexteens24@users.noreply.github.com> --- .../xyz/superez/dynamickeepinv/DeathListener.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java b/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java index 3d132b3..037fb60 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java +++ b/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java @@ -177,7 +177,7 @@ public void onPlayerDeath(PlayerDeathEvent event) { ); // Only save if there are items worth saving - if (pendingDeath.hasItems() || player.getLevel() > 0) { + if (pendingDeath.hasItems() || player.getTotalExperience() > 0) { pendingManager.addPendingDeath(pendingDeath); // IMPORTANT: Cancel drops and disable keepInventory @@ -518,9 +518,10 @@ private void applyKeepInventorySettings(PlayerDeathEvent event, boolean keepItem @EventHandler(priority = EventPriority.MONITOR) public void onPlayerRespawn(PlayerRespawnEvent event) { + DKIConfig cfg = plugin.getDKIConfig(); // Check if GUI mode is enabled - if (!plugin.getConfig().getBoolean("economy.enabled", false)) return; - if (!"gui".equalsIgnoreCase(plugin.getConfig().getString("economy.mode", "charge-to-keep"))) return; + if (!cfg.economyEnabled) return; + if (cfg.economyMode != EconomyMode.GUI) return; Player player = event.getPlayer(); PendingDeathManager pendingManager = plugin.getPendingDeathManager(); @@ -551,6 +552,7 @@ public void onPlayerRespawn(PlayerRespawnEvent event) { public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); PendingDeathManager pendingManager = plugin.getPendingDeathManager(); + DKIConfig cfg = plugin.getDKIConfig(); // Preload auto-pay settings if manager exists if (pendingManager != null) { @@ -558,8 +560,8 @@ public void onPlayerJoin(PlayerJoinEvent event) { } // Check if GUI mode is enabled - if (!plugin.getConfig().getBoolean("economy.enabled", false)) return; - if (!"gui".equalsIgnoreCase(plugin.getConfig().getString("economy.mode", "charge-to-keep"))) return; + if (!cfg.economyEnabled) return; + if (cfg.economyMode != EconomyMode.GUI) return; if (pendingManager == null) return; From 6b489cc97dc25803330f54c02cf9e5ac19b07b34 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:34:55 +0000 Subject: [PATCH 3/4] Fix pending death handling for storage armor and offhand consistency Agent-Logs-Url: https://github.com/Alexteens24/DynamicKeepInv/sessions/0224c97d-5332-4b52-bb3c-bfc4d1d7bbc7 Co-authored-by: Alexteens24 <207885348+Alexteens24@users.noreply.github.com> --- .../superez/dynamickeepinv/DeathListener.java | 2 +- .../superez/dynamickeepinv/PendingDeath.java | 17 ++++- .../dynamickeepinv/PendingDeathManager.java | 76 ++++++++++++++----- 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java b/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java index 037fb60..b5849f6 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java +++ b/src/main/java/xyz/superez/dynamickeepinv/DeathListener.java @@ -90,7 +90,7 @@ public void onPlayerDeath(PlayerDeathEvent event) { plugin.debug("GUI mode: Saving inventory for confirmation GUI"); // Prepare inventory for saving, filtering out Soulbound items to keep them - ItemStack[] contents = player.getInventory().getContents(); + ItemStack[] contents = player.getInventory().getStorageContents(); ItemStack[] armor = player.getInventory().getArmorContents(); ItemStack offHand = player.getInventory().getItemInOffHand(); diff --git a/src/main/java/xyz/superez/dynamickeepinv/PendingDeath.java b/src/main/java/xyz/superez/dynamickeepinv/PendingDeath.java index f77591c..10780c7 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/PendingDeath.java +++ b/src/main/java/xyz/superez/dynamickeepinv/PendingDeath.java @@ -178,26 +178,37 @@ public long getAgeMs() { * Check if inventory has any items worth saving */ public boolean hasItems() { - // savedInventory comes from PlayerInventory.getContents() which includes armor and offhand for (ItemStack item : savedInventory) { if (item != null && !item.getType().isAir()) { return true; } } - return false; + for (ItemStack item : savedArmor) { + if (item != null && !item.getType().isAir()) { + return true; + } + } + return offhandItem != null && !offhandItem.getType().isAir(); } /** * Count total items in inventory */ public int countItems() { - // savedInventory comes from PlayerInventory.getContents() which includes armor and offhand int count = 0; for (ItemStack item : savedInventory) { if (item != null && !item.getType().isAir()) { count++; } } + for (ItemStack item : savedArmor) { + if (item != null && !item.getType().isAir()) { + count++; + } + } + if (offhandItem != null && !offhandItem.getType().isAir()) { + count++; + } return count; } } diff --git a/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java b/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java index 8040be9..939696a 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java +++ b/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java @@ -306,9 +306,9 @@ private void restoreInventory(Player player, PendingDeath pending) { // Collect any items currently in the player's inventory that might be overwritten List leftovers = new ArrayList<>(); - // Restore main contents (merging to preserve Soulbound/kept items) + // Restore main storage (merging to preserve Soulbound/kept items) ItemStack[] savedContents = pending.getSavedInventory(); - ItemStack[] currentContents = player.getInventory().getContents(); + ItemStack[] currentContents = player.getInventory().getStorageContents(); for (int i = 0; i < savedContents.length && i < currentContents.length; i++) { if (savedContents[i] != null) { @@ -320,10 +320,30 @@ private void restoreInventory(Player player, PendingDeath pending) { } // If savedContents[i] is null, we keep currentContents[i] (which might be a kept soulbound item) } - player.getInventory().setContents(currentContents); + player.getInventory().setStorageContents(currentContents); - // We do not need to restore armor/offhand explicitly as they are included in setContents (from getContents) - // savedContents (from getContents) covers slots 0-40 (including armor and offhand) + // Restore armor slots + ItemStack[] savedArmor = pending.getSavedArmor(); + ItemStack[] currentArmor = player.getInventory().getArmorContents(); + for (int i = 0; i < savedArmor.length && i < currentArmor.length; i++) { + if (savedArmor[i] != null) { + if (currentArmor[i] != null && !currentArmor[i].getType().isAir()) { + leftovers.add(currentArmor[i]); + } + currentArmor[i] = savedArmor[i]; + } + } + player.getInventory().setArmorContents(currentArmor); + + // Restore offhand + ItemStack savedOffhand = pending.getOffhandItem(); + if (savedOffhand != null && !savedOffhand.getType().isAir()) { + ItemStack currentOffhand = player.getInventory().getItemInOffHand(); + if (currentOffhand != null && !currentOffhand.getType().isAir()) { + leftovers.add(currentOffhand); + } + player.getInventory().setItemInOffHand(savedOffhand); + } // Give back any items that were overwritten (e.g. picked up after respawn) if (!leftovers.isEmpty()) { @@ -386,12 +406,9 @@ private void performDrop(Location dropLocation, PendingDeath pending, Player pla // Check for Graves integration (GravesX or AxGraves) if (player != null && (plugin.isGravesXEnabled() || plugin.isAxGravesEnabled())) { List drops = new ArrayList<>(); - - for (ItemStack item : pending.getSavedInventory()) { - if (item != null && !item.getType().isAir() && !hasVanishingCurse(item)) { - drops.add(item); - } - } + appendDroppableItems(drops, pending.getSavedInventory()); + appendDroppableItems(drops, pending.getSavedArmor()); + appendDroppableItem(drops, pending.getOffhandItem()); // Calculate XP int xp = calculateTotalExperience(pending.getSavedLevel(), pending.getSavedExp()); @@ -416,12 +433,9 @@ private void performDrop(Location dropLocation, PendingDeath pending, Player pla } // Drop all items - for (ItemStack item : pending.getSavedInventory()) { - if (item != null && !item.getType().isAir()) { - if (hasVanishingCurse(item)) continue; // Skip vanishing curse - dropLocation.getWorld().dropItemNaturally(dropLocation, item); - } - } + dropItemsNaturally(dropLocation, pending.getSavedInventory()); + dropItemsNaturally(dropLocation, pending.getSavedArmor()); + dropItemNaturally(dropLocation, pending.getOffhandItem()); // Drop XP orbs if (pending.getSavedLevel() > 0) { @@ -464,6 +478,34 @@ private boolean hasVanishingCurse(ItemStack item) { return item.getItemMeta().hasEnchant(org.bukkit.enchantments.Enchantment.VANISHING_CURSE); } + private void appendDroppableItems(List target, ItemStack[] items) { + if (items == null) return; + for (ItemStack item : items) { + appendDroppableItem(target, item); + } + } + + private void appendDroppableItem(List target, ItemStack item) { + if (item == null || item.getType().isAir() || hasVanishingCurse(item)) { + return; + } + target.add(item); + } + + private void dropItemsNaturally(Location dropLocation, ItemStack[] items) { + if (items == null) return; + for (ItemStack item : items) { + dropItemNaturally(dropLocation, item); + } + } + + private void dropItemNaturally(Location dropLocation, ItemStack item) { + if (item == null || item.getType().isAir() || hasVanishingCurse(item)) { + return; + } + dropLocation.getWorld().dropItemNaturally(dropLocation, item); + } + /** * Handle player disconnect - keep pending death in DB for reconnect */ From 8b31a2a4e24b9b89101480139301e4e8ab801546 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Apr 2026 13:43:17 +0000 Subject: [PATCH 4/4] Unify pending XP drop logic and migrate config reads to DKI snapshot Agent-Logs-Url: https://github.com/Alexteens24/DynamicKeepInv/sessions/59edc7c2-e399-4395-81f4-f7e140bd98e4 Co-authored-by: Alexteens24 <207885348+Alexteens24@users.noreply.github.com> --- .../dynamickeepinv/CommandCompleter.java | 4 ++-- .../dynamickeepinv/CommandDispatcher.java | 24 +++++++++++-------- .../dynamickeepinv/DynamicKeepInvPlugin.java | 21 ++++++++-------- .../dynamickeepinv/IntegrationManager.java | 14 ++++++----- .../dynamickeepinv/PendingDeathManager.java | 15 ++++++------ .../xyz/superez/dynamickeepinv/StatsGUI.java | 2 +- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/main/java/xyz/superez/dynamickeepinv/CommandCompleter.java b/src/main/java/xyz/superez/dynamickeepinv/CommandCompleter.java index 36d1a7c..c1772cd 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/CommandCompleter.java +++ b/src/main/java/xyz/superez/dynamickeepinv/CommandCompleter.java @@ -37,8 +37,8 @@ public List onTabComplete(CommandSender sender, Command command, String commands.add("stats"); } - if (plugin.getConfig().getBoolean("economy.enabled", false) - && "gui".equalsIgnoreCase(plugin.getConfig().getString("economy.mode", "charge-to-keep"))) { + DKIConfig cfg = plugin.getDKIConfig(); + if (cfg.economyEnabled && cfg.economyMode == EconomyMode.GUI) { commands.add("confirm"); commands.add("autopay"); } diff --git a/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java b/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java index 616d21f..020cb05 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java +++ b/src/main/java/xyz/superez/dynamickeepinv/CommandDispatcher.java @@ -74,6 +74,7 @@ public boolean dispatch(CommandSender sender, Command command, String label, Str case "enable": plugin.getConfig().set("enabled", true); plugin.saveConfig(); + plugin.refreshDKIConfig(); plugin.startChecking(); sender.sendMessage(plugin.parseMessage(plugin.getMessage("commands.enabled"))); break; @@ -81,6 +82,7 @@ public boolean dispatch(CommandSender sender, Command command, String label, Str case "disable": plugin.getConfig().set("enabled", false); plugin.saveConfig(); + plugin.refreshDKIConfig(); plugin.stopChecking(true); sender.sendMessage(plugin.parseMessage(plugin.getMessage("commands.disabled"))); break; @@ -89,6 +91,7 @@ public boolean dispatch(CommandSender sender, Command command, String label, Str boolean newState = !plugin.getConfig().getBoolean("enabled", true); plugin.getConfig().set("enabled", newState); plugin.saveConfig(); + plugin.refreshDKIConfig(); if (newState) { plugin.startChecking(); sender.sendMessage(plugin.parseMessage(plugin.getMessage("commands.enabled"))); @@ -157,8 +160,8 @@ private boolean handleConfirmCommand(CommandSender sender) { return true; } - if (!plugin.getConfig().getBoolean("economy.enabled", false) - || !"gui".equalsIgnoreCase(plugin.getConfig().getString("economy.mode", "charge-to-keep"))) { + DKIConfig cfg = plugin.getDKIConfig(); + if (!cfg.economyEnabled || cfg.economyMode != EconomyMode.GUI) { sender.sendMessage(plugin.parseMessage("&cDeath confirmation GUI is not enabled! Set economy mode to 'gui' in config.")); return true; } @@ -184,8 +187,8 @@ private boolean handleAutoPayCommand(CommandSender sender) { return true; } - if (!plugin.getConfig().getBoolean("economy.enabled", false) - || !"gui".equalsIgnoreCase(plugin.getConfig().getString("economy.mode", "charge-to-keep"))) { + DKIConfig cfg = plugin.getDKIConfig(); + if (!cfg.economyEnabled || cfg.economyMode != EconomyMode.GUI) { sender.sendMessage(plugin.parseMessage("&cAuto-pay requires GUI economy mode! Set economy mode to 'gui' in config.")); return true; } @@ -290,15 +293,16 @@ private void handleTestCommand(CommandSender sender, String[] args) { } private void showStatus(CommandSender sender) { + DKIConfig cfg = plugin.getDKIConfig(); sender.sendMessage(plugin.parseMessage(plugin.getMessage("status.header"))); sender.sendMessage(plugin.parseMessage(plugin.getMessage("status.enabled") - .replace("{value}", String.valueOf(plugin.getConfig().getBoolean("enabled", true))))); + .replace("{value}", String.valueOf(cfg.enabled)))); sender.sendMessage(plugin.parseMessage(plugin.getMessage("status.keep-inv-day") - .replace("{value}", String.valueOf(plugin.getConfig().getBoolean("rules.day.keep-items", true))))); + .replace("{value}", String.valueOf(cfg.dayKeepItems)))); sender.sendMessage(plugin.parseMessage(plugin.getMessage("status.keep-inv-night") - .replace("{value}", String.valueOf(plugin.getConfig().getBoolean("rules.night.keep-items", false))))); + .replace("{value}", String.valueOf(cfg.nightKeepItems)))); sender.sendMessage(plugin.parseMessage(plugin.getMessage("status.check-interval") - .replace("{value}", String.valueOf(plugin.getConfig().getInt("check-interval", 100))))); + .replace("{value}", String.valueOf(cfg.checkInterval)))); // Rule chain summary sender.sendMessage(plugin.parseMessage("&7--- &eActive Rule Chain &7---")); @@ -315,8 +319,8 @@ private void showStatus(CommandSender sender) { } sender.sendMessage(plugin.parseMessage(plugin.getMessage("status.world-header"))); - long dayStart = plugin.getConfig().getLong("time.day-start", 0); - long nightStart = plugin.getConfig().getLong("time.night-start", 13000); + long dayStart = cfg.dayStart; + long nightStart = cfg.nightStart; for (World world : Bukkit.getWorlds()) { long time = world.getTime(); boolean isDay = plugin.isTimeInRange(time, dayStart, nightStart); diff --git a/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java b/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java index 46c6f06..febadba 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java +++ b/src/main/java/xyz/superez/dynamickeepinv/DynamicKeepInvPlugin.java @@ -89,8 +89,7 @@ public void onEnable() { getCommand("dynamickeepinv").setTabCompleter(new CommandCompleter(this)); // Initialize GUI economy mode components - if (getConfig().getBoolean("economy.enabled", false) - && "gui".equalsIgnoreCase(getConfig().getString("economy.mode", "charge-to-keep"))) { + if (dkiConfig.economyEnabled && dkiConfig.economyMode == EconomyMode.GUI) { pendingDeathManager = new PendingDeathManager(this); deathConfirmGUI = new DeathConfirmGUI(this); getLogger().info("Death confirmation GUI mode enabled!"); @@ -104,9 +103,9 @@ public void onEnable() { getLogger().info("DynamicKeepInv is starting... (Platform: " + (isFolia ? "Folia" : "Paper/Spigot") + ")"); - if (getConfig().getBoolean("enabled", true)) { + if (dkiConfig.enabled) { startChecking(); - List enabledWorlds = getConfig().getStringList("worlds.enabled"); + List enabledWorlds = dkiConfig.enabledWorlds; if (!enabledWorlds.isEmpty()) { getLogger().info("Enabled worlds: " + String.join(", ", enabledWorlds)); } else { @@ -146,7 +145,7 @@ public void handleWorldUnload(World world) { } public EconomyManager getEconomyManager() { - if (!getConfig().getBoolean("economy.enabled", false)) { + if (!dkiConfig.economyEnabled) { return economyManager; } @@ -261,7 +260,7 @@ public Component parseMessage(String message) { void startChecking() { stopChecking(false); - int interval = getConfig().getInt("check-interval", 100); + int interval = dkiConfig.checkInterval; if (isFolia) { GlobalRegionScheduler scheduler = Bukkit.getGlobalRegionScheduler(); @@ -501,7 +500,7 @@ private void cleanupStatsSystem() { void reloadStatsSystem() { cleanupStatsSystem(); - if (getConfig().getBoolean("stats.enabled", true)) { + if (dkiConfig.statsEnabled) { statsManager = new StatsManager(this); statsGUI = new StatsGUI(this); statsListener = new StatsListener(this); @@ -523,8 +522,7 @@ void reloadPendingDeathManager() { } // Initialize if GUI mode enabled - if (getConfig().getBoolean("economy.enabled", false) - && "gui".equalsIgnoreCase(getConfig().getString("economy.mode", "charge-to-keep"))) { + if (dkiConfig.economyEnabled && dkiConfig.economyMode == EconomyMode.GUI) { pendingDeathManager = new PendingDeathManager(this); deathConfirmGUI = new DeathConfirmGUI(this); getLogger().info("Death confirmation GUI mode enabled!"); @@ -547,7 +545,8 @@ public boolean isTimeInRange(long time, long rangeStart, long rangeEnd) { } public boolean isDayTime(long time) { - return isTimeInRange(time, getConfig().getLong("time.day-start", 0), getConfig().getLong("time.night-start", 13000)); + DKIConfig cfg = dkiConfig; + return isTimeInRange(time, cfg.dayStart, cfg.nightStart); } private boolean getWorldKeepInventory(World world, boolean isDay, boolean globalKeepInvDay, boolean globalKeepInvNight) { @@ -566,7 +565,7 @@ private boolean getWorldKeepInventory(World world, boolean isDay, boolean global } public void debug(String message) { - if (getConfig().getBoolean("debug", false)) { + if (dkiConfig.debug) { getLogger().log(Level.INFO, "[DEBUG] " + message); } } diff --git a/src/main/java/xyz/superez/dynamickeepinv/IntegrationManager.java b/src/main/java/xyz/superez/dynamickeepinv/IntegrationManager.java index 2b9271b..da374df 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/IntegrationManager.java +++ b/src/main/java/xyz/superez/dynamickeepinv/IntegrationManager.java @@ -26,31 +26,33 @@ public IntegrationManager(DynamicKeepInvPlugin plugin) { } public void reload() { - if (plugin.getConfig().getBoolean("integrations.lands.enabled", false)) { + DKIConfig cfg = plugin.getDKIConfig(); + + if (cfg.landsEnabled) { landsHook = new LandsHook(plugin); } else { landsHook = null; } - if (plugin.getConfig().getBoolean("integrations.griefprevention.enabled", false)) { + if (cfg.gpEnabled) { griefPreventionHook = new GriefPreventionHook(plugin); } else { griefPreventionHook = null; } - if (plugin.getConfig().getBoolean("integrations.worldguard.enabled", false)) { + if (cfg.worldGuardEnabled) { worldGuardHook = new WorldGuardHook(plugin); } else { worldGuardHook = null; } - if (plugin.getConfig().getBoolean("integrations.towny.enabled", false)) { + if (cfg.townyEnabled) { townyHook = new TownyHook(plugin); } else { townyHook = null; } - if (plugin.getConfig().getBoolean("integrations.gravesx.enabled", false)) { + if (cfg.gravesXEnabled) { if (Bukkit.getPluginManager().getPlugin("GravesX") != null) { gravesXHook = new GravesXHook(plugin); if (!gravesXHook.setup()) { @@ -64,7 +66,7 @@ public void reload() { gravesXHook = null; } - if (plugin.getConfig().getBoolean("integrations.axgraves.enabled", false)) { + if (cfg.axGravesEnabled) { if (Bukkit.getPluginManager().getPlugin("AxGraves") != null) { axGravesHook = new AxGravesHook(plugin); if (!axGravesHook.setup()) { diff --git a/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java b/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java index 939696a..5a01352 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java +++ b/src/main/java/xyz/superez/dynamickeepinv/PendingDeathManager.java @@ -53,8 +53,9 @@ public PendingDeathManager(DynamicKeepInvPlugin plugin) { } private void loadConfig() { - timeoutMs = plugin.getConfig().getLong("economy.gui.timeout", 30) * 1000L; - expireMs = plugin.getConfig().getLong("economy.gui.expire-time", 300) * 1000L; + DKIConfig cfg = plugin.getDKIConfig(); + timeoutMs = cfg.guiTimeoutSec * 1000L; + expireMs = cfg.guiExpireSec * 1000L; } private void initDatabase() { @@ -403,6 +404,8 @@ private void dropItemsForPendingDeath(PendingDeath pending) { } private void performDrop(Location dropLocation, PendingDeath pending, Player player) { + int xp = calculateTotalExperience(pending.getSavedLevel(), pending.getSavedExp()); + // Check for Graves integration (GravesX or AxGraves) if (player != null && (plugin.isGravesXEnabled() || plugin.isAxGravesEnabled())) { List drops = new ArrayList<>(); @@ -410,9 +413,6 @@ private void performDrop(Location dropLocation, PendingDeath pending, Player pla appendDroppableItems(drops, pending.getSavedArmor()); appendDroppableItem(drops, pending.getOffhandItem()); - // Calculate XP - int xp = calculateTotalExperience(pending.getSavedLevel(), pending.getSavedExp()); - if (!drops.isEmpty() || xp > 0) { // Try GravesX if (plugin.isGravesXEnabled()) { @@ -438,10 +438,9 @@ private void performDrop(Location dropLocation, PendingDeath pending, Player pla dropItemNaturally(dropLocation, pending.getOffhandItem()); // Drop XP orbs - if (pending.getSavedLevel() > 0) { - int expToDrop = Math.min(pending.getSavedLevel() * 7, 100); + if (xp > 0) { dropLocation.getWorld().spawn(dropLocation, org.bukkit.entity.ExperienceOrb.class, - orb -> orb.setExperience(expToDrop)); + orb -> orb.setExperience(xp)); } } diff --git a/src/main/java/xyz/superez/dynamickeepinv/StatsGUI.java b/src/main/java/xyz/superez/dynamickeepinv/StatsGUI.java index 07c529b..c44ee8a 100644 --- a/src/main/java/xyz/superez/dynamickeepinv/StatsGUI.java +++ b/src/main/java/xyz/superez/dynamickeepinv/StatsGUI.java @@ -113,7 +113,7 @@ private void openGUI(Player viewer, UUID targetUUID, String targetName) { "ยง7Percentage of deaths saved"); gui.setItem(25, rateItem); - if (plugin.getConfig().getBoolean("economy.enabled", false)) { + if (plugin.getDKIConfig().economyEnabled) { double totalPaid = stats.getTotalEconomyPaid(targetUUID); int paymentCount = stats.getEconomyPaymentCount(targetUUID); ItemStack economyItem = createItem(Material.GOLD_INGOT,