From 4ea7b864a86cea367abaef7c43ead49cc88a5302 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:00:37 -0400 Subject: [PATCH 1/4] Add facility to hide mixin options outside dev --- .../annotation/IgnoreOutsideDev.java | 15 ++++++++++++++ .../core/config/ModernFixEarlyConfig.java | 20 ++++++++++++------- .../rewrite_registry/ForgeRegistryMixin.java | 2 ++ .../ForgeRegistrySnapshotMixin.java | 2 ++ 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 common/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java diff --git a/common/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java b/common/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java new file mode 100644 index 00000000..ae4307c3 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/annotation/IgnoreOutsideDev.java @@ -0,0 +1,15 @@ +package org.embeddedt.modernfix.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The config system will ignore mixins with this annotation when generating config options unless running + * in a dev environment. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.TYPE) +public @interface IgnoreOutsideDev { +} diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index ad237a34..fc965085 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -8,10 +8,14 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; +import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.Mixin; import java.io.*; import java.nio.charset.StandardCharsets; @@ -47,9 +51,10 @@ public class ModernFixEarlyConfig { return ModernFixPlatformHooks.modPresent(modId); } - private static final String MIXIN_DESC = "Lorg/spongepowered/asm/mixin/Mixin;"; - private static final String MIXIN_CLIENT_ONLY_DESC = "Lorg/embeddedt/modernfix/annotation/ClientOnlyMixin;"; - private static final String MIXIN_REQUIRES_MOD_DESC = "Lorg/embeddedt/modernfix/annotation/RequiresMod;"; + private static final String MIXIN_DESC = Mixin.class.descriptorString(); + private static final String MIXIN_CLIENT_ONLY_DESC = ClientOnlyMixin.class.descriptorString(); + private static final String MIXIN_REQUIRES_MOD_DESC = RequiresMod.class.descriptorString(); + private static final String MIXIN_DEV_ONLY_DESC = IgnoreOutsideDev.class.descriptorString(); private static final Pattern PLATFORM_PREFIX = Pattern.compile("(forge|fabric|common)\\."); @@ -92,7 +97,7 @@ public class ModernFixEarlyConfig { reader.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); if(node.invisibleAnnotations == null) return; - boolean isMixin = false, isClientOnly = false, requiredModPresent = true; + boolean isMixin = false, isClientOnly = false, requiredModPresent = true, isDevOnly = false; String requiredModId = ""; for(AnnotationNode annotation : node.invisibleAnnotations) { if(Objects.equals(annotation.desc, MIXIN_DESC)) { @@ -110,9 +115,11 @@ public class ModernFixEarlyConfig { break; } } + } else if(Objects.equals(annotation.desc, MIXIN_DEV_ONLY_DESC)) { + isDevOnly = true; } } - if(isMixin) { + if(isMixin && (!isDevOnly || ModernFixPlatformHooks.isDevEnv())) { String mixinClassName = sanitize(node.name.replace('/', '.')).replace("org.embeddedt.modernfix.mixin.", ""); if(!requiredModPresent) mixinsMissingMods.put(mixinClassName, requiredModId); @@ -157,9 +164,8 @@ public class ModernFixEarlyConfig { private static final ImmutableMap DEFAULT_SETTING_OVERRIDES = new DefaultSettingMapBuilder() .put("mixin.perf.dynamic_resources", false) .put("mixin.feature.direct_stack_trace", false) - .put("mixin.perf.rewrite_registry", false) + .putConditionally(ModernFixPlatformHooks::isDevEnv, "mixin.perf.rewrite_registry", false) .put("mixin.perf.clear_mixin_classinfo", false) - .put("mixin.perf.compress_blockstate", false) .put("mixin.bugfix.packet_leak", false) .put("mixin.perf.deduplicate_location", false) .put("mixin.feature.integrated_server_watchdog", true) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistryMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistryMixin.java index 621db8c5..1e955230 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistryMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistryMixin.java @@ -6,6 +6,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.IForgeRegistryEntry; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; import org.embeddedt.modernfix.forge.registry.FastForgeRegistry; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -17,6 +18,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(value = ForgeRegistry.class, remap = false) +@IgnoreOutsideDev public class ForgeRegistryMixin> { @Shadow @Final diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java index 8421e5cf..a538a112 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java @@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.registries.ForgeRegistry; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -16,6 +17,7 @@ import java.util.Map; import java.util.Set; @Mixin(ForgeRegistry.Snapshot.class) +@IgnoreOutsideDev public class ForgeRegistrySnapshotMixin { @Shadow @Final @Mutable public Map ids; From 546d1df48f643b86e91389a733767775a3ffe698 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:13:01 -0400 Subject: [PATCH 2/4] Prevent mixin.perf suboptions from defaulting to on if an explicit option is not added --- .../embeddedt/modernfix/core/ModernFixMixinPlugin.java | 6 +++++- .../modernfix/core/config/ModernFixEarlyConfig.java | 9 ++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java index c27995f1..ca2fb8ca 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -97,7 +97,11 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { Option option = instance.config.getEffectiveOptionForMixin(mixin); if (option == null) { - this.logger.error("No rules matched mixin '{}', treating as foreign and disabling!", mixin); + String msg = "No rules matched mixin '{}', treating as foreign and disabling!"; + if(ModernFixPlatformHooks.isDevEnv()) + this.logger.error(msg, mixin); + else + this.logger.debug(msg, mixin); return false; } diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index fc965085..8c0f40db 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -128,10 +128,17 @@ public class ModernFixEarlyConfig { List mixinOptionNames = dotSplitter.splitToList(mixinClassName); StringBuilder optionBuilder = new StringBuilder(mixinClassName.length()); optionBuilder.append("mixin"); + // mixin.core, mixin.safety can be top-level, everything else must have a subcategory + boolean allowTopLevel; + if(mixinOptionNames.size() > 0) + allowTopLevel = mixinOptionNames.get(0).equals("core") || mixinOptionNames.get(0).equals("safety"); + else + allowTopLevel = false; for(int i = 0; i < mixinOptionNames.size() - 1; i++) { optionBuilder.append('.'); optionBuilder.append(mixinOptionNames.get(i)); - mixinOptions.add(optionBuilder.toString()); + if(i > 0 || allowTopLevel) + mixinOptions.add(optionBuilder.toString()); } } } catch(IOException e) { From 4537f86bbcff84dae467ad4e2a764e923b41c906 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:40:22 -0400 Subject: [PATCH 3/4] Add mod menu in dev --- fabric/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric/build.gradle b/fabric/build.gradle index a17fb87f..070eba7d 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -39,7 +39,7 @@ dependencies { modIncludeImplementation(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modIncludeImplementation(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } - modCompileOnly("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false } + modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false } modImplementation "curse.maven:spark-361579:${rootProject.spark_fabric_version}" modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}") { exclude group: 'net.fabricmc', module: 'fabric-loader' } // Remove the next line if you don't want to depend on the API From bd351197b22bc9ba663e65b2fae919f161b315bf Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:23:11 -0400 Subject: [PATCH 4/4] Backport https://github.com/MinecraftForge/MinecraftForge/pull/8959 to 1.18 --- .../main/resources/modernfix.accesswidener | 3 ++- .../LevelStorageSourceMixin.java | 27 +++++++++++++++++++ .../RegistryLoaderMixin.java | 27 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/LevelStorageSourceMixin.java create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/RegistryLoaderMixin.java diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index bccdbe43..babf2c36 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -30,4 +30,5 @@ accessible field net/minecraft/server/MinecraftServer resources Lnet/minecraft/s accessible class net/minecraft/server/MinecraftServer$ReloadableResources accessible method net/minecraft/client/gui/screens/Screen addRenderableWidget (Lnet/minecraft/client/gui/components/events/GuiEventListener;)Lnet/minecraft/client/gui/components/events/GuiEventListener; accessible field net/minecraft/client/KeyMapping ALL Ljava/util/Map; -accessible field net/minecraft/server/packs/resources/MultiPackResourceManager namespacedManagers Ljava/util/Map; \ No newline at end of file +accessible field net/minecraft/server/packs/resources/MultiPackResourceManager namespacedManagers Ljava/util/Map; +accessible field net/minecraft/resources/RegistryOps registryAccess Lnet/minecraft/core/RegistryAccess; \ No newline at end of file diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/LevelStorageSourceMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/LevelStorageSourceMixin.java new file mode 100644 index 00000000..42514369 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/LevelStorageSourceMixin.java @@ -0,0 +1,27 @@ +package org.embeddedt.modernfix.forge.mixin.bugfix.removed_dimensions; + +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.Lifecycle; +import net.minecraft.resources.RegistryOps; +import net.minecraft.world.level.levelgen.WorldGenSettings; +import net.minecraft.world.level.storage.LevelStorageSource; +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.CallbackInfoReturnable; + +@Mixin(LevelStorageSource.class) +public class LevelStorageSourceMixin { + @Inject(method = "readWorldGenSettings", at = @At(value = "INVOKE", target = "Lcom/mojang/serialization/Codec;parse(Lcom/mojang/serialization/Dynamic;)Lcom/mojang/serialization/DataResult;")) + private static void freezeRegistriesBeforeParsing(Dynamic nbt, DataFixer fixer, int version, CallbackInfoReturnable> cir) { + DynamicOps var10 = nbt.getOps(); + if (var10 instanceof RegistryOps ops) { + ops.registryAccess.ownedRegistries().forEach((e) -> { + e.value().freeze(); + }); + } + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/RegistryLoaderMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/RegistryLoaderMixin.java new file mode 100644 index 00000000..dfa7d4a5 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/removed_dimensions/RegistryLoaderMixin.java @@ -0,0 +1,27 @@ +package org.embeddedt.modernfix.forge.mixin.bugfix.removed_dimensions; + +import com.google.gson.JsonElement; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.WritableRegistry; +import net.minecraft.resources.RegistryLoader; +import net.minecraft.resources.ResourceKey; +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.CallbackInfoReturnable; + +@Mixin(RegistryLoader.class) +public class RegistryLoaderMixin { + @Inject(method = "overrideElementFromResources", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/WritableRegistry;getOrCreateHolder(Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/core/Holder;", ordinal = 0), cancellable = true) + private void handleErroringHolder(WritableRegistry arg, ResourceKey> arg2, Codec codec, ResourceKey arg3, DynamicOps dynamicOps, CallbackInfoReturnable>> cir) { + try { + arg.getOrCreateHolder(arg3); + } catch(RuntimeException e) { + cir.setReturnValue(DataResult.error("Missing holder for " + arg3)); + } + } +}