From 384b76d8c111743df6b72ec6ddb50f7e4032fab4 Mon Sep 17 00:00:00 2001 From: Worive <13164341+Worive@users.noreply.github.com> Date: Sat, 30 Aug 2025 10:50:50 +0200 Subject: [PATCH 1/5] Fix Backpack slot usage tooltip allways displaying 0/0 As now the server keeps all the data about the backpacks inventory, the client will perform a request to the server to get the usage information. Fix GTNewHorizons/GT-New-Horizons-Modpack#20998 --- .../container/ContainerAdvanced.java | 6 + .../backpack/item/ItemBackpackBase.java | 21 +- .../backpack/misc/BackpackUsageCache.java | 190 ++++++++++++++++++ .../network/PacketHandlerBackpack.java | 5 + .../network/message/MessageBackpackInfo.java | 48 +++++ .../message/MessageBackpackInfoRequest.java | 49 +++++ 6 files changed, 313 insertions(+), 6 deletions(-) create mode 100644 src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java create mode 100644 src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfo.java create mode 100644 src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfoRequest.java diff --git a/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java b/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java index 800adb85..b1517aee 100644 --- a/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java +++ b/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java @@ -15,6 +15,7 @@ import de.eydamos.backpack.inventory.ISaveableInventory; import de.eydamos.backpack.inventory.slot.SlotCraftingAdvanced; import de.eydamos.backpack.inventory.slot.SlotPhantom; +import de.eydamos.backpack.misc.BackpackUsageCache; import de.eydamos.backpack.saves.BackpackSave; import de.eydamos.backpack.saves.PlayerSave; import de.eydamos.backpack.util.BackpackUtil; @@ -79,6 +80,11 @@ public void onContainerClosed(EntityPlayer entityPlayer) { if (inventory != null) { inventory.closeInventory(); } + + if (backpackSave != null) { + BackpackUsageCache.invalidate(backpackSave.getUUID()); + } + super.onContainerClosed(entityPlayer); } diff --git a/src/main/java/de/eydamos/backpack/item/ItemBackpackBase.java b/src/main/java/de/eydamos/backpack/item/ItemBackpackBase.java index cf102ca5..6f062aef 100644 --- a/src/main/java/de/eydamos/backpack/item/ItemBackpackBase.java +++ b/src/main/java/de/eydamos/backpack/item/ItemBackpackBase.java @@ -8,7 +8,6 @@ import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.StatCollector; import net.minecraft.world.World; @@ -19,6 +18,7 @@ import cpw.mods.fml.relauncher.SideOnly; import de.eydamos.backpack.helper.GuiHelper; import de.eydamos.backpack.inventory.InventoryBackpack; +import de.eydamos.backpack.misc.BackpackUsageCache; import de.eydamos.backpack.misc.ConfigurationBackpack; import de.eydamos.backpack.misc.Constants; import de.eydamos.backpack.misc.Localizations; @@ -184,11 +184,20 @@ public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List EnumChatFormatting.YELLOW + StatCollector.translateToLocal(Localizations.TIER) + " " + (itemStack.getItemDamage() / 100 + 1)); - BackpackSave backpackSave = new BackpackSave(itemStack); - NBTTagList itemList = backpackSave.getInventory(Constants.NBT.INVENTORY_BACKPACK); - int used = itemList.tagCount(); - int size = backpackSave.getSize(); - information.add(used + "/" + size + ' ' + StatCollector.translateToLocal(Localizations.SLOTS_USED)); + + if (itemStack.stackTagCompound == null) return; + + String uuid = itemStack.stackTagCompound.getString(Constants.NBT.UID); + if (uuid == null) return; + + BackpackUsageCache.BackpackSlotUsageInfo info = BackpackUsageCache.getBackpackInfo(uuid); + + if (info != null) { + String slotsText = StatCollector.translateToLocal(Localizations.SLOTS_USED); + information.add(info.usedSlots + "/" + info.totalSlots + ' ' + slotsText); + } else { + BackpackUsageCache.requestBackpackInfo(uuid); + } } } else { information.add(StatCollector.translateToLocal(Localizations.MORE_INFORMATION)); diff --git a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java new file mode 100644 index 00000000..f60875a8 --- /dev/null +++ b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java @@ -0,0 +1,190 @@ +package de.eydamos.backpack.misc; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import de.eydamos.backpack.Backpack; +import de.eydamos.backpack.network.message.MessageBackpackInfoRequest; + +@SideOnly(Side.CLIENT) +public class BackpackUsageCache { + + private static final Map cache = new ConcurrentHashMap<>(); + private static final Map requestTimestamps = new ConcurrentHashMap<>(); + + // Configuration constants + private static final long CACHE_DURATION_MS = 60000; // 1 minute + private static final long REQUEST_THROTTLE_MS = 1000; // 1 second throttle between requests + private static final int MAX_CACHE_SIZE = 100; // Prevent memory leaks + + private static final ReadWriteLock cacheLock = new ReentrantReadWriteLock(); + + private static class CacheEntry { + + public final BackpackSlotUsageInfo info; + public final long timestamp; + public final boolean isValid; + + public CacheEntry(BackpackSlotUsageInfo info, long timestamp, boolean isValid) { + this.info = info; + this.timestamp = timestamp; + this.isValid = isValid; + } + + public boolean isExpired() { + return (System.currentTimeMillis() - timestamp) > CACHE_DURATION_MS; + } + } + + public static class BackpackSlotUsageInfo { + + public final int usedSlots; + public final int totalSlots; + + public BackpackSlotUsageInfo(int used, int total) { + if (used < 0 || total < 0 || used > total) { + throw new IllegalArgumentException("Invalid backpack slot values: used=" + used + ", total=" + total); + } + this.usedSlots = used; + this.totalSlots = total; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + BackpackSlotUsageInfo that = (BackpackSlotUsageInfo) obj; + return usedSlots == that.usedSlots && totalSlots == that.totalSlots; + } + + @Override + public int hashCode() { + return 31 * usedSlots + totalSlots; + } + + @Override + public String toString() { + return "BackpackInfo{used=" + usedSlots + ", total=" + totalSlots + "}"; + } + } + + /** + * Updates backpack information in the cache + * + * @param uuid The backpack UUID + * @param used Number of used slots + * @param total Total number of slots + */ + public static void updateBackpackInfo(String uuid, int used, int total) { + if (uuid == null || uuid.trim().isEmpty()) { + throw new IllegalArgumentException("UUID cannot be null or empty"); + } + + BackpackSlotUsageInfo info = new BackpackSlotUsageInfo(used, total); + long currentTime = System.currentTimeMillis(); + CacheEntry entry = new CacheEntry(info, currentTime, true); + + cacheLock.readLock().lock(); + try { + cache.put(uuid, entry); + + if (cache.size() > MAX_CACHE_SIZE) { + evictOldestEntries(); + } + } finally { + cacheLock.readLock().unlock(); + } + } + + /** + * Retrieves backpack information from cache + * + * @param uuid The backpack UUID + * @return BackpackInfo if valid and not expired, null otherwise + */ + public static BackpackSlotUsageInfo getBackpackInfo(String uuid) { + if (uuid == null || uuid.trim().isEmpty()) { + return null; + } + + CacheEntry entry = cache.get(uuid); + if (entry == null || !entry.isValid || entry.isExpired()) { + if (entry != null && entry.isExpired()) { + invalidate(uuid); + } + return null; + } + + return entry.info; + } + + /** + * Requests backpack information with throttling + * + * @param uuid The player UUID + */ + public static void requestBackpackInfo(String uuid) { + if (uuid == null || uuid.trim().isEmpty()) { + throw new IllegalArgumentException("UUID cannot be null or empty"); + } + + long currentTime = System.currentTimeMillis(); + Long lastRequestTime = requestTimestamps.get(uuid); + + // Check throttling + if (lastRequestTime != null && (currentTime - lastRequestTime) < REQUEST_THROTTLE_MS) { + return; + } + + BackpackSlotUsageInfo cachedInfo = getBackpackInfo(uuid); + if (cachedInfo != null) { + return; + } + + Backpack.packetHandler.networkWrapper.sendToServer(new MessageBackpackInfoRequest(uuid)); + requestTimestamps.put(uuid, currentTime); + + } + + /** + * Invalidates a specific UUID from the cache + * + * @param uuid The player UUID to invalidate + */ + public static void invalidate(String uuid) { + if (uuid == null || uuid.trim().isEmpty()) { + return; + } + + cache.remove(uuid); + requestTimestamps.remove(uuid); + } + + /** + * Evicts oldest entries when cache size exceeds limit + */ + private static void evictOldestEntries() { + cacheLock.writeLock().lock(); + try { + if (cache.size() <= MAX_CACHE_SIZE) { + return; + } + + // Find oldest entries to evict (evict 10% of cache) + int entriesToEvict = Math.max(1, cache.size() / 10); + + cache.entrySet().stream().sorted((e1, e2) -> Long.compare(e1.getValue().timestamp, e2.getValue().timestamp)) + .limit(entriesToEvict).map(Map.Entry::getKey).forEach(key -> { + cache.remove(key); + requestTimestamps.remove(key); + }); + + } finally { + cacheLock.writeLock().unlock(); + } + } +} diff --git a/src/main/java/de/eydamos/backpack/network/PacketHandlerBackpack.java b/src/main/java/de/eydamos/backpack/network/PacketHandlerBackpack.java index 1e2e2d79..0a0d3a1b 100644 --- a/src/main/java/de/eydamos/backpack/network/PacketHandlerBackpack.java +++ b/src/main/java/de/eydamos/backpack/network/PacketHandlerBackpack.java @@ -4,6 +4,8 @@ import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; import de.eydamos.backpack.misc.Constants; +import de.eydamos.backpack.network.message.MessageBackpackInfo; +import de.eydamos.backpack.network.message.MessageBackpackInfoRequest; import de.eydamos.backpack.network.message.MessageGuiCommand; import de.eydamos.backpack.network.message.MessageOpenBackpack; import de.eydamos.backpack.network.message.MessageOpenGui; @@ -23,10 +25,13 @@ public void initialise() { networkWrapper.registerMessage(MessageGuiCommand.class, MessageGuiCommand.class, 2, Side.SERVER); networkWrapper.registerMessage(MessagePersonalBackpack.class, MessagePersonalBackpack.class, 3, Side.SERVER); networkWrapper.registerMessage(MessageRecipe.class, MessageRecipe.class, 4, Side.SERVER); + networkWrapper + .registerMessage(MessageBackpackInfoRequest.class, MessageBackpackInfoRequest.class, 5, Side.SERVER); // these packages are send from the server to the client networkWrapper.registerMessage(MessageOpenPersonalSlot.class, MessageOpenPersonalSlot.class, 10, Side.CLIENT); networkWrapper.registerMessage(MessageOpenBackpack.class, MessageOpenBackpack.class, 11, Side.CLIENT); networkWrapper.registerMessage(MessagePersonalBackpack.class, MessagePersonalBackpack.class, 12, Side.CLIENT); + networkWrapper.registerMessage(MessageBackpackInfo.class, MessageBackpackInfo.class, 13, Side.CLIENT); } } diff --git a/src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfo.java b/src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfo.java new file mode 100644 index 00000000..6cfa3838 --- /dev/null +++ b/src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfo.java @@ -0,0 +1,48 @@ +package de.eydamos.backpack.network.message; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import de.eydamos.backpack.misc.BackpackUsageCache; +import io.netty.buffer.ByteBuf; + +/** + * Used to pass to the client the slot usage information for a specific backpack. + */ +public class MessageBackpackInfo implements IMessage, IMessageHandler { + + private String backpackUUID; + private int usedSlots; + private int totalSlots; + + public MessageBackpackInfo() {} + + public MessageBackpackInfo(String uuid, int used, int total) { + this.backpackUUID = uuid; + this.usedSlots = used; + this.totalSlots = total; + } + + @Override + public void fromBytes(ByteBuf buf) { + int length = buf.readInt(); + this.backpackUUID = new String(buf.readBytes(length).array()); + this.usedSlots = buf.readInt(); + this.totalSlots = buf.readInt(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(backpackUUID.length()); + buf.writeBytes(backpackUUID.getBytes()); + buf.writeInt(usedSlots); + buf.writeInt(totalSlots); + } + + @Override + public IMessage onMessage(MessageBackpackInfo message, MessageContext ctx) { + BackpackUsageCache.updateBackpackInfo(message.backpackUUID, message.usedSlots, message.totalSlots); + return null; + } + +} diff --git a/src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfoRequest.java b/src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfoRequest.java new file mode 100644 index 00000000..b8bd83dd --- /dev/null +++ b/src/main/java/de/eydamos/backpack/network/message/MessageBackpackInfoRequest.java @@ -0,0 +1,49 @@ +package de.eydamos.backpack.network.message; + +import net.minecraft.nbt.NBTTagCompound; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import de.eydamos.backpack.Backpack; +import de.eydamos.backpack.misc.Constants; +import de.eydamos.backpack.saves.BackpackSave; +import io.netty.buffer.ByteBuf; + +/** + * Request from the client to ask the server to send him the slot usage information about a backpack. + */ +public class MessageBackpackInfoRequest implements IMessage, IMessageHandler { + + private String backpackUUID; + + public MessageBackpackInfoRequest() {} + + public MessageBackpackInfoRequest(String uuid) { + this.backpackUUID = uuid; + } + + @Override + public void fromBytes(ByteBuf buf) { + int length = buf.readInt(); + this.backpackUUID = new String(buf.readBytes(length).array()); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(backpackUUID.length()); + buf.writeBytes(backpackUUID.getBytes()); + } + + @Override + public IMessage onMessage(MessageBackpackInfoRequest message, MessageContext ctx) { + NBTTagCompound backpack = Backpack.saveFileHandler.loadBackpack(message.backpackUUID); + + BackpackSave backpackSave = new BackpackSave(backpack); + + int used = backpackSave.getInventory(Constants.NBT.INVENTORY_BACKPACK).tagCount(); + int total = backpackSave.getSize(); + + return new MessageBackpackInfo(message.backpackUUID, used, total); + } +} From d6f02224e03de6fc8fa66ef39f0e1229a733ea72 Mon Sep 17 00:00:00 2001 From: Worive <13164341+Worive@users.noreply.github.com> Date: Sun, 21 Sep 2025 18:42:03 +0200 Subject: [PATCH 2/5] Remove usage of isValid --- .../eydamos/backpack/misc/BackpackUsageCache.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java index f60875a8..6b1b91f8 100644 --- a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java +++ b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java @@ -27,12 +27,10 @@ private static class CacheEntry { public final BackpackSlotUsageInfo info; public final long timestamp; - public final boolean isValid; - public CacheEntry(BackpackSlotUsageInfo info, long timestamp, boolean isValid) { + public CacheEntry(BackpackSlotUsageInfo info, long timestamp) { this.info = info; this.timestamp = timestamp; - this.isValid = isValid; } public boolean isExpired() { @@ -112,10 +110,13 @@ public static BackpackSlotUsageInfo getBackpackInfo(String uuid) { } CacheEntry entry = cache.get(uuid); - if (entry == null || !entry.isValid || entry.isExpired()) { - if (entry != null && entry.isExpired()) { - invalidate(uuid); - } + + if (entry == null) { + return null; + } + + if (entry.isExpired()) { + invalidate(uuid); return null; } From 588573b245938009542265163607ee58fc9940a5 Mon Sep 17 00:00:00 2001 From: Worive <13164341+Worive@users.noreply.github.com> Date: Sun, 21 Sep 2025 18:43:19 +0200 Subject: [PATCH 3/5] Fix cacheLock and improper atomic operations --- .../backpack/misc/BackpackUsageCache.java | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java index 6b1b91f8..fa05316d 100644 --- a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java +++ b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java @@ -1,5 +1,6 @@ package de.eydamos.backpack.misc; +import java.util.Comparator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReadWriteLock; @@ -21,6 +22,7 @@ public class BackpackUsageCache { private static final long REQUEST_THROTTLE_MS = 1000; // 1 second throttle between requests private static final int MAX_CACHE_SIZE = 100; // Prevent memory leaks + // Lock is only needed for the compound "put-and-evict" operation private static final ReadWriteLock cacheLock = new ReentrantReadWriteLock(); private static class CacheEntry { @@ -84,9 +86,10 @@ public static void updateBackpackInfo(String uuid, int used, int total) { BackpackSlotUsageInfo info = new BackpackSlotUsageInfo(used, total); long currentTime = System.currentTimeMillis(); - CacheEntry entry = new CacheEntry(info, currentTime, true); + CacheEntry entry = new CacheEntry(info, currentTime); - cacheLock.readLock().lock(); + // A write lock is required here to make the "put-and-evict" operation atomic. + cacheLock.writeLock().lock(); try { cache.put(uuid, entry); @@ -94,7 +97,7 @@ public static void updateBackpackInfo(String uuid, int used, int total) { evictOldestEntries(); } } finally { - cacheLock.readLock().unlock(); + cacheLock.writeLock().unlock(); } } @@ -130,25 +133,24 @@ public static BackpackSlotUsageInfo getBackpackInfo(String uuid) { */ public static void requestBackpackInfo(String uuid) { if (uuid == null || uuid.trim().isEmpty()) { - throw new IllegalArgumentException("UUID cannot be null or empty"); - } - - long currentTime = System.currentTimeMillis(); - Long lastRequestTime = requestTimestamps.get(uuid); - - // Check throttling - if (lastRequestTime != null && (currentTime - lastRequestTime) < REQUEST_THROTTLE_MS) { return; } - BackpackSlotUsageInfo cachedInfo = getBackpackInfo(uuid); - if (cachedInfo != null) { + if (getBackpackInfo(uuid) != null) { return; } - Backpack.packetHandler.networkWrapper.sendToServer(new MessageBackpackInfoRequest(uuid)); - requestTimestamps.put(uuid, currentTime); + long currentTime = System.currentTimeMillis(); + + requestTimestamps.compute(uuid, (key, lastRequestTime) -> { + // Throttle check + if (lastRequestTime != null && (currentTime - lastRequestTime) < REQUEST_THROTTLE_MS) { + return lastRequestTime; + } + Backpack.packetHandler.networkWrapper.sendToServer(new MessageBackpackInfoRequest(key)); + return currentTime; + }); } /** @@ -166,26 +168,22 @@ public static void invalidate(String uuid) { } /** - * Evicts oldest entries when cache size exceeds limit + * Evicts the oldest entries when cache size exceeds the limit. WARNING: This method must be called from within a + * write-locked context. */ private static void evictOldestEntries() { - cacheLock.writeLock().lock(); - try { - if (cache.size() <= MAX_CACHE_SIZE) { - return; - } - - // Find oldest entries to evict (evict 10% of cache) - int entriesToEvict = Math.max(1, cache.size() / 10); + // This check is a safeguard, but the caller should ensure the lock is held. + if (cache.size() <= MAX_CACHE_SIZE) { + return; + } - cache.entrySet().stream().sorted((e1, e2) -> Long.compare(e1.getValue().timestamp, e2.getValue().timestamp)) - .limit(entriesToEvict).map(Map.Entry::getKey).forEach(key -> { - cache.remove(key); - requestTimestamps.remove(key); - }); + // Find the oldest entries to evict (evict 10% of cache) + int entriesToEvict = Math.max(1, cache.size() / 10); - } finally { - cacheLock.writeLock().unlock(); - } + cache.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.comparingLong(e -> e.timestamp))) + .limit(entriesToEvict).map(Map.Entry::getKey).forEach(key -> { + cache.remove(key); + requestTimestamps.remove(key); + }); } } From d00e66aaaeea3d7d99f6fb37d05b0cd788d4dd7e Mon Sep 17 00:00:00 2001 From: Worive <13164341+Worive@users.noreply.github.com> Date: Sun, 21 Sep 2025 18:44:06 +0200 Subject: [PATCH 4/5] Update docs --- .../eydamos/backpack/misc/BackpackUsageCache.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java index fa05316d..657fe7a7 100644 --- a/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java +++ b/src/main/java/de/eydamos/backpack/misc/BackpackUsageCache.java @@ -74,7 +74,7 @@ public String toString() { /** * Updates backpack information in the cache - * + * * @param uuid The backpack UUID * @param used Number of used slots * @param total Total number of slots @@ -102,10 +102,10 @@ public static void updateBackpackInfo(String uuid, int used, int total) { } /** - * Retrieves backpack information from cache - * + * Retrieves backpack information from cache. If an entry is found to be expired, it is removed + * * @param uuid The backpack UUID - * @return BackpackInfo if valid and not expired, null otherwise + * @return BackpackSlotUsageInfo if valid and not expired, null otherwise */ public static BackpackSlotUsageInfo getBackpackInfo(String uuid) { if (uuid == null || uuid.trim().isEmpty()) { @@ -127,7 +127,8 @@ public static BackpackSlotUsageInfo getBackpackInfo(String uuid) { } /** - * Requests backpack information with throttling + * Requests backpack information from the server if not present in the cache, respecting a throttle to prevent + * spamming requests. * * @param uuid The player UUID */ @@ -155,7 +156,7 @@ public static void requestBackpackInfo(String uuid) { /** * Invalidates a specific UUID from the cache - * + * * @param uuid The player UUID to invalidate */ public static void invalidate(String uuid) { From 190dffc911e6ddf5a2ac032417fe23e26dccba72 Mon Sep 17 00:00:00 2001 From: Worive <13164341+Worive@users.noreply.github.com> Date: Fri, 3 Oct 2025 07:07:19 +0200 Subject: [PATCH 5/5] Fix server using clientOnly code --- .../backpack/inventory/container/ContainerAdvanced.java | 4 ++-- src/main/java/de/eydamos/backpack/proxy/ClientProxy.java | 6 ++++++ src/main/java/de/eydamos/backpack/proxy/CommonProxy.java | 5 +++++ src/main/java/de/eydamos/backpack/proxy/IProxy.java | 2 ++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java b/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java index 702be5c3..36965918 100644 --- a/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java +++ b/src/main/java/de/eydamos/backpack/inventory/container/ContainerAdvanced.java @@ -12,10 +12,10 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import de.eydamos.backpack.Backpack; import de.eydamos.backpack.inventory.ISaveableInventory; import de.eydamos.backpack.inventory.slot.SlotCraftingAdvanced; import de.eydamos.backpack.inventory.slot.SlotPhantom; -import de.eydamos.backpack.misc.BackpackUsageCache; import de.eydamos.backpack.saves.BackpackSave; import de.eydamos.backpack.saves.PlayerSave; import de.eydamos.backpack.util.BackpackUtil; @@ -82,7 +82,7 @@ public void onContainerClosed(EntityPlayer entityPlayer) { } if (backpackSave != null) { - BackpackUsageCache.invalidate(backpackSave.getUUID()); + Backpack.proxy.invalidateBackpackCache(backpackSave.getUUID()); } super.onContainerClosed(entityPlayer); diff --git a/src/main/java/de/eydamos/backpack/proxy/ClientProxy.java b/src/main/java/de/eydamos/backpack/proxy/ClientProxy.java index 3f3ed0e0..a086688a 100644 --- a/src/main/java/de/eydamos/backpack/proxy/ClientProxy.java +++ b/src/main/java/de/eydamos/backpack/proxy/ClientProxy.java @@ -12,6 +12,7 @@ import de.eydamos.backpack.gui.GuiWorkbenchBackpack; import de.eydamos.backpack.handler.EventHandlerClientOnly; import de.eydamos.backpack.handler.KeyInputHandler; +import de.eydamos.backpack.misc.BackpackUsageCache; import de.eydamos.backpack.misc.ConfigurationBackpack; import de.eydamos.backpack.misc.Constants; import de.eydamos.backpack.nei.OverlayHandlerBackpack; @@ -50,4 +51,9 @@ public void addNeiSupport() { FMLLog.log(Constants.MOD_ID, Level.INFO, "[Backpacks] NEI Support couldn't be enabled"); } } + + @Override + public void invalidateBackpackCache(String uuid) { + BackpackUsageCache.invalidate(uuid); + } } diff --git a/src/main/java/de/eydamos/backpack/proxy/CommonProxy.java b/src/main/java/de/eydamos/backpack/proxy/CommonProxy.java index 1fdb0f19..55059a37 100644 --- a/src/main/java/de/eydamos/backpack/proxy/CommonProxy.java +++ b/src/main/java/de/eydamos/backpack/proxy/CommonProxy.java @@ -23,4 +23,9 @@ public void registerKeybindings() {} @Override public void addNeiSupport() {} + + @Override + public void invalidateBackpackCache(String uuid) { + // Do nothing by default (server side) + } } diff --git a/src/main/java/de/eydamos/backpack/proxy/IProxy.java b/src/main/java/de/eydamos/backpack/proxy/IProxy.java index 67e26951..135cff58 100644 --- a/src/main/java/de/eydamos/backpack/proxy/IProxy.java +++ b/src/main/java/de/eydamos/backpack/proxy/IProxy.java @@ -7,4 +7,6 @@ public interface IProxy { void registerKeybindings(); void addNeiSupport(); + + void invalidateBackpackCache(String uuid); }