diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java new file mode 100644 index 00000000..e4f0fa57 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java @@ -0,0 +1,41 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.world_leaks; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.lighting.LevelLightEngine; +import org.embeddedt.modernfix.ModernFix; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; +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.callback.CallbackInfo; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @Shadow @Nullable public ClientLevel level; + + /** + * To mitigate the effect of leaked client worlds, clear most of the data structures that waste memory. + */ + @Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/Minecraft;level:Lnet/minecraft/client/multiplayer/ClientLevel;")) + private void clearLevelDataForLeaks(CallbackInfo ci) { + if(this.level != null) { + try { + AtomicReferenceArray chunks = this.level.getChunkSource().storage.chunks; + for(int i = 0; i < chunks.length(); i++) { + chunks.set(i, null); + } + this.level.getChunkSource().lightEngine = new LevelLightEngine(this.level.getChunkSource(), false, false); + // clear BE list otherwise they will hold chunks + this.level.blockEntityTickers.clear(); + } catch(RuntimeException e) { + ModernFix.LOGGER.error("Exception clearing level data", e); + } + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java index 845fbb1e..015e74a4 100644 --- a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java @@ -12,7 +12,7 @@ import java.util.Map; * Replacement backing map for CompoundTags that interns keys. */ public class CanonizingStringMap extends HashMap { - private static final Interner KEY_INTERNER = Interners.newStrongInterner(); + private static final Interner KEY_INTERNER = Interners.newWeakInterner(); private static String intern(String key) { return key != null ? KEY_INTERNER.intern(key) : null; diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index 35f1affc..3d6d358a 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -1,5 +1,13 @@ accessWidener v2 named +accessible field net/minecraft/client/multiplayer/ClientChunkCache storage Lnet/minecraft/client/multiplayer/ClientChunkCache$Storage; +accessible field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine; +mutable field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine; +accessible class net/minecraft/client/multiplayer/ClientChunkCache$Storage +accessible field net/minecraft/client/multiplayer/ClientChunkCache$Storage chunks Ljava/util/concurrent/atomic/AtomicReferenceArray; + +accessible field net/minecraft/world/level/Level blockEntityTickers Ljava/util/List; + accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType accessible method net/minecraft/nbt/CompoundTag (Ljava/util/Map;)V diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 58fc2335..af11380f 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -14,6 +14,15 @@ }, "license": "LGPL-3.0", "icon": "icon.png", + "custom": { + "modmenu": { + "links": { + "modmenu.kofi": "https://ko-fi.com/embeddedt", + "modmenu.github_releases": "https://github.com/embeddedt/ModernFix/releases", + "modmenu.curseforge": "https://www.curseforge.com/minecraft/mc-mods/modernfix" + } + } + }, "environment": "*", "entrypoints": { "main": [