From 8c061ec0703a9358a664c6d5b1b64c48ad116403 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 30 May 2023 10:27:47 -0400 Subject: [PATCH 1/8] Support new REI version Related: #116 --- .../searchtree/REIBackedSearchTree.java | 69 +++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) 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 da92a2d0..fdd5f3d0 100644 --- a/common/src/main/java/org/embeddedt/modernfix/searchtree/REIBackedSearchTree.java +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/REIBackedSearchTree.java @@ -1,22 +1,28 @@ package org.embeddedt.modernfix.searchtree; +import com.google.common.base.Predicates; 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 me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl; +import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper; import net.minecraft.client.searchtree.ReloadableIdSearchTree; import net.minecraft.world.item.ItemStack; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class REIBackedSearchTree extends DummySearchTree { - private final AsyncSearchManager searchManager = new AsyncSearchManager(EntryRegistry.getInstance()::getPreFilteredList, () -> { - return stack -> true; - }, EntryStack::normalize); + private final AsyncSearchManager searchManager = createSearchManager(); private final boolean filteringByTag; private String lastSearchText = ""; @@ -39,14 +45,23 @@ public class REIBackedSearchTree extends DummySearchTree { if(!pSearchText.equals(lastSearchText)) { listCache.clear(); this.searchManager.updateFilter(pSearchText); - List> stacks; + List stacks; try { stacks = this.searchManager.getNow(); } catch(RuntimeException e) { ModernFix.LOGGER.error("Couldn't search for '" + pSearchText + "'", e); stacks = Collections.emptyList(); } - for(EntryStack stack : stacks) { + for(Object o : stacks) { + EntryStack stack; + if(o instanceof EntryStack) + stack = (EntryStack)o; + else if(o instanceof HashedEntryStackWrapper) { + stack = ((HashedEntryStackWrapper)o).unwrap(); + } else { + ModernFix.LOGGER.error("Don't know how to handle {}", o.getClass().getName()); + continue; + } if(stack.getType() == VanillaEntryTypes.ITEM) { listCache.add(stack.cheatsAs().getValue()); } @@ -56,6 +71,50 @@ public class REIBackedSearchTree extends DummySearchTree { return listCache; } + @SuppressWarnings({"unchecked", "rawtypes"}) + private static AsyncSearchManager createSearchManager() { + Method m, normalizeMethod; + try { + try { + m = EntryRegistryImpl.class.getDeclaredMethod("getPreFilteredComplexList"); + m.setAccessible(true); + normalizeMethod = HashedEntryStackWrapper.class.getDeclaredMethod("normalize"); + normalizeMethod.setAccessible(true); + } catch(NoSuchMethodException e) { + m = EntryRegistryImpl.class.getDeclaredMethod("getPreFilteredList"); + m.setAccessible(true); + normalizeMethod = EntryStack.class.getDeclaredMethod("normalize"); + normalizeMethod.setAccessible(true); + } + final MethodHandle getListMethod = MethodHandles.publicLookup().unreflect(m); + final MethodHandle normalize = MethodHandles.publicLookup().unreflect(normalizeMethod); + final EntryRegistryImpl registry = (EntryRegistryImpl)EntryRegistry.getInstance(); + Supplier stackListSupplier = () -> { + try { + return (List)getListMethod.invokeExact(registry); + } catch(Throwable e) { + if(e instanceof RuntimeException) + throw (RuntimeException)e; + throw new RuntimeException(e); + } + }; + UnaryOperator normalizeOperator = o -> { + try { + return normalize.invoke(o); + } catch(Throwable e) { + if(e instanceof RuntimeException) + throw (RuntimeException)e; + throw new RuntimeException(e); + } + }; + return new AsyncSearchManager(stackListSupplier, () -> { + return Predicates.alwaysTrue(); + }, normalizeOperator); + } catch(ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() { @Override public ReloadableIdSearchTree getSearchTree(boolean tag) { From 76485b0cbaa505daaa5acfe5bdfaa05a60d49a5e Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 30 May 2023 10:43:08 -0400 Subject: [PATCH 2/8] Fix Skyblock Builder crash Related: #117 --- .../embeddedt/modernfix/core/config/ModernFixEarlyConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ca7e9333..0be68db5 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 @@ -183,7 +183,7 @@ public class ModernFixEarlyConfig { disableIfModPresent("mixin.perf.thread_priorities", "smoothboot"); disableIfModPresent("mixin.perf.boost_worker_count", "smoothboot"); disableIfModPresent("mixin.perf.async_jei", "modernui"); - disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge"); + disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge" ,"skyblockbuilder"); disableIfModPresent("mixin.bugfix.mc218112", "performant"); disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant"); disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me"); From b15537a32f7b3bc6bab4ddf99991d9bf2955a1d8 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 31 May 2023 09:37:34 -0400 Subject: [PATCH 3/8] Make CanonizingStringMap not crash on null keys/values --- .../org/embeddedt/modernfix/util/CanonizingStringMap.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 05bd219b..1202500b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java @@ -141,6 +141,7 @@ public class CanonizingStringMap implements Map { } public static CanonizingStringMap deepCopy(CanonizingStringMap inputMap, Function deepCopier) { + Objects.requireNonNull(deepCopier); Object2ObjectMap copiedBackingMap; int size = inputMap.backingMap.size(); if(size > GROWTH_THRESHOLD) { @@ -148,7 +149,8 @@ public class CanonizingStringMap implements Map { } else copiedBackingMap = new Object2ObjectArrayMap<>(size); inputMap.backingMap.object2ObjectEntrySet().forEach(entry -> { - copiedBackingMap.put(entry.getKey(), deepCopier.apply(entry.getValue())); + if(entry.getKey() != null && entry.getValue() != null) + copiedBackingMap.put(entry.getKey(), deepCopier.apply(entry.getValue())); }); return new CanonizingStringMap<>(copiedBackingMap); } From 1a7d5b3436d7a01edb92f113576672e0bee44e46 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 1 Jun 2023 19:39:21 -0400 Subject: [PATCH 4/8] Decommission the chunk saving fix Does not actually fix the issue, sadly --- .../ChunkManagerMixin.java | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java deleted file mode 100644 index eff09266..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.bugfix.edge_chunk_not_saved; - -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.ImposterProtoChunk; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArg; - -import java.util.function.Predicate; - -/* https://github.com/SuperCoder7979/chunksavingfix-fabric/blob/main/src/main/java/supercoder79/chunksavingfix/mixin/MixinThreadedAnvilChunkStorage.java */ -@Mixin(ChunkMap.class) -public class ChunkManagerMixin { - // TODO: hits both at the moment- check and re-evaluate - @ModifyArg(method = "saveAllChunks(Z)V", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", ordinal = 0), require = 0) - private Predicate alwaysAccessibleFlush(Predicate chunkHolder) { - return c -> true; - } - @ModifyArg(method = "saveAllChunks(Z)V", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", ordinal = 1), require = 0) - private Predicate allowProtoChunkFlush(Predicate chunk) { - return c -> c instanceof ProtoChunk || c instanceof ImposterProtoChunk || c instanceof LevelChunk; - } - - @ModifyArg(method = "saveAllChunks(Z)V", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", ordinal = 3), require = 0) - private Predicate alwaysAccessible(Predicate chunkHolder) { - return c -> true; - } -} From 4b73d699e41fe6289aca1283137a2f6be20c5659 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 1 Jun 2023 19:45:19 -0400 Subject: [PATCH 5/8] Disable packet leak fix when MemoryLeakFix is present on Fabric --- .../modernfix/core/config/ModernFixEarlyConfig.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 0be68db5..543cb6b6 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 @@ -59,6 +59,8 @@ public class ModernFixEarlyConfig { private final Set mixinOptions = new ObjectOpenHashSet<>(); private final Map mixinsMissingMods = new Object2ObjectOpenHashMap<>(); + public static boolean isFabric = false; + public Map getPermanentlyDisabledMixins() { return mixinsMissingMods; } @@ -71,6 +73,8 @@ public class ModernFixEarlyConfig { if(stream == null) continue; try(Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + if(configFile.contains("fabric")) + isFabric = true; JsonObject configObject = (JsonObject)new JsonParser().parse(reader); JsonArray mixinList = configObject.getAsJsonArray("mixins"); String packageName = configObject.get("package").getAsString().replace('.', '/'); @@ -192,6 +196,9 @@ public class ModernFixEarlyConfig { disableIfModPresent("mixin.perf.faster_texture_stitching", "optifine"); disableIfModPresent("mixin.perf.datapack_reload_exceptions", "cyanide"); disableIfModPresent("mixin.perf.faster_texture_loading", "stitch", "optifine", "changed"); + if(isFabric) { + disableIfModPresent("mixin.bugfix.packet_leak", "memoryleakfix"); + } } private void disableIfModPresent(String configName, String... ids) { From c8bce3e015574dab49402e12b0dd21d0e8e19144 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 1 Jun 2023 19:54:18 -0400 Subject: [PATCH 6/8] Disable bugfix.chunk_deadlock for DimThread Related: #118 --- .../embeddedt/modernfix/core/config/ModernFixEarlyConfig.java | 2 ++ 1 file changed, 2 insertions(+) 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 543cb6b6..0f2e2b8c 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 @@ -191,6 +191,8 @@ public class ModernFixEarlyConfig { disableIfModPresent("mixin.bugfix.mc218112", "performant"); disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant"); disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me"); + // DimThread makes changes to the server chunk manager (understandably), C2ME probably does the same + disableIfModPresent("mixin.bugfix.chunk_deadlock", "c2me", "dimthread"); disableIfModPresent("mixin.perf.reuse_datapacks", "tac"); disableIfModPresent("mixin.launch.class_search_cache", "optifine"); disableIfModPresent("mixin.perf.faster_texture_stitching", "optifine"); From 39e1ac0896cd97fda8be36dac3e4e41ede42d248 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 1 Jun 2023 21:11:54 -0400 Subject: [PATCH 7/8] Simplify item rendering optimization Now uses a wrapped item model instead of actually modifying the rendering code, to avoid disabling Sodium's optimization --- .../ItemRendererMixin.java | 72 +++----------- .../modernfix/render/SimpleItemModelView.java | 94 +++++++++++++++++++ 2 files changed, 106 insertions(+), 60 deletions(-) create mode 100644 common/src/main/java/org/embeddedt/modernfix/render/SimpleItemModelView.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java index 9f936496..4ca3ff51 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/faster_item_rendering/ItemRendererMixin.java @@ -2,55 +2,33 @@ package org.embeddedt.modernfix.common.mixin.perf.faster_item_rendering; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import net.minecraft.client.color.item.ItemColors; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemTransform; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.SimpleBakedModel; -import net.minecraft.core.Direction; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import org.embeddedt.modernfix.render.FastItemRenderType; import org.embeddedt.modernfix.render.RenderState; -import org.spongepowered.asm.mixin.Final; +import org.embeddedt.modernfix.render.SimpleItemModelView; 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.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; -import java.util.Random; - -@Mixin(ItemRenderer.class) +@Mixin(value = ItemRenderer.class, priority = 600) public abstract class ItemRendererMixin { - @Shadow @Final private ItemColors itemColors; - - private final Random dummyRandom = new Random(); - - private static final float[] COLOR_MULTIPLIER = new float[]{1.0F, 1.0F, 1.0F, 1.0F}; - private ItemTransforms.TransformType transformType; + private final SimpleItemModelView modelView = new SimpleItemModelView(); @Inject(method = "render", at = @At("HEAD")) private void markRenderingType(ItemStack itemStack, ItemTransforms.TransformType transformType, boolean leftHand, PoseStack matrixStack, MultiBufferSource buffer, int combinedLight, int combinedOverlay, BakedModel model, CallbackInfo ci) { this.transformType = transformType; } - private static final Direction[] ITEM_DIRECTIONS = new Direction[] { Direction.SOUTH }; - private static final Direction[] BLOCK_DIRECTIONS = new Direction[] { Direction.UP, Direction.EAST, Direction.NORTH }; - - private boolean isCorrectDirectionForType(FastItemRenderType type, Direction direction) { - if(type == FastItemRenderType.SIMPLE_ITEM) - return direction == Direction.SOUTH; - else { - return direction == Direction.UP || direction == Direction.EAST || direction == Direction.NORTH; - } - } - /** * If a model * - is a vanilla item model (SimpleBakedModel), @@ -59,8 +37,8 @@ public abstract class ItemRendererMixin { * we do not need to go through the process of rendering every quad. Just render the south ones (the ones facing the * camera). */ - @Inject(method = "renderModelLists", at = @At("HEAD"), cancellable = true) - private void fasterItemRender(BakedModel model, ItemStack stack, int combinedLight, int combinedOverlay, PoseStack matrixStack, VertexConsumer buffer, CallbackInfo ci) { + @ModifyVariable(method = "renderModelLists", at = @At("HEAD"), index = 1, argsOnly = true) + private BakedModel useSimpleWrappedItemModel(BakedModel model, BakedModel arg, ItemStack stack, int combinedLight, int combinedOverlay, PoseStack matrixStack, VertexConsumer buffer) { if(!RenderState.IS_RENDERING_LEVEL && !stack.isEmpty() && model.getClass() == SimpleBakedModel.class && transformType == ItemTransforms.TransformType.GUI) { FastItemRenderType type; ItemTransform transform = model.getTransforms().gui; @@ -69,26 +47,12 @@ public abstract class ItemRendererMixin { else if(stack.getItem() instanceof BlockItem && isBlockTransforms(transform)) type = FastItemRenderType.SIMPLE_BLOCK; else - return; - ci.cancel(); - PoseStack.Pose pose = matrixStack.last(); - int[] combinedLights = new int[] {combinedLight, combinedLight, combinedLight, combinedLight}; - Direction[] directions = type == FastItemRenderType.SIMPLE_ITEM ? ITEM_DIRECTIONS : BLOCK_DIRECTIONS; - for(Direction direction : directions) { - List culledFaces = model.getQuads(null, direction, dummyRandom); - /* check size to avoid instantiating iterator when the list is empty */ - if(culledFaces.size() > 0) { - for(BakedQuad quad : culledFaces) { - render2dItemFace(quad, stack, buffer, pose, combinedLights, combinedOverlay); - } - } - } - List unculledFaces = model.getQuads(null, null, dummyRandom); - for(BakedQuad quad : unculledFaces) { - if(isCorrectDirectionForType(type, quad.getDirection())) - render2dItemFace(quad, stack, buffer, pose, combinedLights, combinedOverlay); - } - } + return model; + modelView.setItem(model); + modelView.setType(type); + return modelView; + } else + return model; } private boolean isBlockTransforms(ItemTransform transform) { @@ -96,16 +60,4 @@ public abstract class ItemRendererMixin { && transform.rotation.y() == 225f && transform.rotation.z() == 0f; } - - private void render2dItemFace(BakedQuad quad, ItemStack stack, VertexConsumer buffer, PoseStack.Pose pose, int[] combinedLights, int combinedOverlay) { - int i = -1; - if (quad.isTinted()) { - i = this.itemColors.getColor(stack, quad.getTintIndex()); - } - - float f = (float)(i >> 16 & 255) / 255.0F; - float f1 = (float)(i >> 8 & 255) / 255.0F; - float f2 = (float)(i & 255) / 255.0F; - buffer.putBulkData(pose, quad, COLOR_MULTIPLIER, f, f1, f2, combinedLights, combinedOverlay, true); - } } diff --git a/common/src/main/java/org/embeddedt/modernfix/render/SimpleItemModelView.java b/common/src/main/java/org/embeddedt/modernfix/render/SimpleItemModelView.java new file mode 100644 index 00000000..0b745c3f --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/render/SimpleItemModelView.java @@ -0,0 +1,94 @@ +package org.embeddedt.modernfix.render; + +import com.google.common.collect.ImmutableList; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Random; + +/** + * Wrapper class that presents a fake view of item models (only showing the simple front-facing quads), rather + * than every quad. + */ +public class SimpleItemModelView implements BakedModel { + private BakedModel wrappedItem; + private FastItemRenderType type; + + public void setItem(BakedModel model) { + this.wrappedItem = model; + } + + public void setType(FastItemRenderType type) { + this.type = type; + } + + private boolean isCorrectDirectionForType(Direction direction) { + if(type == FastItemRenderType.SIMPLE_ITEM) + return direction == Direction.SOUTH; + else { + return direction == Direction.UP || direction == Direction.EAST || direction == Direction.NORTH; + } + } + + private final List nullQuadList = new ObjectArrayList<>(); + + @Override + public List getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) { + if(side != null) { + return isCorrectDirectionForType(side) ? wrappedItem.getQuads(state, side, rand) : ImmutableList.of(); + } else { + nullQuadList.clear(); + List realList = wrappedItem.getQuads(state, null, rand); + for(int i = 0; i < realList.size(); i++) { + BakedQuad quad = realList.get(i); + if(isCorrectDirectionForType(quad.getDirection())) { + nullQuadList.add(quad); + } + } + return nullQuadList; + } + } + + @Override + public boolean useAmbientOcclusion() { + return wrappedItem.useAmbientOcclusion(); + } + + @Override + public boolean isGui3d() { + return wrappedItem.isGui3d(); + } + + @Override + public boolean usesBlockLight() { + return wrappedItem.usesBlockLight(); + } + + @Override + public boolean isCustomRenderer() { + return wrappedItem.isCustomRenderer(); + } + + @Override + public TextureAtlasSprite getParticleIcon() { + return wrappedItem.getParticleIcon(); + } + + @Override + public ItemTransforms getTransforms() { + return wrappedItem.getTransforms(); + } + + @Override + public ItemOverrides getOverrides() { + return wrappedItem.getOverrides(); + } +} From db223b62a088161d2f9858ce63cebbd5d50c01d3 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 2 Jun 2023 12:06:34 -0400 Subject: [PATCH 8/8] Advancement recursion speedup on Forge, based off Advancements Debug --- .../PlayerAdvancementsMixin.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/faster_advancements/PlayerAdvancementsMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/faster_advancements/PlayerAdvancementsMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/faster_advancements/PlayerAdvancementsMixin.java new file mode 100644 index 00000000..a4ba971e --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/faster_advancements/PlayerAdvancementsMixin.java @@ -0,0 +1,65 @@ +package org.embeddedt.modernfix.forge.mixin.perf.faster_advancements; + +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import net.minecraft.advancements.Advancement; +import net.minecraft.advancements.AdvancementProgress; +import net.minecraft.server.PlayerAdvancements; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Map; +import java.util.Set; + +@Mixin(PlayerAdvancements.class) +public abstract class PlayerAdvancementsMixin { + + @Shadow protected abstract boolean shouldBeVisible(Advancement advancement); + + @Shadow @Final private Set visible; + + @Shadow @Final private Set visibilityChanged; + + @Shadow @Final private Map advancements; + + @Shadow @Final private Set progressChanged; + + /** + * Avoids checking the same advancement many times. + */ + private void ensureVisibilityDfs(Advancement advancement, Set visited) { + if(visited.add(advancement)) { + boolean bl = this.shouldBeVisible(advancement); + boolean bl2 = this.visible.contains(advancement); + if (bl && !bl2) { + this.visible.add(advancement); + this.visibilityChanged.add(advancement); + if (this.advancements.containsKey(advancement)) { + this.progressChanged.add(advancement); + } + } else if (!bl && bl2) { + this.visible.remove(advancement); + this.visibilityChanged.add(advancement); + } + + for(Advancement child : advancement.getChildren()) { + ensureVisibilityDfs(child, visited); + } + + Advancement parent = advancement.getParent(); + if (bl != bl2 && parent != null) { + ensureVisibilityDfs(parent, visited); + } + } + } + + /** + * @author embeddedt + * @reason avoid checking the same advancement many times + */ + @Overwrite + private void ensureVisibility(Advancement advancement) { + ensureVisibilityDfs(advancement, new ReferenceOpenHashSet<>()); + } +}