diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index f92a6ac9..1f60556b 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -29,6 +29,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.trim_model_caches", true); this.addMixinRule("bugfix.concurrency", true); this.addMixinRule("bugfix.edge_chunk_not_saved", true); + this.addMixinRule("bugfix.packet_leak", false); this.addMixinRule("perf.async_jei", true); this.addMixinRule("perf.thread_priorities", true); this.addMixinRule("perf.preload_block_classes", false); diff --git a/src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java b/src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java new file mode 100644 index 00000000..8659bd70 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/duck/IClientNetHandler.java @@ -0,0 +1,7 @@ +package org.embeddedt.modernfix.duck; + +import net.minecraft.network.PacketBuffer; + +public interface IClientNetHandler { + PacketBuffer getCopiedCustomBuffer(); +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java new file mode 100644 index 00000000..1cbc53ba --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java @@ -0,0 +1,31 @@ +package org.embeddedt.modernfix.mixin.bugfix.packet_leak; + +import net.minecraft.client.network.play.ClientPlayNetHandler; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SCustomPayloadPlayPacket; +import org.embeddedt.modernfix.duck.IClientNetHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ClientPlayNetHandler.class) +public class ClientPlayNetHandlerMixin implements IClientNetHandler { + private PacketBuffer savedCopy = null; + /** + * @author embeddedt + * @reason Release the packet buffer at the end. Needed in f + */ + @Redirect(method = "handleCustomPayload", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/play/server/SCustomPayloadPlayPacket;getData()Lnet/minecraft/network/PacketBuffer;")) + private PacketBuffer saveCopyForRelease(SCustomPayloadPlayPacket instance) { + PacketBuffer copy = instance.getData(); + savedCopy = copy; + return copy; + } + + @Override + public PacketBuffer getCopiedCustomBuffer() { + PacketBuffer copy = savedCopy; + savedCopy = null; + return copy; + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java new file mode 100644 index 00000000..700ae882 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/bugfix/packet_leak/SCustomPayloadPlayPacketMixin.java @@ -0,0 +1,43 @@ +package org.embeddedt.modernfix.mixin.bugfix.packet_leak; + +import net.minecraft.client.network.play.IClientPlayNetHandler; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SCustomPayloadPlayPacket; +import net.minecraft.util.ResourceLocation; +import org.embeddedt.modernfix.duck.IClientNetHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(SCustomPayloadPlayPacket.class) +public class SCustomPayloadPlayPacketMixin { + @Shadow private PacketBuffer data; + + private boolean needsRelease; + + @Inject(method = "(Lnet/minecraft/util/ResourceLocation;Lnet/minecraft/network/PacketBuffer;)V", at = @At("RETURN")) + private void markNotOwned(ResourceLocation pIdentifier, PacketBuffer pData, CallbackInfo ci) { + this.needsRelease = false; + } + + @Inject(method = "read", at = @At("RETURN")) + private void markOwned(PacketBuffer p_148837_1_, CallbackInfo ci) { + this.needsRelease = true; + } + + @Redirect(method = "handle(Lnet/minecraft/client/network/play/IClientPlayNetHandler;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/play/IClientPlayNetHandler;handleCustomPayload(Lnet/minecraft/network/play/server/SCustomPayloadPlayPacket;)V")) + private void handleAndFree(IClientPlayNetHandler instance, SCustomPayloadPlayPacket sCustomPayloadPlayPacket) { + try { + instance.handleCustomPayload(sCustomPayloadPlayPacket); + } finally { + PacketBuffer copied = ((IClientNetHandler)instance).getCopiedCustomBuffer(); + if(copied != null) + copied.release(); + } + if(this.needsRelease) + this.data.release(); + } +} diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 47c28e97..1adf5d8d 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -54,7 +54,9 @@ "perf.blast_search_trees.IngredientFilterInvoker", "perf.faster_baking.ModelBakeryMixin", "perf.cache_model_materials.VanillaModelMixin", - "perf.cache_model_materials.MultipartMixin" + "perf.cache_model_materials.MultipartMixin", + "bugfix.packet_leak.ClientPlayNetHandlerMixin", + "bugfix.packet_leak.SCustomPayloadPlayPacketMixin" ], "injectors": { "defaultRequire": 1