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 1b635a8f..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/edge_chunk_not_saved/ChunkManagerMixin.java +++ /dev/null @@ -1,33 +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 org.spongepowered.asm.mixin.injection.Redirect; - -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; - } - - @Redirect(method = "saveChunkIfNeeded", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkHolder;wasAccessibleSinceLastSave()Z"), require = 0) - private boolean alwaysAccessible(ChunkHolder chunkHolder) { - return true; - } -} 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 5857cc44..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.util.RandomSource; 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; - -@Mixin(ItemRenderer.class) +@Mixin(value = ItemRenderer.class, priority = 600) public abstract class ItemRendererMixin { - @Shadow @Final private ItemColors itemColors; - - private final RandomSource dummyRandom = RandomSource.createNewThreadLocalInstance(); - - 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/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 8ecd0453..c375e443 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('.', '/'); @@ -178,15 +182,20 @@ 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"); + // 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"); 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) { 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..b1a27b0f --- /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.util.RandomSource; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * 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, RandomSource 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(); + } +} 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); }