From 51ff0c5b8011971cace724bde40d38c3042ab8a6 Mon Sep 17 00:00:00 2001 From: jchung01 Date: Thu, 22 Aug 2024 19:51:41 -0700 Subject: [PATCH 1/5] Fix some more minor memory leaks from the following mods - Bibliocraft version check - Iron Chests item stack render - Compact Machines recipe render --- dependencies.gradle | 2 + gradle.properties | 2 + .../universaltweaks/core/UTMixinLoader.java | 8 +- .../bibliocraft/mixin/UTBiblioCraftMixin.java | 20 +++ .../mods/compactmachines/DummyWorld.java | 68 +++++++ .../mixin/UTProxyWorldMixin.java | 168 ++++++++++++++++++ .../UTTileEntityIronChestRendererMixin.java | 123 +++++++++++++ ...TileEntityIronShulkerBoxRendererMixin.java | 121 +++++++++++++ .../resources/mixins.mods.bibliocraft.json | 7 + .../mixins.mods.compactmachines.memory.json | 7 + ...> mixins.mods.compactmachines.render.json} | 2 +- .../resources/mixins.mods.ironchests.json | 7 + 12 files changed, 533 insertions(+), 2 deletions(-) create mode 100644 src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java create mode 100644 src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java create mode 100644 src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/mixin/UTProxyWorldMixin.java create mode 100644 src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java create mode 100644 src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java create mode 100644 src/main/resources/mixins.mods.bibliocraft.json create mode 100644 src/main/resources/mixins.mods.compactmachines.memory.json rename src/main/resources/{mixins.mods.compactmachines.json => mixins.mods.compactmachines.render.json} (84%) create mode 100644 src/main/resources/mixins.mods.ironchests.json diff --git a/dependencies.gradle b/dependencies.gradle index eb740d65..7d824e14 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -62,6 +62,7 @@ final def mod_dependencies = [ 'curse.maven:autoreglib-250363:2746011' : [debug_quark], 'curse.maven:baubles-227083:2518667' : [debug_astral_sorcery, debug_bewitchment, debug_botania, debug_thaumcraft, debug_thaumic_wonders], 'curse.maven:bewitchment-285439:3044569' : [debug_bewitchment], + 'curse.maven:bibliocraft-228027:3647708' : [debug_bibliocraft], 'curse.maven:binnies-mods-223525:2916129' : [debug_binnies_mods], 'curse.maven:biomes-o-plenty-220318:2842510' : [debug_biomes_o_plenty], 'curse.maven:blood-magic-224791:2822288' : [debug_blood_magic], @@ -91,6 +92,7 @@ final def mod_dependencies = [ 'curse.maven:hwyla-253449:2568751' : [debug_hwyla], 'curse.maven:industrialcraft-242638:3078604' : [debug_industrialcraft], 'curse.maven:ironbackpacks-227049:2564573' : [debug_iron_backpacks], + 'curse.maven:ironchests-228756:2747935' : [debug_iron_chests], 'curse.maven:mantle-74924:2713386' : [debug_tinkers_construct], 'curse.maven:mcjtylib-233105:2745846' : [debug_rftools], 'curse.maven:mekanism-268560:2835175' : [debug_mekanism], diff --git a/gradle.properties b/gradle.properties index abe0ebc5..2d9ee663 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,6 +10,7 @@ debug_arcane_archives = false debug_astral_sorcery = false debug_atomicstrykers_infernal_mobs = false debug_bewitchment = false +debug_bibliocraft = false debug_binnies_mods = false debug_biomes_o_plenty = false debug_blood_magic = false @@ -36,6 +37,7 @@ debug_hwyla = false debug_industrial_foregoing = false debug_industrialcraft = false debug_iron_backpacks = false +debug_iron_chests = false debug_mekanism = false debug_modular_routers = false debug_mrtjpcore = false diff --git a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java index 39079fd4..8959816d 100644 --- a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java +++ b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java @@ -18,10 +18,16 @@ public class UTMixinLoader implements ILateMixinLoader private static final Map> clientsideMixinConfigs = ImmutableMap.copyOf(new HashMap>() { { + // TODO: add config + put("mixins.mods.bibliocraft.json", () -> loaded("bibliocraft")); put("mixins.mods.cbmultipart.client.json", () -> loaded("forgemultipartcbe") && UTConfigMods.CB_MULTIPART.utMemoryLeakFixToggle); - put("mixins.mods.compactmachines.json", () -> loaded("compactmachines3") && UTConfigMods.COMPACT_MACHINES.utCMRenderFixToggle); + // TODO: add config + put("mixins.mods.compactmachines.memory.json", () -> loaded("compactmachines3")); + put("mixins.mods.compactmachines.render.json", () -> loaded("compactmachines3") && UTConfigMods.COMPACT_MACHINES.utCMRenderFixToggle); put("mixins.mods.crafttweaker.json", () -> loaded("crafttweaker")); put("mixins.mods.hwyla.json", () -> loaded("waila")); + // TODO: add config + put("mixins.mods.ironchests.json", () -> loaded("ironchest")); put("mixins.mods.modularrouters.json", () -> loaded("modularrouters") && UTConfigMods.MODULAR_ROUTERS.utParticleThreadToggle); put("mixins.mods.roost.json", () -> loaded("roost") && loaded("contenttweaker")); put("mixins.mods.storagedrawers.client.json", () -> loaded("storagedrawers")); diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java new file mode 100644 index 00000000..21f9b6bd --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java @@ -0,0 +1,20 @@ +package mod.acgaming.universaltweaks.mods.bibliocraft.mixin; + +import jds.bibliocraft.BiblioCraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = BiblioCraft.class, remap = false) +public class UTBiblioCraftMixin +{ + /** + * @reason Skip version checking because it retains the first WorldClient + */ + @Inject(method = "postInitClient", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/common/eventhandler/EventBus;register(Ljava/lang/Object;)V", ordinal = 0, shift = At.Shift.AFTER), cancellable = true) + private void utDisableVersionCheck(CallbackInfo ci) + { + ci.cancel(); + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java new file mode 100644 index 00000000..d7b444d2 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java @@ -0,0 +1,68 @@ +package mod.acgaming.universaltweaks.mods.compactmachines; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.GameType; +import net.minecraft.world.World; +import net.minecraft.world.WorldSettings; +import net.minecraft.world.WorldType; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraftforge.fml.common.Loader; + +import io.netty.util.collection.LongObjectHashMap; +import io.netty.util.collection.LongObjectMap; + +public class DummyWorld +{ + public static final WorldSettings DEFAULT_SETTINGS = new WorldSettings(1L, GameType.SURVIVAL, true, false, WorldType.DEFAULT); + public static final boolean isAlfheimLoaded = Loader.isModLoaded("alfheim"); + + public static class DummyChunkProvider implements IChunkProvider + { + private final World world; + private final LongObjectMap loadedChunks = new LongObjectHashMap<>(); + + public DummyChunkProvider(World world) { + this.world = world; + } + + @Nullable + @Override + public Chunk getLoadedChunk(int x, int z) { + return loadedChunks.get(ChunkPos.asLong(x, z)); + } + + @Nonnull + @Override + public Chunk provideChunk(int x, int z) { + long chunkKey = ChunkPos.asLong(x, z); + if (loadedChunks.containsKey(chunkKey)) + return loadedChunks.get(chunkKey); + Chunk chunk = new Chunk(world, x, z); + loadedChunks.put(chunkKey, chunk); + return chunk; + } + + @Override + public boolean tick() { + for (Chunk chunk : loadedChunks.values()) { + chunk.onTick(false); + } + return !loadedChunks.isEmpty(); + } + + @Nonnull + @Override + public String makeString() { + return "Dummy"; + } + + @Override + public boolean isChunkGeneratedAt(int x, int z) { + return true; + } + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/mixin/UTProxyWorldMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/mixin/UTProxyWorldMixin.java new file mode 100644 index 00000000..adaac9cb --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/mixin/UTProxyWorldMixin.java @@ -0,0 +1,168 @@ +package mod.acgaming.universaltweaks.mods.compactmachines.mixin; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.profiler.Profiler; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.EnumSkyBlock; +import net.minecraft.world.World; +import net.minecraft.world.WorldProvider; +import net.minecraft.world.WorldProviderSurface; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.storage.ISaveHandler; +import net.minecraft.world.storage.WorldInfo; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.common.Optional; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; + +import mod.acgaming.universaltweaks.mods.compactmachines.DummyWorld; +import org.dave.compactmachines3.world.ProxyWorld; +import org.spongepowered.asm.mixin.*; +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 to avoid client memory leak when rendering miniaturization recipes. + * Also reduces memory usage when Alfheim Lighting Engine is present. + *
+ * Adapted from MMCE/Multiblocked's DummyWorld. + * @author jchung01 + */ +@Mixin(value = ProxyWorld.class) +public abstract class UTProxyWorldMixin extends World +{ + @Mutable + @Shadow(remap = false) + @Final + private World realWorld; + + protected UTProxyWorldMixin(ISaveHandler saveHandlerIn, WorldInfo info, WorldProvider providerIn, Profiler profilerIn, boolean client) + { + super(saveHandlerIn, info, providerIn, profilerIn, client); + } + + @Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/WorldClient;getWorldInfo()Lnet/minecraft/world/storage/WorldInfo;", remap = true), remap = false) + private static WorldInfo utDummyWorldInfo(WorldClient instance) + { + return new WorldInfo(DummyWorld.DEFAULT_SETTINGS, "Dummy"); + } + + @Redirect(method = "*", at = @At(value = "FIELD", target = "Lnet/minecraft/client/multiplayer/WorldClient;provider:Lnet/minecraft/world/WorldProvider;", remap = true), remap = false) + private static WorldProvider utDummyWorldProvider(WorldClient instance) + { + return new WorldProviderSurface(); + } + + @Redirect(method = "*", at = @At(value = "FIELD", target = "Lnet/minecraft/client/multiplayer/WorldClient;profiler:Lnet/minecraft/profiler/Profiler;", remap = true), remap = false) + private static Profiler utDummyProfiler(WorldClient instance) + { + return new Profiler(); + } + + @Inject(method = "*", at = @At(value = "TAIL"), remap = false) + private void utSetupDummyWorld(CallbackInfo ci) + { + // Guarantee the dimension ID was not reset by the provider + this.provider.setDimension(Integer.MAX_VALUE - 1024); + int providerDim = this.provider.getDimension(); + this.provider.setWorld(this); + this.provider.setDimension(providerDim); + this.chunkProvider = this.createChunkProvider(); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); + this.getWorldBorder().setSize(30000000); + ObfuscationReflectionHelper.setPrivateValue(World.class, this, null, FMLLaunchHandler.isDeobfuscatedEnvironment() ? "lightUpdateBlockList" : "field_72994_J"); + // De-allocate alfheim lighting engine + if (DummyWorld.isAlfheimLoaded) { + ObfuscationReflectionHelper.setPrivateValue(World.class, this, null, + "alfheim$lightingEngine"); + } + this.realWorld = null; + } + + /** + * @author jchung01 + * @reason Don't use realWorld + */ + @Nonnull + @Overwrite + protected IChunkProvider createChunkProvider() + { + return new DummyWorld.DummyChunkProvider(this); + } + + @Override + protected void initCapabilities() { + //NOOP - do not trigger forge events + } + + @Override + public void notifyNeighborsRespectDebug(@Nonnull BlockPos pos, @Nonnull Block blockType, boolean p_175722_3_) { + //NOOP - do not trigger forge events + } + + @Override + public void notifyNeighborsOfStateChange(@Nonnull BlockPos pos, @Nonnull Block blockType, boolean updateObservers) { + //NOOP - do not trigger forge events + } + + @Override + public void notifyNeighborsOfStateExcept(@Nonnull BlockPos pos, @Nonnull Block blockType, @Nonnull EnumFacing skipSide) { + //NOOP - do not trigger forge events + } + + @Override + public void markAndNotifyBlock(@Nonnull BlockPos pos, @Nullable Chunk chunk, @Nonnull IBlockState iblockstate, @Nonnull IBlockState newState, int flags) { + //NOOP - do not trigger forge events + } + + @Override + public void notifyBlockUpdate(@Nonnull BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newState, int flags) { + } + + @Override + public void markBlockRangeForRenderUpdate(@Nonnull BlockPos rangeMin, @Nonnull BlockPos rangeMax) { + } + + @Override + public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { + } + + @Override + public void updateObservingBlocksAt(@Nonnull BlockPos pos, @Nonnull Block blockType) { + } + + @Override + // De-allocated lightUpdateBlockList, default return + public boolean checkLightFor(@Nonnull EnumSkyBlock lightType, @Nonnull BlockPos pos) { + return true; + } + + @Nonnull + @Override + @Optional.Method(modid = "alfheim") + public World init() { + return this; + } + + @SuppressWarnings("NullableProblems") + @Override + @Optional.Method(modid = "alfheim") + public int getLightFromNeighborsFor(EnumSkyBlock type, BlockPos pos) { + return 15; + } + + @SuppressWarnings({"MissingUnique", "unused"}) + @Optional.Method(modid = "alfheim") + public int alfheim$getLight(BlockPos pos, boolean checkNeighbors) { + return 15; + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java new file mode 100644 index 00000000..a4d9caf9 --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java @@ -0,0 +1,123 @@ +package mod.acgaming.universaltweaks.mods.ironchests.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.item.ItemStack; + +import cpw.mods.ironchest.client.renderer.chest.TileEntityIronChestRenderer; +import cpw.mods.ironchest.common.tileentity.chest.TileEntityIronChest; +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; + +// Courtesy of jchung01 +@Mixin(value = TileEntityIronChestRenderer.class, remap = false) +public class UTTileEntityIronChestRendererMixin extends TileEntitySpecialRenderer +{ + @Shadow + private static float[][] shifts; + + /** + * Use simple RenderItem instead of RenderEntityItem. + * @reason Don't use customItem which retains the first WorldClient. + * @author jchung01 + */ + @Inject(method = "render(Lcpw/mods/ironchest/common/tileentity/chest/TileEntityIronChest;DDDFIF)V", at = @At(value = "INVOKE", target = "Ljava/util/Random;setSeed(J)V", shift = At.Shift.AFTER), cancellable = true) + private void utReplaceItemRenderer(TileEntityIronChest te, double x, double y, double z, float partialTicks, int destroyStage, float partial, CallbackInfo ci) + { + // if (UT) return; + ci.cancel(); + + float shiftX; + float shiftY; + float shiftZ; + int shift = 0; + float blockScale = 0.70F; + float timeD = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks; + + if (te.getTopItems().get(1).isEmpty()) + { + shift = 8; + blockScale = 0.85F; + } + + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y, (float) z); + + // CHANGE START: Don't init customItem + /* + if (customItem == null) + { + customItem = new EntityItem(this.getWorld()); + } + + customItem.hoverStart = 0F; + */ + // CHANGE END + + for (ItemStack item : te.getTopItems()) + { + if (shift > shifts.length || shift > 8) + { + break; + } + + if (item.isEmpty()) + { + shift++; + continue; + } + + shiftX = shifts[shift][0]; + shiftY = shifts[shift][1]; + shiftZ = shifts[shift][2]; + shift++; + + GlStateManager.pushMatrix(); + GlStateManager.translate(shiftX, shiftY, shiftZ); + GlStateManager.rotate(timeD, 0F, 1F, 0F); + GlStateManager.scale(blockScale, blockScale, blockScale); + + // CHANGE START: Don't use customItem and use built-in RenderItem + /* + customItem.setItem(item); + + if (this.itemRenderer == null) + { + this.itemRenderer = new RenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()) + { + @Override + public int getModelCount(ItemStack stack) + { + return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1); + } + + @Override + public boolean shouldBob() + { + return false; + } + + @Override + public boolean shouldSpreadItems() + { + return true; + } + }; + } + + this.itemRenderer.doRender(customItem, 0D, 0D, 0D, 0F, partialTicks); + */ + Minecraft.getMinecraft().getRenderItem().renderItem(item, ItemCameraTransforms.TransformType.GROUND); + // CHANGE END + + GlStateManager.popMatrix(); + } + + GlStateManager.popMatrix(); + } +} diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java new file mode 100644 index 00000000..f632e08a --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java @@ -0,0 +1,121 @@ +package mod.acgaming.universaltweaks.mods.ironchests.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.item.ItemStack; + +import cpw.mods.ironchest.client.renderer.shulker.TileEntityIronShulkerBoxRenderer; +import cpw.mods.ironchest.common.tileentity.shulker.TileEntityIronShulkerBox; +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; + +// Courtesy of jchung01 +@Mixin(value = TileEntityIronShulkerBoxRenderer.class, remap = false) +public class UTTileEntityIronShulkerBoxRendererMixin +{ + @Shadow + private static float[][] shifts; + + /** + * Use simple RenderItem instead of RenderEntityItem. + * @reason Don't use customItem which retains the first WorldClient. + * @author jchung01 + */ + @Inject(method = "render(Lcpw/mods/ironchest/common/tileentity/shulker/TileEntityIronShulkerBox;DDDFIF)V", at = @At(value = "INVOKE", target = "Ljava/util/Random;setSeed(J)V", shift = At.Shift.AFTER), cancellable = true) + private void utReplaceItemRenderer(TileEntityIronShulkerBox te, double x, double y, double z, float partialTicks, int destroyStage, float alpha, CallbackInfo ci) + { + // if (UT) return; + ci.cancel(); + + float shiftX; + float shiftY; + float shiftZ; + int shift = 0; + float blockScale = 0.70F; + float timeD = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks; + + if (te.getTopItems().get(1).isEmpty()) + { + shift = 8; + blockScale = 0.85F; + } + + GlStateManager.pushMatrix(); + GlStateManager.translate((float) x, (float) y, (float) z); + + // CHANGE START: Don't init customItem + /* + if (customItem == null) + { + customItem = new EntityItem(this.getWorld()); + } + + customItem.hoverStart = 0F; + */ + // CHANGE END + + for (ItemStack item : te.getTopItems()) + { + if (shift > shifts.length || shift > 8) + { + break; + } + + if (item.isEmpty()) + { + shift++; + continue; + } + + shiftX = shifts[shift][0]; + shiftY = shifts[shift][1]; + shiftZ = shifts[shift][2]; + shift++; + + GlStateManager.pushMatrix(); + GlStateManager.translate(shiftX, shiftY, shiftZ); + GlStateManager.rotate(timeD, 0F, 1F, 0F); + GlStateManager.scale(blockScale, blockScale, blockScale); + // CHANGE START: Don't use customItem and use built-in RenderItem + /* + customItem.setItem(item); + + if (this.itemRenderer == null) + { + this.itemRenderer = new RenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()) + { + @Override + public int getModelCount(ItemStack stack) + { + return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1); + } + + @Override + public boolean shouldBob() + { + return false; + } + + @Override + public boolean shouldSpreadItems() + { + return true; + } + }; + } + + this.itemRenderer.doRender(customItem, 0D, 0D, 0D, 0F, partialTicks); + */ + Minecraft.getMinecraft().getRenderItem().renderItem(item, ItemCameraTransforms.TransformType.GROUND); + // CHANGE END + + GlStateManager.popMatrix(); + } + + GlStateManager.popMatrix(); + } +} diff --git a/src/main/resources/mixins.mods.bibliocraft.json b/src/main/resources/mixins.mods.bibliocraft.json new file mode 100644 index 00000000..307f1b12 --- /dev/null +++ b/src/main/resources/mixins.mods.bibliocraft.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.universaltweaks.mods.bibliocraft.mixin", + "refmap": "universaltweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "client": ["UTBiblioCraftMixin"] +} \ No newline at end of file diff --git a/src/main/resources/mixins.mods.compactmachines.memory.json b/src/main/resources/mixins.mods.compactmachines.memory.json new file mode 100644 index 00000000..711d9ca3 --- /dev/null +++ b/src/main/resources/mixins.mods.compactmachines.memory.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.universaltweaks.mods.compactmachines.mixin", + "refmap": "universaltweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "client": ["UTProxyWorldMixin"] +} \ No newline at end of file diff --git a/src/main/resources/mixins.mods.compactmachines.json b/src/main/resources/mixins.mods.compactmachines.render.json similarity index 84% rename from src/main/resources/mixins.mods.compactmachines.json rename to src/main/resources/mixins.mods.compactmachines.render.json index b64c8c7b..75927035 100644 --- a/src/main/resources/mixins.mods.compactmachines.json +++ b/src/main/resources/mixins.mods.compactmachines.render.json @@ -3,5 +3,5 @@ "refmap": "universaltweaks.refmap.json", "minVersion": "0.8", "compatibilityLevel": "JAVA_8", - "mixins": ["UTCubeToolsMixin"] + "client": ["UTCubeToolsMixin"] } \ No newline at end of file diff --git a/src/main/resources/mixins.mods.ironchests.json b/src/main/resources/mixins.mods.ironchests.json new file mode 100644 index 00000000..9432b93e --- /dev/null +++ b/src/main/resources/mixins.mods.ironchests.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.universaltweaks.mods.ironchests.mixin", + "refmap": "universaltweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "client": ["UTTileEntityIronChestRendererMixin", "UTTileEntityIronShulkerBoxRendererMixin"] +} \ No newline at end of file From 060c00afeb9a16d959fc2963728a58037d6e7257 Mon Sep 17 00:00:00 2001 From: jchung01 Date: Fri, 23 Aug 2024 13:59:54 -0700 Subject: [PATCH 2/5] Fix minor memory leak in EIO obelisk render --- .../universaltweaks/core/UTMixinLoader.java | 2 + .../mixin/UTObeliskSpecialRendererMixin.java | 99 +++++++++++++++++++ src/main/resources/mixins.mods.enderio.json | 7 ++ 3 files changed, 108 insertions(+) create mode 100644 src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java create mode 100644 src/main/resources/mixins.mods.enderio.json diff --git a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java index 8959816d..52b84c5c 100644 --- a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java +++ b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java @@ -25,6 +25,8 @@ public class UTMixinLoader implements ILateMixinLoader put("mixins.mods.compactmachines.memory.json", () -> loaded("compactmachines3")); put("mixins.mods.compactmachines.render.json", () -> loaded("compactmachines3") && UTConfigMods.COMPACT_MACHINES.utCMRenderFixToggle); put("mixins.mods.crafttweaker.json", () -> loaded("crafttweaker")); + // TODO: add config + put("mixins.mods.enderio.json", () -> loaded("enderio")); put("mixins.mods.hwyla.json", () -> loaded("waila")); // TODO: add config put("mixins.mods.ironchests.json", () -> loaded("ironchest")); diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java new file mode 100644 index 00000000..49cbe66f --- /dev/null +++ b/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java @@ -0,0 +1,99 @@ +package mod.acgaming.universaltweaks.mods.enderio.mixin; + +import java.util.Random; +import javax.annotation.Nonnull; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import com.enderio.core.client.render.ManagedTESR; +import com.enderio.core.client.render.RenderUtil; +import com.enderio.core.common.TileEntityBase; +import crazypants.enderio.base.EnderIO; +import crazypants.enderio.machines.machine.obelisk.render.ObeliskSpecialRenderer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(value = ObeliskSpecialRenderer.class, remap = false) +public abstract class UTObeliskSpecialRendererMixin extends ManagedTESR +{ + @Shadow + @Final + private Random rand; + + @Shadow + @Nonnull + protected abstract ItemStack getFloatingItem(T te); + + protected UTObeliskSpecialRendererMixin(Block block) + { + super(block); + } + + /** + * Use simple RenderItem instead of RenderEntityItem. + * @reason Don't use rei/entityItem which retains the first WorldClient. + * @author jchung01 + */ + @Overwrite + protected void renderItemStack(T te, @Nonnull World world, double x, double y, double z, float tick) + { + // CHANGE START: Don't init enityItem + /* + EntityItem ei = this.enityItem; + if (ei == null) { + this.enityItem = ei = new EntityItem(world, 0, 0, 0, getFloatingItem(te)); + } + ei.setItem(getFloatingItem(te)); + ei.hoverStart = (float) ((EnderIO.proxy.getTickCount() * 0.05f + (tick * 0.05f)) % (Math.PI * 2)); + */ + // CHANGE END + RenderUtil.bindBlockTexture(); + + GlStateManager.pushMatrix(); + GlStateManager.translate(x + 0.5, y + 0.7, z + 0.5); + GlStateManager.scale(1.1f, 1.1f, 1.1f); + + // CHANGE START: Simplify seed and remove allocation + if (te != null) + { + BlockPos p = te.getPos(); + this.rand.setSeed(p.getX() + p.getY() + p.getZ()); + } + else + { + this.rand.setSeed(0); + } + // CHANGE END + + this.rand.nextBoolean(); + if (Minecraft.getMinecraft().gameSettings.fancyGraphics) { + GlStateManager.rotate(rand.nextFloat() * 360f, 0, 1, 0); + } + // CHANGE START: Don't use enityItem and use built-in RenderItem + /* + ei.hoverStart += rand.nextFloat(); + + GlStateManager.translate(0, -0.15f, 0); + if (rei == null) { + rei = new InnerRenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()); + } + rei.doRender(ei, 0.0D, 0.0D, 0.0D, 0.0F, 0.0F); + */ + float timeDelta = ((EnderIO.proxy.getTickCount() + tick) / 20.0f) * (180 / (float) Math.PI); + GlStateManager.rotate(timeDelta, 0F, 1F, 0F); + // An approximate shift, not exactly the same as original + GlStateManager.translate(0, -0.025f, 0); + Minecraft.getMinecraft().getRenderItem().renderItem(getFloatingItem(te), ItemCameraTransforms.TransformType.GROUND); + // CHANGE END + + GlStateManager.popMatrix(); + } +} diff --git a/src/main/resources/mixins.mods.enderio.json b/src/main/resources/mixins.mods.enderio.json new file mode 100644 index 00000000..58f0aa8e --- /dev/null +++ b/src/main/resources/mixins.mods.enderio.json @@ -0,0 +1,7 @@ +{ + "package": "mod.acgaming.universaltweaks.mods.enderio.mixin", + "refmap": "universaltweaks.refmap.json", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "client": ["UTObeliskSpecialRendererMixin"] +} \ No newline at end of file From fc6c9286d55e24308be121d55dcec65377b78b55 Mon Sep 17 00:00:00 2001 From: jchung01 Date: Fri, 23 Aug 2024 14:02:49 -0700 Subject: [PATCH 3/5] Use Overwrite in Iron Chests mixins to avoid allocations --- .../UTTileEntityIronChestRendererMixin.java | 241 ++++++++++++----- ...TileEntityIronShulkerBoxRendererMixin.java | 250 +++++++++++++----- 2 files changed, 362 insertions(+), 129 deletions(-) diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java index a4d9caf9..b25e932a 100644 --- a/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java +++ b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronChestRendererMixin.java @@ -1,18 +1,24 @@ package mod.acgaming.universaltweaks.mods.ironchests.mixin; +import java.util.Random; + +import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelChest; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; import cpw.mods.ironchest.client.renderer.chest.TileEntityIronChestRenderer; +import cpw.mods.ironchest.common.blocks.chest.BlockIronChest; +import cpw.mods.ironchest.common.blocks.chest.IronChestType; +import cpw.mods.ironchest.common.core.IronChestBlocks; import cpw.mods.ironchest.common.tileentity.chest.TileEntityIronChest; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; 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; // Courtesy of jchung01 @Mixin(value = TileEntityIronChestRenderer.class, remap = false) @@ -20,104 +26,213 @@ public class UTTileEntityIronChestRendererMixin extends TileEntitySpecialRendere { @Shadow private static float[][] shifts; + @Shadow + private static float halfPI; + @Shadow + private ModelChest model; + @Shadow + private Random random; /** * Use simple RenderItem instead of RenderEntityItem. * @reason Don't use customItem which retains the first WorldClient. * @author jchung01 */ - @Inject(method = "render(Lcpw/mods/ironchest/common/tileentity/chest/TileEntityIronChest;DDDFIF)V", at = @At(value = "INVOKE", target = "Ljava/util/Random;setSeed(J)V", shift = At.Shift.AFTER), cancellable = true) - private void utReplaceItemRenderer(TileEntityIronChest te, double x, double y, double z, float partialTicks, int destroyStage, float partial, CallbackInfo ci) + @Overwrite + public void render(TileEntityIronChest te, double x, double y, double z, float partialTicks, int destroyStage, float partial) { - // if (UT) return; - ci.cancel(); + if (te == null || te.isInvalid()) + { + return; + } - float shiftX; - float shiftY; - float shiftZ; - int shift = 0; - float blockScale = 0.70F; - float timeD = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks; + EnumFacing facing = EnumFacing.SOUTH; + IronChestType type = te.getType(); + + if (te.hasWorld() && te.getWorld().getBlockState(te.getPos()).getBlock() == IronChestBlocks.ironChestBlock) + { + facing = te.getFacing(); + IBlockState state = te.getWorld().getBlockState(te.getPos()); + type = state.getValue(BlockIronChest.VARIANT_PROP); + } - if (te.getTopItems().get(1).isEmpty()) + if (destroyStage >= 0) + { + this.bindTexture(DESTROY_STAGES[destroyStage]); + GlStateManager.matrixMode(5890); + GlStateManager.pushMatrix(); + GlStateManager.scale(4F, 4F, 1F); + GlStateManager.translate(0.0625F, 0.0625F, 0.0625F); + GlStateManager.matrixMode(5888); + } + else { - shift = 8; - blockScale = 0.85F; + this.bindTexture(type.modelTexture); } GlStateManager.pushMatrix(); - GlStateManager.translate((float) x, (float) y, (float) z); - // CHANGE START: Don't init customItem - /* - if (customItem == null) + if (type == IronChestType.CRYSTAL) { - customItem = new EntityItem(this.getWorld()); + GlStateManager.disableCull(); } - customItem.hoverStart = 0F; - */ - // CHANGE END + GlStateManager.color(1F, 1F, 1F, 1F); + GlStateManager.translate((float) x, (float) y + 1F, (float) z + 1F); + GlStateManager.scale(1F, -1F, -1F); + GlStateManager.translate(0.5F, 0.5F, 0.5F); - for (ItemStack item : te.getTopItems()) + switch (facing) { - if (shift > shifts.length || shift > 8) + case NORTH: { + GlStateManager.rotate(180F, 0F, 1F, 0F); break; } - - if (item.isEmpty()) + case SOUTH: { - shift++; - continue; + GlStateManager.rotate(0F, 0F, 1F, 0F); + break; + } + case WEST: + { + GlStateManager.rotate(90F, 0F, 1F, 0F); + break; + } + case EAST: + { + GlStateManager.rotate(270F, 0F, 1F, 0F); + break; + } + default: + { + GlStateManager.rotate(0F, 0F, 1F, 0F); + break; } + } + + GlStateManager.translate(-0.5F, -0.5F, -0.5F); + + float lidangle = te.prevLidAngle + (te.lidAngle - te.prevLidAngle) * partialTicks; + + lidangle = 1F - lidangle; + lidangle = 1F - lidangle * lidangle * lidangle; + + if (type.isTransparent()) + { + GlStateManager.scale(1F, 0.99F, 1F); + } + + this.model.chestLid.rotateAngleX = -lidangle * halfPI; + // Render the chest itself + this.model.renderAll(); - shiftX = shifts[shift][0]; - shiftY = shifts[shift][1]; - shiftZ = shifts[shift][2]; - shift++; + if (destroyStage >= 0) + { + GlStateManager.matrixMode(5890); + GlStateManager.popMatrix(); + GlStateManager.matrixMode(5888); + } + + if (type == IronChestType.CRYSTAL) + { + GlStateManager.enableCull(); + } + + GlStateManager.popMatrix(); + GlStateManager.color(1F, 1F, 1F, 1F); + + if (type.isTransparent() && te.getDistanceSq(this.rendererDispatcher.entityX, this.rendererDispatcher.entityY, this.rendererDispatcher.entityZ) < 128d) + { + this.random.setSeed(254L); + + float shiftX; + float shiftY; + float shiftZ; + int shift = 0; + float blockScale = 0.70F; + float timeD = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks; + + if (te.getTopItems().get(1).isEmpty()) + { + shift = 8; + blockScale = 0.85F; + } GlStateManager.pushMatrix(); - GlStateManager.translate(shiftX, shiftY, shiftZ); - GlStateManager.rotate(timeD, 0F, 1F, 0F); - GlStateManager.scale(blockScale, blockScale, blockScale); + GlStateManager.translate((float) x, (float) y, (float) z); - // CHANGE START: Don't use customItem and use built-in RenderItem + // CHANGE START: Don't init customItem /* - customItem.setItem(item); + if (customItem == null) + { + customItem = new EntityItem(this.getWorld()); + } - if (this.itemRenderer == null) + customItem.hoverStart = 0F; + */ + // CHANGE END + + for (ItemStack item : te.getTopItems()) { - this.itemRenderer = new RenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()) + if (shift > shifts.length || shift > 8) { - @Override - public int getModelCount(ItemStack stack) - { - return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1); - } + break; + } - @Override - public boolean shouldBob() - { - return false; - } + if (item.isEmpty()) + { + shift++; + continue; + } + + shiftX = shifts[shift][0]; + shiftY = shifts[shift][1]; + shiftZ = shifts[shift][2]; + shift++; - @Override - public boolean shouldSpreadItems() + GlStateManager.pushMatrix(); + GlStateManager.translate(shiftX, shiftY, shiftZ); + GlStateManager.rotate(timeD, 0F, 1F, 0F); + GlStateManager.scale(blockScale, blockScale, blockScale); + + // CHANGE START: Don't use customItem and use built-in RenderItem + /* + customItem.setItem(item); + + if (this.itemRenderer == null) + { + this.itemRenderer = new RenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()) { - return true; - } - }; + @Override + public int getModelCount(ItemStack stack) + { + return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1); + } + + @Override + public boolean shouldBob() + { + return false; + } + + @Override + public boolean shouldSpreadItems() + { + return true; + } + }; + } + + this.itemRenderer.doRender(customItem, 0D, 0D, 0D, 0F, partialTicks); + */ + Minecraft.getMinecraft().getRenderItem().renderItem(item, ItemCameraTransforms.TransformType.GROUND); + // CHANGE END + + GlStateManager.popMatrix(); } - this.itemRenderer.doRender(customItem, 0D, 0D, 0D, 0F, partialTicks); - */ - Minecraft.getMinecraft().getRenderItem().renderItem(item, ItemCameraTransforms.TransformType.GROUND); - // CHANGE END - GlStateManager.popMatrix(); } - - GlStateManager.popMatrix(); } } diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java index f632e08a..e9d07efd 100644 --- a/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java +++ b/src/main/java/mod/acgaming/universaltweaks/mods/ironchests/mixin/UTTileEntityIronShulkerBoxRendererMixin.java @@ -1,121 +1,239 @@ package mod.acgaming.universaltweaks.mods.ironchests.mixin; +import java.util.Random; + +import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelShulker; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import cpw.mods.ironchest.client.renderer.shulker.TileEntityIronShulkerBoxRenderer; +import cpw.mods.ironchest.common.blocks.shulker.BlockIronShulkerBox; +import cpw.mods.ironchest.common.blocks.shulker.IronShulkerBoxType; import cpw.mods.ironchest.common.tileentity.shulker.TileEntityIronShulkerBox; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; 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; // Courtesy of jchung01 @Mixin(value = TileEntityIronShulkerBoxRenderer.class, remap = false) -public class UTTileEntityIronShulkerBoxRendererMixin +public class UTTileEntityIronShulkerBoxRendererMixin extends TileEntitySpecialRenderer { @Shadow private static float[][] shifts; + @Final + @Shadow + private ModelShulker model; + @Shadow + private Random random; /** * Use simple RenderItem instead of RenderEntityItem. * @reason Don't use customItem which retains the first WorldClient. * @author jchung01 */ - @Inject(method = "render(Lcpw/mods/ironchest/common/tileentity/shulker/TileEntityIronShulkerBox;DDDFIF)V", at = @At(value = "INVOKE", target = "Ljava/util/Random;setSeed(J)V", shift = At.Shift.AFTER), cancellable = true) - private void utReplaceItemRenderer(TileEntityIronShulkerBox te, double x, double y, double z, float partialTicks, int destroyStage, float alpha, CallbackInfo ci) + @Overwrite + public void render(TileEntityIronShulkerBox te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { - // if (UT) return; - ci.cancel(); + if (te == null || te.isInvalid()) + { + return; + } + + EnumFacing enumfacing = EnumFacing.UP; + IronShulkerBoxType type = te.getType(); + + if (te.hasWorld()) + { + IBlockState iblockstate = this.getWorld().getBlockState(te.getPos()); - float shiftX; - float shiftY; - float shiftZ; - int shift = 0; - float blockScale = 0.70F; - float timeD = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks; + if (iblockstate.getBlock() instanceof BlockIronShulkerBox) + { + enumfacing = te.getFacing(); + type = iblockstate.getValue(BlockIronShulkerBox.VARIANT_PROP); + } + } - if (te.getTopItems().get(1).isEmpty()) + GlStateManager.enableDepth(); + GlStateManager.depthFunc(515); + GlStateManager.depthMask(true); + GlStateManager.disableCull(); + + if (destroyStage >= 0) { - shift = 8; - blockScale = 0.85F; + this.bindTexture(DESTROY_STAGES[destroyStage]); + GlStateManager.matrixMode(5890); + GlStateManager.pushMatrix(); + GlStateManager.scale(4.0F, 4.0F, 1.0F); + GlStateManager.translate(0.0625F, 0.0625F, 0.0625F); + GlStateManager.matrixMode(5888); + } + else + { + ResourceLocation rs = new ResourceLocation("ironchest", "textures/model/shulker/" + te.getColor().getName() + "/shulker_" + te.getColor().getName() + type.modelTexture); + + this.bindTexture(rs); } GlStateManager.pushMatrix(); - GlStateManager.translate((float) x, (float) y, (float) z); + GlStateManager.enableRescaleNormal(); - // CHANGE START: Don't init customItem - /* - if (customItem == null) + if (destroyStage < 0) { - customItem = new EntityItem(this.getWorld()); + GlStateManager.color(1.0F, 1.0F, 1.0F, alpha); } - customItem.hoverStart = 0F; - */ - // CHANGE END + GlStateManager.translate((float) x + 0.5F, (float) y + 1.5F, (float) z + 0.5F); + GlStateManager.scale(1.0F, -1.0F, -1.0F); + GlStateManager.translate(0.0F, 1.0F, 0.0F); + GlStateManager.scale(0.9995F, 0.9995F, 0.9995F); + GlStateManager.translate(0.0F, -1.0F, 0.0F); - for (ItemStack item : te.getTopItems()) + switch (enumfacing) { - if (shift > shifts.length || shift > 8) - { + case DOWN: + GlStateManager.translate(0.0F, 2.0F, 0.0F); + GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F); + case UP: + default: break; - } + case NORTH: + GlStateManager.translate(0.0F, 1.0F, 1.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + break; + case SOUTH: + GlStateManager.translate(0.0F, 1.0F, -1.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + break; + case WEST: + GlStateManager.translate(-1.0F, 1.0F, 0.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(-90.0F, 0.0F, 0.0F, 1.0F); + break; + case EAST: + GlStateManager.translate(1.0F, 1.0F, 0.0F); + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F); + } + + this.model.base.render(0.0625F); + GlStateManager.translate(0.0F, -te.getProgress(partialTicks) * 0.5F, 0.0F); + GlStateManager.rotate(270.0F * te.getProgress(partialTicks), 0.0F, 1.0F, 0.0F); + this.model.lid.render(0.0625F); + GlStateManager.enableCull(); + GlStateManager.disableRescaleNormal(); + GlStateManager.popMatrix(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + + if (destroyStage >= 0) + { + GlStateManager.matrixMode(5890); + GlStateManager.popMatrix(); + GlStateManager.matrixMode(5888); + } + + if (type == IronShulkerBoxType.CRYSTAL) + { + GlStateManager.enableCull(); + } + + if (type.isTransparent() && te.getDistanceSq(this.rendererDispatcher.entityX, this.rendererDispatcher.entityY, this.rendererDispatcher.entityZ) < 128d) + { + this.random.setSeed(254L); + + float shiftX; + float shiftY; + float shiftZ; + int shift = 0; + float blockScale = 0.70F; + float timeD = (float) (360D * (System.currentTimeMillis() & 0x3FFFL) / 0x3FFFL) - partialTicks; - if (item.isEmpty()) + if (te.getTopItems().get(1).isEmpty()) { - shift++; - continue; + shift = 8; + blockScale = 0.85F; } - shiftX = shifts[shift][0]; - shiftY = shifts[shift][1]; - shiftZ = shifts[shift][2]; - shift++; - GlStateManager.pushMatrix(); - GlStateManager.translate(shiftX, shiftY, shiftZ); - GlStateManager.rotate(timeD, 0F, 1F, 0F); - GlStateManager.scale(blockScale, blockScale, blockScale); - // CHANGE START: Don't use customItem and use built-in RenderItem + GlStateManager.translate((float) x, (float) y, (float) z); + + // CHANGE START: Don't init customItem /* - customItem.setItem(item); + if (customItem == null) + { + customItem = new EntityItem(this.getWorld()); + } - if (this.itemRenderer == null) + customItem.hoverStart = 0F; + */ + // CHANGE END + + for (ItemStack item : te.getTopItems()) { - this.itemRenderer = new RenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()) + if (shift > shifts.length || shift > 8) { - @Override - public int getModelCount(ItemStack stack) - { - return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1); - } + break; + } - @Override - public boolean shouldBob() - { - return false; - } + if (item.isEmpty()) + { + shift++; + continue; + } + + shiftX = shifts[shift][0]; + shiftY = shifts[shift][1]; + shiftZ = shifts[shift][2]; + shift++; + + GlStateManager.pushMatrix(); + GlStateManager.translate(shiftX, shiftY, shiftZ); + GlStateManager.rotate(timeD, 0F, 1F, 0F); + GlStateManager.scale(blockScale, blockScale, blockScale); + // CHANGE START: Don't use customItem and use built-in RenderItem + /* + customItem.setItem(item); - @Override - public boolean shouldSpreadItems() + if (this.itemRenderer == null) + { + this.itemRenderer = new RenderEntityItem(Minecraft.getMinecraft().getRenderManager(), Minecraft.getMinecraft().getRenderItem()) { - return true; - } - }; + @Override + public int getModelCount(ItemStack stack) + { + return SignedBytes.saturatedCast(Math.min(stack.getCount() / 32, 15) + 1); + } + + @Override + public boolean shouldBob() + { + return false; + } + + @Override + public boolean shouldSpreadItems() + { + return true; + } + }; + } + + this.itemRenderer.doRender(customItem, 0D, 0D, 0D, 0F, partialTicks); + */ + Minecraft.getMinecraft().getRenderItem().renderItem(item, ItemCameraTransforms.TransformType.GROUND); + // CHANGE END + + GlStateManager.popMatrix(); } - this.itemRenderer.doRender(customItem, 0D, 0D, 0D, 0F, partialTicks); - */ - Minecraft.getMinecraft().getRenderItem().renderItem(item, ItemCameraTransforms.TransformType.GROUND); - // CHANGE END - GlStateManager.popMatrix(); } - - GlStateManager.popMatrix(); } } From 96ea283daf88393fbb5a27344ba7440194f16725 Mon Sep 17 00:00:00 2001 From: jchung01 Date: Sat, 24 Aug 2024 11:05:12 -0700 Subject: [PATCH 4/5] Update configs, readme --- README.md | 9 ++- .../universaltweaks/config/UTConfigMods.java | 57 +++++++++++++++++-- .../universaltweaks/core/UTMixinLoader.java | 12 ++-- .../bibliocraft/mixin/UTBiblioCraftMixin.java | 1 + .../mixin/UTObeliskSpecialRendererMixin.java | 2 +- .../assets/universaltweaks/lang/en_us.lang | 3 + 6 files changed, 68 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index b4a62454..6cbde348 100644 --- a/README.md +++ b/README.md @@ -285,6 +285,8 @@ All changes are toggleable via config files. * **Improved Player Tick:** Improves AoA player ticking by only sending inventory changes when necessary * **Arcane Archives** * **Duplication Fixes:** Fixes various duplication exploits +* **Bibliocraft** + * **Disable Version Check:** Fixes client-side memory leak by disabling version check * **Binnie's Mods** * **Gather Windfall:** Allows Forestry farms to pick up ExtraTrees fruit * **Biomes O' Plenty** @@ -309,8 +311,9 @@ All changes are toggleable via config files. * **Collective** * **Memory Leak Fix:** Fixes memory leak when unloading worlds/switching dimensions * **Compact Machines** - * **Invisible Wall Render Fix:** Fixes some compact machine walls being invisible if [Nothirium](https://www.curseforge.com/minecraft/mc-mods/nothirium) 0.2.x (and up) or [Vintagium](https://github.com/Asek3/sodium-1.12) is installed * **Allowed Spawns Improvement:** Improves server performance by properly controlling spawn checks (effectiveness depends on CM's config) + * **Invisible Wall Render Fix:** Fixes some compact machine walls being invisible if [Nothirium](https://www.curseforge.com/minecraft/mc-mods/nothirium) 0.2.x (and up) or [Vintagium](https://github.com/Asek3/sodium-1.12) is installed + * **Memory Leak Fix:** Fixes client-side memory leak associated with miniaturization recipes * **Effortless Building** * **Block Transmutation Fix:** Fixes Effortless Building ignoring Metadata when checking for items in inventory * **Elementary Staffs** @@ -321,6 +324,8 @@ All changes are toggleable via config files. * **Sprinting Integration:** Configurable consumption of feathers when the player is sprinting * **Emojicord** * **Emoji Context:** Improves emoji context calculation to improve fps when rendering a lot of text +* **Ender IO** + * **Replace Obelisk Renderer:** Fixes client-side memory leak by replacing obelisk renderer with a simpler one * **Ender Storage** * **Fix Frequency Tracking:** Fixes storage frequencies being tracked multiple times * **Epic Siege Mod** @@ -348,6 +353,8 @@ All changes are toggleable via config files. * **Sticky Pedestal Compatibility:** Enables compatibility between Infernal Mobs' Sticky effect and Reliquary's Pedestal * **Iron Backpacks** * **Duplication Fixes:** Fixes various duplication exploits +* **Iron Chests** + * **Replace Crystal Chest/Shulker Renderer:** Fixes client-side memory leak by replacing the crystal chest/shulker box renderer with a simpler one (Note: Disables stack size rendering) * **Item Stages** * **Ingredient Matching:** Changes item matching code to CraftTweaker's ingredient matching system, fixes item NBT issues * **Mekanism** diff --git a/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java b/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java index d88b7441..dffba1c7 100644 --- a/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java +++ b/src/main/java/mod/acgaming/universaltweaks/config/UTConfigMods.java @@ -35,6 +35,10 @@ public class UTConfigMods @Config.Name("Advent of Ascension") public static final AOACategory AOA = new AOACategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.bibliocraft") + @Config.Name("BiblioCraft") + public static final BiblioCraftCategory BIBLIOCRAFT = new BiblioCraftCategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.bop") @Config.Name("Biomes O' Plenty") public static final BiomesOPlentyCategory BIOMES_O_PLENTY = new BiomesOPlentyCategory(); @@ -91,6 +95,10 @@ public class UTConfigMods @Config.Name("Emojicord") public static final EmojicordCategory EMOJICORD = new EmojicordCategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.enderio") + @Config.Name("Ender IO") + public static final EnderIOCategory ENDER_IO = new EnderIOCategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.enderstorage") @Config.Name("Ender Storage") public static final EnderStorageCategory ENDER_STORAGE = new EnderStorageCategory(); @@ -127,6 +135,10 @@ public class UTConfigMods @Config.Name("Iron Backpacks") public static final IronBackpacksCategory IRON_BACKPACKS = new IronBackpacksCategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.ironchests") + @Config.Name("Iron Chests") + public static final IronChestsCategory IRON_CHESTS = new IronChestsCategory(); + @Config.LangKey("cfg.universaltweaks.modintegration.itemstages") @Config.Name("Item Stages") public static final ItemStagesCategory ITEM_STAGES = new ItemStagesCategory(); @@ -306,6 +318,14 @@ public static class AOACategory public boolean utImprovedPlayerTickToggle = true; } + public static class BiblioCraftCategory + { + @Config.RequiresMcRestart + @Config.Name("Disable Version Check") + @Config.Comment("Fixes client-side memory leak by disabling version check") + public boolean utDisableVersionCheckToggle = true; + } + public static class BiomesOPlentyCategory { @Config.RequiresMcRestart @@ -399,11 +419,6 @@ public static class CollectiveCategory public static class CompactMachinesCoreCategory { - @Config.RequiresMcRestart - @Config.Name("Invisible Wall Render Fix") - @Config.Comment("Fixes some compact machine walls being invisible if Nothirium 0.2.x (and up) or Vintagium is installed") - public boolean utCMRenderFixToggle = true; - @Config.RequiresMcRestart @Config.Name("Allowed Spawns Improvement") @Config.Comment @@ -413,6 +428,16 @@ public static class CompactMachinesCoreCategory "Does nothing if both config values are true" }) public boolean utAllowedSpawnsImprovementToggle = true; + + @Config.RequiresMcRestart + @Config.Name("Invisible Wall Render Fix") + @Config.Comment("Fixes some compact machine walls being invisible if Nothirium 0.2.x (and up) or Vintagium is installed") + public boolean utCMRenderFixToggle = true; + + @Config.RequiresMcRestart + @Config.Name("Memory Leak Fix") + @Config.Comment("Fixes client-side memory leak associated with miniaturization recipes") + public boolean utMemoryLeakFixToggle = true; } public static class EffortlessBuildingCategory @@ -465,6 +490,14 @@ public static class EmojicordCategory public boolean utEmojiContextToggle = true; } + public static class EnderIOCategory + { + @Config.RequiresMcRestart + @Config.Name("Replace Obelisk Renderer") + @Config.Comment("Fixes client-side memory leak by replacing obelisk renderer with a simpler one") + public boolean utReplaceItemRenderer = true; + } + public static class EnderStorageCategory { @Config.RequiresMcRestart @@ -620,6 +653,18 @@ public static class IronBackpacksCategory public boolean utDuplicationFixesToggle = true; } + public static class IronChestsCategory + { + @Config.RequiresMcRestart + @Config.Name("Replace Crystal Chest/Shulker Renderer") + @Config.Comment + ({ + "Fixes client-side memory leak by replacing the crystal chest/shulker box renderer with a simpler one", + "Note: Stack sizes are not rendered, similar to modern versions of this mod" + }) + public boolean utReplaceItemRenderer = true; + } + public static class ItemStagesCategory { @Config.RequiresMcRestart @@ -1047,7 +1092,7 @@ public static class TinkersConstructCategory @Config.LangKey("cfg.universaltweaks.modintegration.tcon.toolcustomization") @Config.Name("Tool Customization") - public final TinkersConstructCategory.ToolCustomizationCategory TOOL_CUSTOMIZATION = new TinkersConstructCategory.ToolCustomizationCategory(); + public final ToolCustomizationCategory TOOL_CUSTOMIZATION = new ToolCustomizationCategory(); public static class ToolCustomizationCategory { diff --git a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java index 9149182f..abc47618 100644 --- a/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java +++ b/src/main/java/mod/acgaming/universaltweaks/core/UTMixinLoader.java @@ -18,18 +18,14 @@ public class UTMixinLoader implements ILateMixinLoader private static final Map> clientsideMixinConfigs = ImmutableMap.copyOf(new HashMap>() { { - // TODO: add config - put("mixins.mods.bibliocraft.json", () -> loaded("bibliocraft")); + put("mixins.mods.bibliocraft.json", () -> loaded("bibliocraft") && UTConfigMods.BIBLIOCRAFT.utDisableVersionCheckToggle); put("mixins.mods.cbmultipart.client.json", () -> loaded("forgemultipartcbe") && UTConfigMods.CB_MULTIPART.utMemoryLeakFixToggle); - // TODO: add config - put("mixins.mods.compactmachines.memory.json", () -> loaded("compactmachines3")); + put("mixins.mods.compactmachines.memory.json", () -> loaded("compactmachines3") && UTConfigMods.COMPACT_MACHINES.utMemoryLeakFixToggle); put("mixins.mods.compactmachines.render.json", () -> loaded("compactmachines3") && UTConfigMods.COMPACT_MACHINES.utCMRenderFixToggle); put("mixins.mods.crafttweaker.json", () -> loaded("crafttweaker")); - // TODO: add config - put("mixins.mods.enderio.json", () -> loaded("enderio")); + put("mixins.mods.enderio.json", () -> loaded("enderio") && UTConfigMods.ENDER_IO.utReplaceItemRenderer); put("mixins.mods.hwyla.json", () -> loaded("waila")); - // TODO: add config - put("mixins.mods.ironchests.json", () -> loaded("ironchest")); + put("mixins.mods.ironchests.json", () -> loaded("ironchest") && UTConfigMods.IRON_CHESTS.utReplaceItemRenderer); put("mixins.mods.modularrouters.json", () -> loaded("modularrouters") && UTConfigMods.MODULAR_ROUTERS.utParticleThreadToggle); put("mixins.mods.roost.json", () -> loaded("roost") && loaded("contenttweaker")); put("mixins.mods.storagedrawers.client.json", () -> loaded("storagedrawers")); diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java index 21f9b6bd..9bd514ec 100644 --- a/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java +++ b/src/main/java/mod/acgaming/universaltweaks/mods/bibliocraft/mixin/UTBiblioCraftMixin.java @@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +// Courtesy of jchung01 @Mixin(value = BiblioCraft.class, remap = false) public class UTBiblioCraftMixin { diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java index 49cbe66f..579733e0 100644 --- a/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java +++ b/src/main/java/mod/acgaming/universaltweaks/mods/enderio/mixin/UTObeliskSpecialRendererMixin.java @@ -21,6 +21,7 @@ import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; +// Courtesy of jchung01 @Mixin(value = ObeliskSpecialRenderer.class, remap = false) public abstract class UTObeliskSpecialRendererMixin extends ManagedTESR { @@ -29,7 +30,6 @@ public abstract class UTObeliskSpecialRendererMixin ex private Random rand; @Shadow - @Nonnull protected abstract ItemStack getFloatingItem(T te); protected UTObeliskSpecialRendererMixin(Block block) diff --git a/src/main/resources/assets/universaltweaks/lang/en_us.lang b/src/main/resources/assets/universaltweaks/lang/en_us.lang index 4ea7577e..363f1c53 100644 --- a/src/main/resources/assets/universaltweaks/lang/en_us.lang +++ b/src/main/resources/assets/universaltweaks/lang/en_us.lang @@ -53,6 +53,7 @@ cfg.universaltweaks.modintegration.actuallyadditions=Actually Additions cfg.universaltweaks.modintegration.aoa=Advent of Ascension cfg.universaltweaks.modintegration.arcanearchives=Arcane Archives cfg.universaltweaks.modintegration.astralsorcery=Astral Sorcery +cfg.universaltweaks.modintegration.bibliocraft=BiblioCraft cfg.universaltweaks.modintegration.bm=Blood Magic cfg.universaltweaks.modintegration.bop=Biomes O' Plenty cfg.universaltweaks.modintegration.botania=Botania @@ -67,6 +68,7 @@ cfg.universaltweaks.modintegration.effortlessbuilding=Effortless Building cfg.universaltweaks.modintegration.elementarystaffs=Elementary Staffs cfg.universaltweaks.modintegration.elenaidodge2=Elenai Dodge 2 cfg.universaltweaks.modintegration.emojicord=Emojicord +cfg.universaltweaks.modintegration.enderio=Ender IO cfg.universaltweaks.modintegration.enderstorage=Ender Storage cfg.universaltweaks.modintegration.erebus=The Erebus cfg.universaltweaks.modintegration.esm=Epic Siege Mod @@ -76,6 +78,7 @@ cfg.universaltweaks.modintegration.industrialcraft=IndustrialCraft 2 cfg.universaltweaks.modintegration.industrialforegoing=Industrial Foregoing cfg.universaltweaks.modintegration.infernalmobs=Infernal Mobs cfg.universaltweaks.modintegration.ironbackpacks=Iron Backpacks +cfg.universaltweaks.modintegration.ironchests=Iron Chests cfg.universaltweaks.modintegration.itemstages=Item Stages cfg.universaltweaks.modintegration.mekanism=Mekanism cfg.universaltweaks.modintegration.mobstages=Mob Stages From 7ee377360d2caa2661e682c441cbee6833f094e4 Mon Sep 17 00:00:00 2001 From: jchung01 Date: Sat, 24 Aug 2024 11:09:10 -0700 Subject: [PATCH 5/5] Move DummyWorld --- .../mods/compactmachines/{ => render}/DummyWorld.java | 2 +- .../mods/compactmachines/render/mixin/UTProxyWorldMixin.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/{ => render}/DummyWorld.java (96%) diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/DummyWorld.java similarity index 96% rename from src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java rename to src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/DummyWorld.java index d7b444d2..975a51f4 100644 --- a/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/DummyWorld.java +++ b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/DummyWorld.java @@ -1,4 +1,4 @@ -package mod.acgaming.universaltweaks.mods.compactmachines; +package mod.acgaming.universaltweaks.mods.compactmachines.render; import javax.annotation.Nonnull; import javax.annotation.Nullable; diff --git a/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/mixin/UTProxyWorldMixin.java b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/mixin/UTProxyWorldMixin.java index adaac9cb..7d10df00 100644 --- a/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/mixin/UTProxyWorldMixin.java +++ b/src/main/java/mod/acgaming/universaltweaks/mods/compactmachines/render/mixin/UTProxyWorldMixin.java @@ -21,7 +21,7 @@ import net.minecraftforge.fml.common.Optional; import net.minecraftforge.fml.relauncher.FMLLaunchHandler; -import mod.acgaming.universaltweaks.mods.compactmachines.DummyWorld; +import mod.acgaming.universaltweaks.mods.compactmachines.render.DummyWorld; import org.dave.compactmachines3.world.ProxyWorld; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At;