From ba5e309ee1ccad05197437f85fa6d745606f7f94 Mon Sep 17 00:00:00 2001 From: Alexdoru <57050655+Alexdoru@users.noreply.github.com> Date: Tue, 12 May 2026 16:51:11 +0200 Subject: [PATCH] [Memory-opti:fix leak] Fix memory leak from PlayerHandler (#33) --- src/main/java/baubles/common/Baubles.java | 7 +++ .../common/container/InventoryBaubles.java | 7 ++- .../common/event/EventHandlerEntity.java | 6 +++ .../common/event/EventHandlerNetwork.java | 50 +++++++++---------- .../baubles/common/lib/PlayerHandler.java | 18 ++++++- 5 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/main/java/baubles/common/Baubles.java b/src/main/java/baubles/common/Baubles.java index c92bd79..84b35c5 100644 --- a/src/main/java/baubles/common/Baubles.java +++ b/src/main/java/baubles/common/Baubles.java @@ -3,8 +3,10 @@ package baubles.common; import java.io.File; import baubles.Tags; +import baubles.common.lib.PlayerHandler; import codechicken.nei.api.API; import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.event.FMLServerStoppedEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -71,4 +73,9 @@ public class Baubles { } } + @Mod.EventHandler + public void onServerStopped(FMLServerStoppedEvent event) { + PlayerHandler.clearServerPlayerBaubles(); + } + } diff --git a/src/main/java/baubles/common/container/InventoryBaubles.java b/src/main/java/baubles/common/container/InventoryBaubles.java index f42e1ff..9f6c86f 100644 --- a/src/main/java/baubles/common/container/InventoryBaubles.java +++ b/src/main/java/baubles/common/container/InventoryBaubles.java @@ -7,7 +7,6 @@ import baubles.api.BaubleType; import baubles.api.IBauble; import baubles.api.expanded.BaubleExpandedSlots; import baubles.api.expanded.IBaubleExpanded; -import baubles.common.Baubles; import baubles.common.lib.ItemStackHelper; import baubles.common.network.PacketHandler; import baubles.common.network.PacketSyncBauble; @@ -295,9 +294,9 @@ public class InventoryBaubles implements IInventory { public void syncSlotToClients(int slot) { try { - EntityPlayer entityPlayer = player.get(); - if (entityPlayer != null && !entityPlayer.worldObj.isRemote) { - PacketHandler.INSTANCE.sendToAll(new PacketSyncBauble(player.get(), slot)); + final EntityPlayer player = this.player.get(); + if (player != null && !player.worldObj.isRemote) { + PacketHandler.INSTANCE.sendToDimension(new PacketSyncBauble(player, slot), player.dimension); } } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/baubles/common/event/EventHandlerEntity.java b/src/main/java/baubles/common/event/EventHandlerEntity.java index f94e5e0..b4ab02f 100644 --- a/src/main/java/baubles/common/event/EventHandlerEntity.java +++ b/src/main/java/baubles/common/event/EventHandlerEntity.java @@ -13,6 +13,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.event.entity.player.PlayerDropsEvent; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.event.world.WorldEvent; public class EventHandlerEntity { @@ -99,4 +100,9 @@ public class EventHandlerEntity { getPlayerFile("baubback", directory, player.getCommandSenderName())); } + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + PlayerHandler.onWorldUnload(event.world); + } + } diff --git a/src/main/java/baubles/common/event/EventHandlerNetwork.java b/src/main/java/baubles/common/event/EventHandlerNetwork.java index 6a76306..01461fa 100644 --- a/src/main/java/baubles/common/event/EventHandlerNetwork.java +++ b/src/main/java/baubles/common/event/EventHandlerNetwork.java @@ -1,45 +1,43 @@ package baubles.common.event; -import baubles.api.BaublesApi; import baubles.api.IBauble; -import baubles.common.Baubles; import baubles.common.container.InventoryBaubles; import baubles.common.lib.PlayerHandler; import baubles.common.network.PacketHandler; import baubles.common.network.PacketSyncBauble; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; -import cpw.mods.fml.relauncher.Side; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; public class EventHandlerNetwork { - @SubscribeEvent - public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent event) { - Side side = FMLCommonHandler.instance().getEffectiveSide(); - if (side == Side.SERVER) { - // Apply all baubles - InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(event.player); - for (int i = 0; i < baubles.getSizeInventory(); i++) { - ItemStack stack = baubles.getStackInSlot(i); - PacketHandler.INSTANCE.sendToAll(new PacketSyncBauble(event.player, i, true)); - if (stack != null && stack.getItem() instanceof IBauble itemBauble) { - itemBauble.onPlayerLoad(stack, event.player); - } - } + @SubscribeEvent + public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent event) { + // Apply all baubles + InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(event.player); + for (int i = 0; i < baubles.getSizeInventory(); i++) { + ItemStack stack = baubles.getStackInSlot(i); + PacketHandler.INSTANCE.sendToDimension(new PacketSyncBauble(event.player, i, true), event.player.dimension); + if (stack != null && stack.getItem() instanceof IBauble itemBauble) { + itemBauble.onPlayerLoad(stack, event.player); + } + } + } - } - } + @SubscribeEvent + public void playerChangedDim(PlayerEvent.PlayerChangedDimensionEvent event) { + InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(event.player); + for (int i = 0; i < baubles.getSizeInventory(); i++) { + PacketHandler.INSTANCE.sendToDimension(new PacketSyncBauble(event.player, i, true), event.player.dimension); + } + } - public static void syncBaubles(EntityPlayer player) { + public static void syncBaubles(EntityPlayer player) { InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(player); - for (int i = 0; i < baubles.getSizeInventory(); i++) { - baubles.syncSlotToClients(i); - } - } - + for (int i = 0; i < baubles.getSizeInventory(); i++) { + baubles.syncSlotToClients(i); + } + } } diff --git a/src/main/java/baubles/common/lib/PlayerHandler.java b/src/main/java/baubles/common/lib/PlayerHandler.java index 72c7f11..bfb7737 100644 --- a/src/main/java/baubles/common/lib/PlayerHandler.java +++ b/src/main/java/baubles/common/lib/PlayerHandler.java @@ -12,11 +12,12 @@ import baubles.common.container.InventoryBaubles; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; public class PlayerHandler { - private static HashMap playerBaublesServer = new HashMap<>(); - private static HashMap playerBaublesClient = new HashMap<>(); + private static final HashMap playerBaublesServer = new HashMap<>(); + private static final HashMap playerBaublesClient = new HashMap<>(); public static void clearPlayerBaubles(EntityPlayer player) { playerBaublesServer.remove(player.getCommandSenderName()); @@ -26,6 +27,19 @@ public class PlayerHandler { playerBaublesClient.clear(); } + public static void clearServerPlayerBaubles() { + playerBaublesServer.clear(); + } + + public static void onWorldUnload(World world) { + if (world.isRemote) { + playerBaublesClient.values().removeIf(inv -> { + final EntityPlayer player = inv.player.get(); + return player == null || player.worldObj == world; + }); + } + } + public static InventoryBaubles getPlayerBaubles(EntityPlayer player) { if (player.worldObj.isRemote) { return playerBaublesClient.computeIfAbsent(player.getCommandSenderName(), username -> new InventoryBaubles(player));