diff --git a/common/build.gradle b/common/build.gradle index 9ed3b9ae..1476a95f 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -6,6 +6,8 @@ loom { accessWidenerPath = file("src/main/resources/modernfix.accesswidener") } +ext.jei_minecraft_version = "1.19.4" /* temporary, till 1.20 releases */ + dependencies { // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies // Do NOT use other classes from fabric loader @@ -23,6 +25,10 @@ dependencies { modCompileOnly("me.shedaniel:RoughlyEnoughItems-fabric:${rei_version}") { transitive = false } + // compile against the JEI API but do not include it at runtime + modCompileOnly("mezz.jei:jei-${jei_minecraft_version}-common:${jei_version}") + modCompileOnly("mezz.jei:jei-${jei_minecraft_version}-gui:${jei_version}") + modCompileOnly("mezz.jei:jei-${jei_minecraft_version}-lib:${jei_version}") // Remove the next line if you don't want to depend on the API // modApi "me.shedaniel:architectury:${rootProject.architectury_version}" } diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index c65a5ff8..7a020414 100644 --- a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -14,6 +14,9 @@ import net.minecraft.world.entity.Entity; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.packet.EntityIDSyncPacket; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import org.embeddedt.modernfix.searchtree.JEIBackedSearchTree; +import org.embeddedt.modernfix.searchtree.REIBackedSearchTree; +import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry; import org.embeddedt.modernfix.world.IntegratedWatchdog; import java.lang.management.ManagementFactory; @@ -36,6 +39,8 @@ public class ModernFixClient { if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) { brandingString = "ModernFix " + ModernFixPlatformHooks.getVersionString(); } + SearchTreeProviderRegistry.register(JEIBackedSearchTree.PROVIDER); + SearchTreeProviderRegistry.register(REIBackedSearchTree.PROVIDER); } public void resetWorldLoadStateMachine() { diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java new file mode 100644 index 00000000..cfc92448 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/packet_leak/ClientPlayNetHandlerMixin.java @@ -0,0 +1,23 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.packet_leak; + +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.duck.IClientNetHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ClientPacketListener.class) +@ClientOnlyMixin +public class ClientPlayNetHandlerMixin { + /** + * @author embeddedt + * @reason allow the other function to track use of the buffer + */ + @Redirect(method = "handleCustomPayload", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/game/ClientboundCustomPayloadPacket;getData()Lnet/minecraft/network/FriendlyByteBuf;")) + private FriendlyByteBuf saveCopyForRelease(ClientboundCustomPayloadPacket instance) { + return ((IClientNetHandler)instance).getCopiedCustomBuffer(); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java new file mode 100644 index 00000000..33be2f09 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java @@ -0,0 +1,43 @@ +package org.embeddedt.modernfix.common.mixin.perf.blast_search_trees; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.searchtree.SearchRegistry; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import org.embeddedt.modernfix.searchtree.DummySearchTree; +import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry; +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; + +import java.util.List; +import java.util.Map; + +@Mixin(Minecraft.class) +@ClientOnlyMixin +public abstract class MinecraftMixin { + @Shadow @Final private SearchRegistry searchRegistry; + + @Shadow public abstract void populateSearchTree(SearchRegistry.Key key, List list); + + @Inject(method = "createSearchTrees", at = @At("HEAD"), cancellable = true) + private void replaceSearchTrees(CallbackInfo ci) { + SearchTreeProviderRegistry.Provider provider = SearchTreeProviderRegistry.getSearchTreeProvider(); + if(provider == null) + return; + ModernFix.LOGGER.info("Replacing search trees with '{}' provider", provider.getName()); + SearchRegistry.TreeBuilderSupplier nameSupplier = list -> provider.getSearchTree(false); + SearchRegistry.TreeBuilderSupplier tagSupplier = list -> provider.getSearchTree(true); + this.searchRegistry.register(SearchRegistry.CREATIVE_NAMES, nameSupplier); + this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, tagSupplier); + this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>()); + ModernFixPlatformHooks.registerCreativeSearchTrees(this.searchRegistry, nameSupplier, tagSupplier, this::populateSearchTree); + ci.cancel(); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compress_blockstate/BlockBehaviourMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compress_blockstate/BlockBehaviourMixin.java deleted file mode 100644 index 2f307825..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compress_blockstate/BlockBehaviourMixin.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.compress_blockstate; - -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; - -@Mixin(BlockBehaviour.class) -public class BlockBehaviourMixin { - @Overwrite(remap = false) - protected boolean isAir(BlockState state) { - return state.getBlock().properties.isAir; - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compress_blockstate/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compress_blockstate/BlockStateBaseMixin.java deleted file mode 100644 index 41ed07c7..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compress_blockstate/BlockStateBaseMixin.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.compress_blockstate; - -import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.MapCodec; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateHolder; -import net.minecraft.world.level.block.state.properties.Property; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(BlockBehaviour.BlockStateBase.class) -public abstract class BlockStateBaseMixin extends StateHolder { - protected BlockStateBaseMixin(Block object, ImmutableMap, Comparable> immutableMap, MapCodec mapCodec) { - super(object, immutableMap, mapCodec); - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;destroySpeed:F" - )) - private float getDestroyTime(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.destroyTime; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;requiresCorrectToolForDrops:Z" - )) - private boolean getRequiresTool(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.requiresCorrectToolForDrops; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;canOcclude:Z" - )) - private boolean getCanOcclude(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.canOcclude; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;isRedstoneConductor:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;" - )) - private BlockBehaviour.StatePredicate getRedstoneConductor(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.isRedstoneConductor; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;isSuffocating:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;" - )) - private BlockBehaviour.StatePredicate getSuffocating(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.isSuffocating; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;isViewBlocking:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;" - )) - private BlockBehaviour.StatePredicate getViewBlocking(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.isViewBlocking; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;hasPostProcess:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;" - )) - private BlockBehaviour.StatePredicate getPostProcess(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.hasPostProcess; - } - - @Redirect(method = "*", at = @At( - value = "FIELD", - opcode = Opcodes.GETFIELD, - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;emissiveRendering:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;" - )) - private BlockBehaviour.StatePredicate getEmissiveRendering(BlockBehaviour.BlockStateBase base) { - return this.owner.properties.emissiveRendering; - } -} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java index c72bd661..08b7c307 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlocksMixin.java @@ -4,14 +4,15 @@ import net.minecraft.world.level.block.Blocks; import org.embeddedt.modernfix.blockstate.BlockStateCacheHandler; 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; +import org.spongepowered.asm.mixin.injection.ModifyArg; -@Mixin(Blocks.class) +import java.util.function.Consumer; + +@Mixin(value = Blocks.class, priority = 1100) public class BlocksMixin { - @Inject(method = "rebuildCache", at = @At("HEAD"), cancellable = true) - private static void rebuildParallel(CallbackInfo ci) { - ci.cancel(); + @ModifyArg(method = "rebuildCache", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/IdMapper;forEach(Ljava/util/function/Consumer;)V"), index = 0) + private static Consumer getEmptyConsumer(Consumer original) { BlockStateCacheHandler.rebuildParallel(true); + return o -> {}; } } 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 1e49dcff..1d072c10 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 @@ -130,13 +130,8 @@ public class ModernFixEarlyConfig { } } - private static final boolean shouldReplaceSearchTrees; private static final boolean isDevEnv = ModernFixPlatformHooks.isDevEnv(); - static { - shouldReplaceSearchTrees = modPresent("jei"); - } - private static final ImmutableMap DEFAULT_SETTING_OVERRIDES = ImmutableMap.builder() .put("mixin.perf.dynamic_resources", false) .put("mixin.feature.direct_stack_trace", false) @@ -148,7 +143,6 @@ public class ModernFixEarlyConfig { .put("mixin.perf.dynamic_entity_renderers", false) .put("mixin.feature.integrated_server_watchdog", true) .put("mixin.perf.faster_item_rendering", false) - .put("mixin.perf.blast_search_trees", shouldReplaceSearchTrees) .put("mixin.devenv", isDevEnv) .put("mixin.perf.remove_spawn_chunks", isDevEnv) .build(); diff --git a/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java b/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java index 0c5d3234..960390aa 100644 --- a/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java +++ b/common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java @@ -2,12 +2,16 @@ package org.embeddedt.modernfix.platform; import dev.architectury.injectables.annotations.ExpectPlatform; import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.client.searchtree.SearchRegistry; import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; import org.objectweb.asm.tree.ClassNode; import java.nio.file.Path; +import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; public class ModernFixPlatformHooks { @@ -70,4 +74,9 @@ public class ModernFixPlatformHooks { public static void onServerCommandRegister(Consumer> handler) { throw new AssertionError(); } + + @ExpectPlatform + public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier nameSupplier, SearchRegistry.TreeBuilderSupplier tagSupplier, BiConsumer, List> populator) { + throw new AssertionError(); + } } diff --git a/common/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java index f4ef7104..a430faaf 100644 --- a/common/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/DummySearchTree.java @@ -1,6 +1,7 @@ package org.embeddedt.modernfix.searchtree; import net.minecraft.client.searchtree.RefreshableSearchTree; +import net.minecraft.world.item.ItemStack; import java.util.Collections; import java.util.List; @@ -22,4 +23,22 @@ public class DummySearchTree implements RefreshableSearchTree { public List search(String pSearchText) { return Collections.emptyList(); } + + static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() { + + @Override + public RefreshableSearchTree getSearchTree(boolean tag) { + return new DummySearchTree<>(); + } + + @Override + public boolean canUse() { + return true; + } + + @Override + public String getName() { + return "Dummy"; + } + }; } diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/searchtree/JEIBackedSearchTree.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java similarity index 50% rename from forge/src/main/java/org/embeddedt/modernfix/forge/searchtree/JEIBackedSearchTree.java rename to common/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java index 85c4839b..e237733a 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/searchtree/JEIBackedSearchTree.java +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/JEIBackedSearchTree.java @@ -1,15 +1,19 @@ -package org.embeddedt.modernfix.forge.searchtree; +package org.embeddedt.modernfix.searchtree; +import com.google.common.collect.ImmutableList; import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.gui.ingredients.IngredientFilter; import mezz.jei.gui.ingredients.IngredientFilterApi; import mezz.jei.library.runtime.JeiRuntime; +import net.minecraft.client.searchtree.RefreshableSearchTree; import net.minecraft.world.item.ItemStack; import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.forge.mixin.perf.blast_search_trees.IngredientFilterInvoker; -import org.embeddedt.modernfix.searchtree.DummySearchTree; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,7 +27,25 @@ public class JEIBackedSearchTree extends DummySearchTree { private String lastSearchText = ""; private final List listCache = new ArrayList<>(); - private static Field filterField = null; + private static final Field filterField; + private static final MethodHandle getIngredientListUncached; + + static { + MethodHandle m; + Field f; + try { + Method jeiMethod = IngredientFilter.class.getDeclaredMethod("getIngredientListUncached", String.class); + jeiMethod.setAccessible(true); + m = MethodHandles.lookup().unreflect(jeiMethod); + f = IngredientFilterApi.class.getDeclaredField("ingredientFilter"); + f.setAccessible(true); + } catch(ReflectiveOperationException | RuntimeException | NoClassDefFoundError e) { + m = null; + f = null; + } + getIngredientListUncached = m; + filterField = f; + } public JEIBackedSearchTree(boolean filteringByTag) { this.filteringByTag = filteringByTag; @@ -35,10 +57,6 @@ public class JEIBackedSearchTree extends DummySearchTree { IngredientFilterApi iFilterApi = (IngredientFilterApi)runtime.get().getIngredientFilter(); IngredientFilter filter; try { - if(filterField == null) { - filterField = IngredientFilterApi.class.getDeclaredField("ingredientFilter"); - filterField.setAccessible(true); - } filter = (IngredientFilter)filterField.get(iFilterApi); } catch(ReflectiveOperationException e) { ModernFix.LOGGER.error(e); @@ -54,7 +72,14 @@ public class JEIBackedSearchTree extends DummySearchTree { private List searchJEI(IngredientFilter filter, String pSearchText) { if(!pSearchText.equals(lastSearchText)) { listCache.clear(); - List> ingredients = ((IngredientFilterInvoker)filter).invokeGetIngredientListUncached(filteringByTag ? ("$" + pSearchText) : pSearchText); + List> ingredients; + String finalSearchTerm = filteringByTag ? ("$" + pSearchText) : pSearchText; + try { + ingredients = (List>)getIngredientListUncached.invokeExact(filter, finalSearchTerm); + } catch(Throwable e) { + ModernFix.LOGGER.error("Error searching", e); + ingredients = ImmutableList.of(); + } for(ITypedIngredient ingredient : ingredients) { if(ingredient.getIngredient() instanceof ItemStack) { listCache.add((ItemStack)ingredient.getIngredient()); @@ -64,4 +89,21 @@ public class JEIBackedSearchTree extends DummySearchTree { } return listCache; } + + public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() { + @Override + public RefreshableSearchTree getSearchTree(boolean tag) { + return new JEIBackedSearchTree(tag); + } + + @Override + public boolean canUse() { + return ModernFixPlatformHooks.modPresent("jei") && getIngredientListUncached != null && filterField != null; + } + + @Override + public String getName() { + return "JEI"; + } + }; } diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/searchtree/JEIRuntimeCapturer.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/JEIRuntimeCapturer.java similarity index 94% rename from forge/src/main/java/org/embeddedt/modernfix/forge/searchtree/JEIRuntimeCapturer.java rename to common/src/main/java/org/embeddedt/modernfix/searchtree/JEIRuntimeCapturer.java index c8c6bc6d..9a24b52e 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/searchtree/JEIRuntimeCapturer.java +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/JEIRuntimeCapturer.java @@ -1,4 +1,4 @@ -package org.embeddedt.modernfix.forge.searchtree; +package org.embeddedt.modernfix.searchtree; import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; diff --git a/common/src/main/java/org/embeddedt/modernfix/searchtree/REIBackedSearchTree.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/REIBackedSearchTree.java index 7bb9f954..f48bb6ac 100644 --- a/common/src/main/java/org/embeddedt/modernfix/searchtree/REIBackedSearchTree.java +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/REIBackedSearchTree.java @@ -4,8 +4,10 @@ import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.impl.client.search.AsyncSearchManager; +import net.minecraft.client.searchtree.RefreshableSearchTree; import net.minecraft.world.item.ItemStack; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import java.util.ArrayList; import java.util.Collections; @@ -53,4 +55,21 @@ public class REIBackedSearchTree extends DummySearchTree { } return listCache; } + + public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() { + @Override + public RefreshableSearchTree getSearchTree(boolean tag) { + return new REIBackedSearchTree(tag); + } + + @Override + public boolean canUse() { + return ModernFixPlatformHooks.modPresent("roughlyenoughitems"); + } + + @Override + public String getName() { + return "REI"; + } + }; } diff --git a/common/src/main/java/org/embeddedt/modernfix/searchtree/SearchTreeProviderRegistry.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/SearchTreeProviderRegistry.java new file mode 100644 index 00000000..81df5502 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/SearchTreeProviderRegistry.java @@ -0,0 +1,36 @@ +package org.embeddedt.modernfix.searchtree; + +import net.minecraft.client.searchtree.RefreshableSearchTree; +import net.minecraft.world.item.ItemStack; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; +import org.embeddedt.modernfix.core.config.Option; + +import java.util.ArrayList; +import java.util.List; + +public class SearchTreeProviderRegistry { + private static final List searchTreeProviders = new ArrayList<>(); + + public static synchronized Provider getSearchTreeProvider() { + for(Provider p : searchTreeProviders) { + if(p.canUse()) + return p; + } + Option option = ModernFixMixinPlugin.instance.config.getEffectiveOptionForMixin("perf.blast_search_trees.Registry"); + if(option != null && option.isOverridden()) + return DummySearchTree.PROVIDER; + else + return null; + } + + public static synchronized void register(Provider p) { + if(p.canUse()) + searchTreeProviders.add(p); + } + + public interface Provider { + RefreshableSearchTree getSearchTree(boolean tag); + boolean canUse(); + String getName(); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java index e5bb2f2d..05bd219b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java @@ -77,11 +77,15 @@ public class CanonizingStringMap implements Map { public void putAll(@NotNull Map map) { if(map.size() == 0) return; + // grow early if we know there are enough non-overlapping keys + if((map.size() - backingMap.size()) > GROWTH_THRESHOLD && !(backingMap instanceof Object2ObjectOpenHashMap)) { + backingMap = new Object2ObjectOpenHashMap<>(backingMap); + } map.forEach((String key, T val) -> { key = KEY_INTERNER.intern(key); backingMap.put(key, val); }); - // if it's too big to be an array, grow it + // if it's still an array, and now too big, grow it if(backingMap.size() > GROWTH_THRESHOLD && !(backingMap instanceof Object2ObjectOpenHashMap)) { backingMap = new Object2ObjectOpenHashMap<>(backingMap); } diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index bf92766d..344227a9 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -12,15 +12,6 @@ accessible field net/minecraft/client/renderer/texture/Stitcher$Holder width I accessible field net/minecraft/client/renderer/texture/Stitcher$Holder height I accessible field net/minecraft/network/syncher/EntityDataAccessor id I mutable field net/minecraft/network/syncher/EntityDataAccessor id I -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isAir Z -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties destroyTime F -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties requiresCorrectToolForDrops Z -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties canOcclude Z -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isRedstoneConductor Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isSuffocating Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties isViewBlocking Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties hasPostProcess Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; -accessible field net/minecraft/world/level/block/state/BlockBehaviour$Properties emissiveRendering Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate; accessible class net/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException accessible field net/minecraft/network/syncher/SynchedEntityData itemsById Lit/unimi/dsi/fastutil/ints/Int2ObjectMap; accessible field net/minecraft/network/syncher/SynchedEntityData ENTITY_ID_POOL Lit/unimi/dsi/fastutil/objects/Object2IntMap; diff --git a/fabric/build.gradle b/fabric/build.gradle index 47220caf..0a7f2f6c 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -35,6 +35,7 @@ dependencies { modIncludeImplementation(fabricApi.module("fabric-command-api-v2", 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' } + modImplementation(fabricApi.module("fabric-data-generation-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modCompileOnly("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false } // Remove the next line if you don't want to depend on the API // modApi "me.shedaniel:architectury-fabric:${rootProject.architectury_version}" diff --git a/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java index b7f8db62..7fd97b77 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixClientFabric.java @@ -4,7 +4,9 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.Minecraft; +import org.embeddedt.modernfix.fabric.datagen.RuntimeDatagen; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,5 +31,8 @@ public class ModernFixClientFabric implements ClientModInitializer { ServerLifecycleEvents.SERVER_STARTED.register(server -> { commonMod.onServerStarted(server); }); + if(FabricLoader.getInstance().isModLoaded("fabric-data-generation-api-v1")) { + RuntimeDatagen.init(); + } } } diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/datagen/RuntimeDatagen.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/datagen/RuntimeDatagen.java new file mode 100644 index 00000000..82863666 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/datagen/RuntimeDatagen.java @@ -0,0 +1,40 @@ +package org.embeddedt.modernfix.fabric.datagen; + +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.network.chat.Component; +import org.embeddedt.modernfix.ModernFix; + +import java.lang.reflect.Method; + +public class RuntimeDatagen { + private static final boolean SHOULD_RUNTIME_DATAGEN = System.getProperty("fabric-api.datagen.output-dir") != null; + + private static void runRuntimeDatagen() { + // call runInternal directly to avoid exiting immediately + try { + System.setProperty("fabric-api.datagen", "true"); + Method method = FabricDataGenHelper.class.getDeclaredMethod("runInternal"); + method.setAccessible(true); + method.invoke(null); + } catch(Throwable e) { + ModernFix.LOGGER.error("Error running datagen", e); + } finally { + System.clearProperty("fabric-api.datagen"); + } + } + + public static void init() { + if(!SHOULD_RUNTIME_DATAGEN) + return; + ScreenEvents.AFTER_INIT.register(((client, s, scaledWidth, scaledHeight) -> { + if(s instanceof TitleScreen screen) { + screen.addRenderableWidget(Button.builder(Component.literal("DG"), (arg) -> { + runRuntimeDatagen(); + }).pos(screen.width / 2 - 100 - 50, screen.height / 4 + 48).size(50, 20).build()); + } + })); + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java index 0639d6c1..f6441b48 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakerImplMixin.java @@ -88,7 +88,8 @@ public abstract class ModelBakerImplMixin { if(arg != ModelBakery.MISSING_MODEL_LOCATION && debugDynamicModelLoading) ModernFix.LOGGER.warn("Model {} not present", arg); wasMissingModel = true; - } + } else + wasMissingModel = false; /* sometimes this runs more than once e.g. for recursive model baking */ cir.getReturnValue().resolveParents(this.field_40571::getModel); } diff --git a/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java b/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java index 01857624..f10a53a9 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java @@ -5,13 +5,17 @@ import net.fabricmc.api.EnvType; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; +import net.minecraft.client.searchtree.SearchRegistry; import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; import org.embeddedt.modernfix.ModernFixFabric; import org.objectweb.asm.tree.*; import java.nio.file.Path; +import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Consumer; public class ModernFixPlatformHooksImpl { @@ -67,4 +71,8 @@ public class ModernFixPlatformHooksImpl { public static void onServerCommandRegister(Consumer> handler) { CommandRegistrationCallback.EVENT.register((dispatcher, arg, env) -> handler.accept(dispatcher)); } + + public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier nameSupplier, SearchRegistry.TreeBuilderSupplier tagSupplier, BiConsumer, List> populator) { + /* no-op on Fabric */ + } } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 7b3901e5..598db739 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -22,7 +22,8 @@ "client": [ "org.embeddedt.modernfix.ModernFixClientFabric" ], - "modmenu": [ "org.embeddedt.modernfix.fabric.modmenu.ModernFixModMenuApiImpl" ] + "modmenu": [ "org.embeddedt.modernfix.fabric.modmenu.ModernFixModMenuApiImpl" ], + "jei_mod_plugin": [ "org.embeddedt.modernfix.searchtree.JEIRuntimeCapturer"] }, "mixins": [ "modernfix-fabric.mixins.json", diff --git a/forge/build.gradle b/forge/build.gradle index c2332fca..8a60e93f 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -38,13 +38,8 @@ dependencies { modCompileOnly("curse.maven:refinedstorage-243076:${refined_storage_version}") - // compile against the JEI API but do not include it at runtime - modCompileOnly("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") - - modCompileOnly("mezz.jei:jei-${minecraft_version}-forge:${jei_version}") - modCompileOnly("curse.maven:jeresources-240630:3951643") - modCompileOnly "me.shedaniel:RoughlyEnoughItems-forge:${rei_version}" + 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}") diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java index 428145b7..af3c25bd 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java @@ -1,6 +1,7 @@ package org.embeddedt.modernfix.forge.mixin.core; import net.minecraft.server.Bootstrap; +import net.minecraftforge.network.NetworkConstants; import org.slf4j.Logger; import org.embeddedt.modernfix.forge.load.ModWorkManagerQueue; import org.spongepowered.asm.mixin.Final; @@ -23,4 +24,10 @@ public class BootstrapMixin { ModWorkManagerQueue.replace(); } } + + /* for https://github.com/MinecraftForge/MinecraftForge/issues/9505 */ + @Inject(method = "bootStrap", at = @At("RETURN")) + private static void doClassloadHack(CallbackInfo ci) { + NetworkConstants.init(); + } } diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/blast_search_trees/IngredientFilterInvoker.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/blast_search_trees/IngredientFilterInvoker.java deleted file mode 100644 index ef67771c..00000000 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/blast_search_trees/IngredientFilterInvoker.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.embeddedt.modernfix.forge.mixin.perf.blast_search_trees; - -import mezz.jei.api.ingredients.ITypedIngredient; -import mezz.jei.gui.ingredients.IngredientFilter; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -import java.util.List; - -@Mixin(IngredientFilter.class) -public interface IngredientFilterInvoker { - @Invoker(remap = false) - List> invokeGetIngredientListUncached(String filterText); -} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/blast_search_trees/MinecraftMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/blast_search_trees/MinecraftMixin.java deleted file mode 100644 index f5f41f92..00000000 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/blast_search_trees/MinecraftMixin.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.embeddedt.modernfix.forge.mixin.perf.blast_search_trees; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.searchtree.SearchRegistry; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.client.CreativeModeTabSearchRegistry; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModList; -import org.embeddedt.modernfix.ModernFix; -import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.searchtree.DummySearchTree; -import org.embeddedt.modernfix.searchtree.REIBackedSearchTree; -import org.embeddedt.modernfix.forge.searchtree.JEIBackedSearchTree; -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; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -@Mixin(Minecraft.class) -@ClientOnlyMixin -public abstract class MinecraftMixin { - @Shadow @Final private SearchRegistry searchRegistry; - - @Shadow public abstract void populateSearchTree(SearchRegistry.Key arg, List list); - - @Inject(method = "createSearchTrees", at = @At("HEAD"), cancellable = true) - private void replaceSearchTrees(CallbackInfo ci) { - ci.cancel(); - Optional jeiContainer = ModList.get().getModContainerById("jei"); - SearchRegistry.TreeBuilderSupplier nameSupplier, tagSupplier; - if(ModList.get().isLoaded("roughlyenoughitems")) { - ModernFix.LOGGER.info("Replaced creative search logic with REI"); - nameSupplier = list -> new REIBackedSearchTree(false); - tagSupplier = list -> new REIBackedSearchTree(true); - } else if(jeiContainer.isPresent()) { - ModernFix.LOGGER.info("Replaced creative search logic with JEI"); - nameSupplier = list -> new JEIBackedSearchTree(false); - tagSupplier = list -> new JEIBackedSearchTree(true); - } else { - ModernFix.LOGGER.info("Replaced creative search logic with dummy implementation"); - nameSupplier = tagSupplier = list -> new DummySearchTree<>(); - } - this.searchRegistry.register(SearchRegistry.CREATIVE_NAMES, nameSupplier); - for(SearchRegistry.Key nameKey : CreativeModeTabSearchRegistry.getNameSearchKeys().values()) { - this.searchRegistry.register(nameKey, nameSupplier); - } - this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, tagSupplier); - for(SearchRegistry.Key tagKey : CreativeModeTabSearchRegistry.getTagSearchKeys().values()) { - this.searchRegistry.register(tagKey, tagSupplier); - } - Map> tagSearchKeys = CreativeModeTabSearchRegistry.getTagSearchKeys(); - CreativeModeTabSearchRegistry.getNameSearchKeys().forEach((tab, nameSearchKey) -> { - SearchRegistry.Key tagSearchKey = tagSearchKeys.get(tab); - tab.setSearchTreeBuilder((contents) -> { - this.populateSearchTree(nameSearchKey, contents); - this.populateSearchTree(tagSearchKey, contents); - }); - }); - this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>()); - } -} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/skip_first_datapack_reload/CreateWorldScreenMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/skip_first_datapack_reload/CreateWorldScreenMixin.java deleted file mode 100644 index 5655dc2e..00000000 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/skip_first_datapack_reload/CreateWorldScreenMixin.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.embeddedt.modernfix.forge.mixin.perf.skip_first_datapack_reload; - -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; -import net.minecraft.client.gui.screens.worldselection.WorldCreationContext; -import net.minecraft.network.chat.Component; -import net.minecraft.server.packs.repository.PackRepository; -import net.minecraft.world.level.WorldDataConfiguration; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.function.Consumer; - -@Mixin(CreateWorldScreen.class) -public abstract class CreateWorldScreenMixin extends Screen { - protected CreateWorldScreenMixin(Component arg) { - super(arg); - } - // TODO: incorporate https://github.com/MinecraftForge/MinecraftForge/pull/9454 - @ModifyArg(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/CreateWorldScreen;createDefaultLoadConfig(Lnet/minecraft/server/packs/repository/PackRepository;Lnet/minecraft/world/level/WorldDataConfiguration;)Lnet/minecraft/server/WorldLoader$InitConfig;"), index = 1) - private static WorldDataConfiguration useDefaultConfiguration(WorldDataConfiguration config) { - return WorldDataConfiguration.DEFAULT; - } - - @Redirect(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldCreationContext;withDataConfiguration(Lnet/minecraft/world/level/WorldDataConfiguration;)Lnet/minecraft/client/gui/screens/worldselection/WorldCreationContext;")) - private static WorldCreationContext sameDataConfiguration(WorldCreationContext context, WorldDataConfiguration config) { - return context; - } - - @Redirect(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/CreateWorldScreen;tryApplyNewDataPacks(Lnet/minecraft/server/packs/repository/PackRepository;ZLjava/util/function/Consumer;)V")) - private static void skipReapply(CreateWorldScreen screen, PackRepository repository, boolean bl, Consumer consumer) { - /* no-op */ - } -} diff --git a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java index 60240a84..487c42aa 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java +++ b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java @@ -1,11 +1,14 @@ package org.embeddedt.modernfix.platform.forge; -import cpw.mods.modlauncher.api.INameMappingService; import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.client.searchtree.SearchRegistry; import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.CreativeModeTabSearchRegistry; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.fml.ModLoader; @@ -13,23 +16,21 @@ import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.LoadingModList; import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator; -import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.server.ServerLifecycleHooks; -import org.embeddedt.modernfix.forge.classloading.FastAccessTransformerList; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; +import org.embeddedt.modernfix.forge.classloading.FastAccessTransformerList; import org.embeddedt.modernfix.forge.packet.PacketHandler; import org.embeddedt.modernfix.util.DummyList; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.*; +import org.objectweb.asm.tree.ClassNode; import org.spongepowered.asm.mixin.injection.struct.InjectorGroupInfo; import java.lang.reflect.Field; import java.nio.file.Path; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class ModernFixPlatformHooksImpl { public static boolean isClient() { @@ -90,40 +91,7 @@ public class ModernFixPlatformHooksImpl { } public static void applyASMTransformers(String mixinClassName, ClassNode targetClass) { - if(mixinClassName.equals("org.embeddedt.modernfix.common.compress_blockstate.perf.mixin.BlockStateBaseMixin")) { - // Delete unused fields off BlockStateBase - Set fieldsToDelete = Stream.of( - "field_235702_f_", // isAir - "field_235703_g_", // material - "field_235705_i_", // destroySpeed - "field_235706_j_", // requiresCorrectToolForDrops - "field_235707_k_", // canOcclude - "field_235708_l_", // isRedstoneConductor - "field_235709_m_", // isSuffocating - "field_235710_n_", // isViewBlocking - "field_235711_o_", // hasPostProcess - "field_235712_p_" // emissiveRendering - ).map(name -> ObfuscationReflectionHelper.remapName(INameMappingService.Domain.FIELD, name)).collect(Collectors.toSet()); - targetClass.fields.removeIf(field -> { - if(fieldsToDelete.contains(field.name)) { - return true; - } - return false; - }); - for(MethodNode m : targetClass.methods) { - if(m.name.equals("")) { - ListIterator iter = m.instructions.iterator(); - while(iter.hasNext()) { - AbstractInsnNode node = iter.next(); - if(node.getOpcode() == Opcodes.PUTFIELD) { - if(fieldsToDelete.contains(((FieldInsnNode)node).name)) { - iter.remove(); - } - } - } - } - } - } + } public static void onServerCommandRegister(Consumer> handler) { @@ -131,4 +99,21 @@ public class ModernFixPlatformHooksImpl { handler.accept(event.getDispatcher()); }); } + + public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier nameSupplier, SearchRegistry.TreeBuilderSupplier tagSupplier, BiConsumer, List> populator) { + for(SearchRegistry.Key nameKey : CreativeModeTabSearchRegistry.getNameSearchKeys().values()) { + registry.register(nameKey, nameSupplier); + } + for(SearchRegistry.Key tagKey : CreativeModeTabSearchRegistry.getTagSearchKeys().values()) { + registry.register(tagKey, tagSupplier); + } + Map> tagSearchKeys = CreativeModeTabSearchRegistry.getTagSearchKeys(); + CreativeModeTabSearchRegistry.getNameSearchKeys().forEach((tab, nameSearchKey) -> { + SearchRegistry.Key tagSearchKey = tagSearchKeys.get(tab); + tab.setSearchTreeBuilder((contents) -> { + populator.accept(nameSearchKey, contents); + populator.accept(tagSearchKey, contents); + }); + }); + } } diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index 5dc798cb..29a2c07a 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -40,7 +40,7 @@ modId = "forge" #mandatory # Does this dependency have to exist - if not, ordering below must be specified mandatory = true #mandatory # The version range of the dependency -versionRange = "[45,)" #mandatory +versionRange = "[45.0.63,)" #mandatory # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory ordering = "NONE" # Side this dependency is applied on - BOTH, CLIENT or SERVER