Merge remote-tracking branch 'origin/1.19.4' into 1.20
This commit is contained in:
commit
30bf3afc1d
|
|
@ -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}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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 <T> void populateSearchTree(SearchRegistry.Key<T> key, List<T> 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<ItemStack> nameSupplier = list -> provider.getSearchTree(false);
|
||||
SearchRegistry.TreeBuilderSupplier<ItemStack> 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Block, BlockState> {
|
||||
protected BlockStateBaseMixin(Block object, ImmutableMap<Property<?>, Comparable<?>> immutableMap, MapCodec<BlockState> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 -> {};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<String, Boolean> DEFAULT_SETTING_OVERRIDES = ImmutableMap.<String, Boolean>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();
|
||||
|
|
|
|||
|
|
@ -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<CommandDispatcher<CommandSourceStack>> handler) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier<ItemStack> nameSupplier, SearchRegistry.TreeBuilderSupplier<ItemStack> tagSupplier, BiConsumer<SearchRegistry.Key<ItemStack>, List<ItemStack>> populator) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<T> implements RefreshableSearchTree<T> {
|
|||
public List<T> search(String pSearchText) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
||||
|
||||
@Override
|
||||
public RefreshableSearchTree<ItemStack> getSearchTree(boolean tag) {
|
||||
return new DummySearchTree<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Dummy";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ItemStack> {
|
|||
private String lastSearchText = "";
|
||||
private final List<ItemStack> 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<ItemStack> {
|
|||
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<ItemStack> {
|
|||
private List<ItemStack> searchJEI(IngredientFilter filter, String pSearchText) {
|
||||
if(!pSearchText.equals(lastSearchText)) {
|
||||
listCache.clear();
|
||||
List<ITypedIngredient<?>> ingredients = ((IngredientFilterInvoker)filter).invokeGetIngredientListUncached(filteringByTag ? ("$" + pSearchText) : pSearchText);
|
||||
List<ITypedIngredient<?>> ingredients;
|
||||
String finalSearchTerm = filteringByTag ? ("$" + pSearchText) : pSearchText;
|
||||
try {
|
||||
ingredients = (List<ITypedIngredient<?>>)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<ItemStack> {
|
|||
}
|
||||
return listCache;
|
||||
}
|
||||
|
||||
public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
||||
@Override
|
||||
public RefreshableSearchTree<ItemStack> 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";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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<ItemStack> {
|
|||
}
|
||||
return listCache;
|
||||
}
|
||||
|
||||
public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
||||
@Override
|
||||
public RefreshableSearchTree<ItemStack> getSearchTree(boolean tag) {
|
||||
return new REIBackedSearchTree(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
return ModernFixPlatformHooks.modPresent("roughlyenoughitems");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "REI";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Provider> 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<ItemStack> getSearchTree(boolean tag);
|
||||
boolean canUse();
|
||||
String getName();
|
||||
}
|
||||
}
|
||||
|
|
@ -77,11 +77,15 @@ public class CanonizingStringMap<T> implements Map<String, T> {
|
|||
public void putAll(@NotNull Map<? extends String, ? extends T> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<CommandDispatcher<CommandSourceStack>> handler) {
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, arg, env) -> handler.accept(dispatcher));
|
||||
}
|
||||
|
||||
public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier<ItemStack> nameSupplier, SearchRegistry.TreeBuilderSupplier<ItemStack> tagSupplier, BiConsumer<SearchRegistry.Key<ItemStack>, List<ItemStack>> populator) {
|
||||
/* no-op on Fabric */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ITypedIngredient<?>> invokeGetIngredientListUncached(String filterText);
|
||||
}
|
||||
|
|
@ -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 <T> void populateSearchTree(SearchRegistry.Key<T> arg, List<T> list);
|
||||
|
||||
@Inject(method = "createSearchTrees", at = @At("HEAD"), cancellable = true)
|
||||
private void replaceSearchTrees(CallbackInfo ci) {
|
||||
ci.cancel();
|
||||
Optional<? extends ModContainer> jeiContainer = ModList.get().getModContainerById("jei");
|
||||
SearchRegistry.TreeBuilderSupplier<ItemStack> 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<ItemStack> nameKey : CreativeModeTabSearchRegistry.getNameSearchKeys().values()) {
|
||||
this.searchRegistry.register(nameKey, nameSupplier);
|
||||
}
|
||||
this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, tagSupplier);
|
||||
for(SearchRegistry.Key<ItemStack> tagKey : CreativeModeTabSearchRegistry.getTagSearchKeys().values()) {
|
||||
this.searchRegistry.register(tagKey, tagSupplier);
|
||||
}
|
||||
Map<CreativeModeTab, SearchRegistry.Key<ItemStack>> tagSearchKeys = CreativeModeTabSearchRegistry.getTagSearchKeys();
|
||||
CreativeModeTabSearchRegistry.getNameSearchKeys().forEach((tab, nameSearchKey) -> {
|
||||
SearchRegistry.Key<ItemStack> tagSearchKey = tagSearchKeys.get(tab);
|
||||
tab.setSearchTreeBuilder((contents) -> {
|
||||
this.populateSearchTree(nameSearchKey, contents);
|
||||
this.populateSearchTree(tagSearchKey, contents);
|
||||
});
|
||||
});
|
||||
this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>());
|
||||
}
|
||||
}
|
||||
|
|
@ -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<WorldDataConfiguration> consumer) {
|
||||
/* no-op */
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> 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("<init>")) {
|
||||
ListIterator<AbstractInsnNode> 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<CommandDispatcher<CommandSourceStack>> handler) {
|
||||
|
|
@ -131,4 +99,21 @@ public class ModernFixPlatformHooksImpl {
|
|||
handler.accept(event.getDispatcher());
|
||||
});
|
||||
}
|
||||
|
||||
public static void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier<ItemStack> nameSupplier, SearchRegistry.TreeBuilderSupplier<ItemStack> tagSupplier, BiConsumer<SearchRegistry.Key<ItemStack>, List<ItemStack>> populator) {
|
||||
for(SearchRegistry.Key<ItemStack> nameKey : CreativeModeTabSearchRegistry.getNameSearchKeys().values()) {
|
||||
registry.register(nameKey, nameSupplier);
|
||||
}
|
||||
for(SearchRegistry.Key<ItemStack> tagKey : CreativeModeTabSearchRegistry.getTagSearchKeys().values()) {
|
||||
registry.register(tagKey, tagSupplier);
|
||||
}
|
||||
Map<CreativeModeTab, SearchRegistry.Key<ItemStack>> tagSearchKeys = CreativeModeTabSearchRegistry.getTagSearchKeys();
|
||||
CreativeModeTabSearchRegistry.getNameSearchKeys().forEach((tab, nameSearchKey) -> {
|
||||
SearchRegistry.Key<ItemStack> tagSearchKey = tagSearchKeys.get(tab);
|
||||
tab.setSearchTreeBuilder((contents) -> {
|
||||
populator.accept(nameSearchKey, contents);
|
||||
populator.accept(tagSearchKey, contents);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user