From de5b79fe7cde35db376213b6296e7116cdc817ff Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 7 Dec 2024 21:44:12 -0500 Subject: [PATCH 1/7] Fix model parents not always being resolved This would cause models to sometimes not appear at all (CC turtles were one reproduction case) --- .../ModelBakerImplMixin.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakerImplMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakerImplMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakerImplMixin.java new file mode 100644 index 00000000..b465efdb --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ModelBakerImplMixin.java @@ -0,0 +1,39 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(ModelBakery.ModelBakerImpl.class) +@ClientOnlyMixin +public abstract class ModelBakerImplMixin { + @Shadow public abstract UnbakedModel getModel(ResourceLocation location); + + @Unique + private int mfix$getDepth = 0; + + /** + * @author embeddedt + * @reason force parent resolution to happen before model gets baked + */ + @ModifyReturnValue(method = "getModel", at = @At("RETURN")) + private UnbakedModel resolveParents(UnbakedModel model) { + mfix$getDepth++; + if(mfix$getDepth == 1) { + try { + model.resolveParents(this::getModel); + } catch(Exception e) { + ModernFix.LOGGER.warn("Exception encountered resolving parents", e); + } + } + mfix$getDepth--; + return model; + } +} From 14a89f94a63d68e855ec38da039363d0147c8147 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:28:01 -0500 Subject: [PATCH 2/7] Backport CTM mixin from 1.21 Related: #487 --- forge/build.gradle | 2 +- .../ctm/CTMModelBakeryAccessor.java | 16 ++++++++++++++++ .../ctm/TextureMetadataHandlerMixin.java | 9 +++++---- gradle.properties | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMModelBakeryAccessor.java diff --git a/forge/build.gradle b/forge/build.gradle index fb8c36f7..101dba1a 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -55,7 +55,7 @@ dependencies { modCompileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}") { transitive false } modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}") //modRuntimeOnly("curse.maven:ferritecore-429235:4441949") - modCompileOnly("team.chisel.ctm:CTM:${ctm_version}") + modCompileOnly("curse.maven:ctm-267602:${ctm_version}") modCompileOnly("curse.maven:supermartijncore-454372:4455391") modCompileOnly("vazkii.patchouli:Patchouli:1.19.2-77") diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMModelBakeryAccessor.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMModelBakeryAccessor.java new file mode 100644 index 00000000..16f2164a --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMModelBakeryAccessor.java @@ -0,0 +1,16 @@ +package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources.ctm; + +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBakery; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Map; + +@Mixin(ModelBakery.class) +@ClientOnlyMixin +public interface CTMModelBakeryAccessor { + @Accessor("bakedCache") + Map mfix$getBakedCache(); +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java index 9dc1644b..333c857d 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/TextureMetadataHandlerMixin.java @@ -20,7 +20,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import team.chisel.ctm.CTM; import team.chisel.ctm.api.model.IModelCTM; -import team.chisel.ctm.client.mixin.ModelBakerImplAccessor; import team.chisel.ctm.client.model.AbstractCTMBakedModel; import team.chisel.ctm.client.model.ModelCTM; import team.chisel.ctm.client.texture.IMetadataSectionCTM; @@ -39,7 +38,7 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte @Shadow(remap = false) @Nonnull protected abstract BakedModel wrap(UnbakedModel model, BakedModel object) throws IOException; - @Shadow(remap = false) @Final public static Multimap TEXTURES_SCRAPED; + @Shadow(remap = false) @Final private Multimap scrapedTextures; @Inject(method = "", at = @At("RETURN")) private void subscribeDynamic(CallbackInfo ci) { @@ -70,7 +69,7 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte continue; } - Collection textures = Sets.newHashSet(TEXTURES_SCRAPED.get(dep)); + Collection textures = Sets.newHashSet(scrapedTextures.get(dep)); Collection newDependencies = model.getDependencies(); for (Material tex : textures) { IMetadataSectionCTM meta = null; @@ -108,10 +107,12 @@ public abstract class TextureMetadataHandlerMixin implements ModernFixClientInte IModelCTM var10 = baked.getModel(); if (var10 instanceof ModelCTM ctmModel) { if (!ctmModel.isInitialized()) { + // Clear the baked cache as upstream CTM does + ((CTMModelBakeryAccessor)bakery).mfix$getBakedCache().clear(); Function spriteGetter = (m) -> { return Minecraft.getInstance().getModelManager().getAtlas(m.atlasLocation()).getSprite(m.texture()); }; - ModelBakery.ModelBakerImpl baker = ModelBakerImplAccessor.createImpl(bakery, ($, m) -> { + ModelBakery.ModelBakerImpl baker = bakery.new ModelBakerImpl(($, m) -> { return spriteGetter.apply(m); }, key); // bypass bakedCache so that dependent models get re-baked and thus retrieve their sprites again diff --git a/gradle.properties b/gradle.properties index 140abcfd..3c239fa4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ parchment_version=2023.07.09 refined_storage_version=4392788 jei_version=15.8.0.11 rei_version=11.0.597 -ctm_version=1.20.1-1.1.8+4 +ctm_version=5983309 kubejs_version=1902.6.0-build.142 rhino_version=1902.2.2-build.268 supported_minecraft_versions=1.20.1 From ba6d0d20fc68ce93b7e0e478d89dcf78a5377594 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:29:24 -0500 Subject: [PATCH 3/7] Stop looking for legacy cache file names Related: #485 --- .../embeddedt/modernfix/structure/CachingStructureManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java b/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java index 3b1c2101..98ffb095 100644 --- a/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java +++ b/common/src/main/java/org/embeddedt/modernfix/structure/CachingStructureManager.java @@ -70,8 +70,6 @@ public class CachingStructureManager { hasher.reset(); String hash = encodeHex(hasher.digest(structureBytes)); CompoundTag cachedUpgraded = getCachedUpgraded(location, truncateHash(hash)); - if(cachedUpgraded == null) - cachedUpgraded = getCachedUpgraded(location, hash); /* pick up old cache */ if(cachedUpgraded != null && cachedUpgraded.getInt("DataVersion") == requiredMinimumDataVersion) { ModernFix.LOGGER.debug("Using cached upgraded version of {}", location); currentTag = cachedUpgraded; From 639f0e2c1a763fff5531ee2016354d6c6bf88c1f Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:56:38 -0500 Subject: [PATCH 4/7] Force-override updateY to be public Related: #494 --- .../perf/worldgen_allocation/SurfaceRulesContextMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java index 346722d5..c2be9c3d 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/worldgen_allocation/SurfaceRulesContextMixin.java @@ -35,7 +35,7 @@ public class SurfaceRulesContextMixin { * @reason Reuse supplier object instead of creating new ones every time */ @Overwrite - protected void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockX, int blockY, int blockZ) { + public void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockX, int blockY, int blockZ) { ++this.lastUpdateY; var getter = this.biome; if(getter == null) { From 98e6af87c11902f1d957967d47e04e09b48a9b4a Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:00:32 -0500 Subject: [PATCH 5/7] Protect DynamicBakedModelProvider against null keys Related: #495 --- .../modernfix/dynamicresources/DynamicBakedModelProvider.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java index b602af14..d31ac804 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java @@ -145,6 +145,9 @@ public class DynamicBakedModelProvider implements Map Date: Mon, 23 Dec 2024 13:56:54 -0500 Subject: [PATCH 6/7] Detect Redirector and show warnings --- .../assets/modernfix/lang/en_us.json | 3 +- .../modernfix/forge/init/ModernFixForge.java | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index 7964db1c..7ab5e016 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -5,7 +5,8 @@ "modernfix.no_lazydfu": "LazyDFU is not installed. If Minecraft needs to update game data from an older version, there may be noticeable lag.", "modernfix.no_ferritecore": "FerriteCore is not installed. Memory usage will be very high.", "modernfix.connectedness_dynresoruces": "Connectedness and ModernFix's dynamic resources option are not compatible. Remove Connectedness or disable dynamic resources in the ModernFix config.", - "modernfix.perf_mod_warning": "It is recommended to install the mods, but the warning(s) can be disabled in the ModernFix config.", + "modernfix.perf_mod_warning": "ModernFix mod warnings can be disabled by turning off mixin.feature.warn_missing_perf_mods in the ModernFix config.", + "modernfix.redirector_installed": "ModernFix detected that Redirector is installed. Redirector is known to cause many strange and hard-to-debug issues, and removing it is strongly recommended.", "modernfix.config": "ModernFix mixin config", "modernfix.config.done_restart": "Done (restart required)", "modernfix.config.wiki": "Open wiki", diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixForge.java b/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixForge.java index 347619d0..43c5ac4e 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixForge.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixForge.java @@ -24,6 +24,7 @@ import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegisterEvent; import net.minecraftforge.server.ServerLifecycleHooks; import org.apache.commons.lang3.tuple.Pair; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler; @@ -89,6 +90,28 @@ public class ModernFixForge { Pair.of(ImmutableList.of("ferritecore"), "modernfix.no_ferritecore") ); + /** + * Redirector 5.0 redirects ALL Enum.values() calls to use a cached array, which breaks any code that mutates + * the given array, and causes all sorts of impossible to debug issues in mods. We complain loudly when it is + * installed now. + */ + private static boolean hasDangerousRedirectorInstalled() { + try { + var clz = Class.forName("com.teampotato.redirector.RedirectorLaunchPluginService"); + var pkg = clz.getPackage(); + if (pkg != null) { + String implVer = pkg.getImplementationVersion(); + var artifactVer = new DefaultArtifactVersion(implVer); + return artifactVer.getMajorVersion() == 5; + } + } catch(Exception e) { + if (!(e instanceof ClassNotFoundException)) { + ModernFix.LOGGER.error("Error detecting Redirector", e); + } + } + return false; + } + @SubscribeEvent public void commonSetup(FMLCommonSetupEvent event) { if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.warn_missing_perf_mods.Warnings")) { @@ -101,6 +124,11 @@ public class ModernFixForge { ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, warning.getRight())); } } + if (hasDangerousRedirectorInstalled()) { + ModernFix.LOGGER.fatal("Redirector 5.x is detected, it is known to cause extremely hard-to-debug issues in other mods"); + ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, "modernfix.redirector_installed")); + atLeastOneWarning = true; + } if(atLeastOneWarning) ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.COMMON_SETUP, "modernfix.perf_mod_warning")); }); From 0b8eddbf25b6019de018d7bd8be77551734427fa Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 25 Dec 2024 15:45:11 -0500 Subject: [PATCH 7/7] Replace RS integration with generic model registry emulation Fixes patterns not rendering Related: #499 --- .../dynresources/ModelBakeEventHelper.java | 1 + .../rs/ClientSetupMixin.java | 38 ------------------- 2 files changed, 1 insertion(+), 38 deletions(-) delete mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java index 3462c43e..fbfdab18 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java @@ -44,6 +44,7 @@ public class ModelBakeEventHelper { "vampirism", "elevatorid", "cfm", + "refinedstorage", "embers"); private final Map modelRegistry; private final Set topLevelModelLocations; diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java deleted file mode 100644 index e7865e4a..00000000 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources.rs; - -import com.refinedmods.refinedstorage.render.BakedModelOverrideRegistry; -import com.refinedmods.refinedstorage.setup.ClientSetup; -import net.minecraft.client.resources.model.*; -import net.minecraft.resources.ResourceLocation; -import org.embeddedt.modernfix.ModernFixClient; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.annotation.RequiresMod; -import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; -import org.spongepowered.asm.mixin.Final; -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; - - -@Mixin(ClientSetup.class) -@RequiresMod("refinedstorage") -@ClientOnlyMixin -public class ClientSetupMixin { - @Shadow(remap = false) @Final private static BakedModelOverrideRegistry BAKED_MODEL_OVERRIDE_REGISTRY; - - @Inject(method = "registerBakedModelOverrides", at = @At("RETURN"), remap = false) - private static void addDynamicListener(CallbackInfo ci) { - ModernFixClient.CLIENT_INTEGRATIONS.add(new ModernFixClientIntegration() { - @Override - public BakedModel onBakedModelLoad(ResourceLocation location, UnbakedModel baseModel, BakedModel originalModel, ModelState state, ModelBakery bakery) { - BakedModelOverrideRegistry.BakedModelOverrideFactory factory = BAKED_MODEL_OVERRIDE_REGISTRY.get(location instanceof ModelResourceLocation ? new ResourceLocation(location.getNamespace(), location.getPath()) : location); - if(factory != null) - return factory.create(originalModel, bakery.getBakedTopLevelModels()); - else - return originalModel; - } - }); - } -}