diff --git a/src/main/java/org/embeddedt/modernfix/ModernFix.java b/src/main/java/org/embeddedt/modernfix/ModernFix.java index 26f09211..ff5863e2 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -38,6 +38,9 @@ public class ModernFix { public static ModernFix INSTANCE; + // Used to skip computing the blockstate caches twice + public static boolean runningFirstInjection = false; + public ModernFix() { INSTANCE = this; diff --git a/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java b/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java new file mode 100644 index 00000000..208a4c1a --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/duck/IBlockState.java @@ -0,0 +1,7 @@ +package org.embeddedt.modernfix.duck; + +import org.embeddedt.modernfix.util.BakeReason; + +public interface IBlockState { + void clearCache(); +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/AbstractBlockStateMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/AbstractBlockStateMixin.java new file mode 100644 index 00000000..5832ab59 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/AbstractBlockStateMixin.java @@ -0,0 +1,18 @@ +package org.embeddedt.modernfix.mixin; + +import net.minecraft.block.AbstractBlock; +import org.embeddedt.modernfix.duck.IBlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import javax.annotation.Nullable; + +@Mixin(AbstractBlock.AbstractBlockState.class) +public class AbstractBlockStateMixin implements IBlockState { + @Shadow @Nullable protected AbstractBlock.AbstractBlockState.Cache cache; + + @Override + public void clearCache() { + this.cache = null; + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/BlockCallbacksMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/BlockCallbacksMixin.java new file mode 100644 index 00000000..182b4230 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/BlockCallbacksMixin.java @@ -0,0 +1,23 @@ +package org.embeddedt.modernfix.mixin; + +import net.minecraft.block.BlockState; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.duck.IBlockState; +import org.embeddedt.modernfix.util.BakeReason; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(targets = { "net/minecraftforge/registries/GameData$BlockCallbacks" }) +public class BlockCallbacksMixin { + @Redirect(method = "onBake", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;cacheState()V")) + private void skipCacheIfAllowed(BlockState state) { + if(BakeReason.currentBakeReason == BakeReason.FREEZE + || BakeReason.currentBakeReason == BakeReason.REMOTE_SNAPSHOT_INJECT + || (BakeReason.currentBakeReason == BakeReason.LOCAL_SNAPSHOT_INJECT && ModernFix.runningFirstInjection)) { + ((IBlockState)state).clearCache(); + } else { + state.cacheState(); + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/GameDataMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/GameDataMixin.java new file mode 100644 index 00000000..73bca975 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/GameDataMixin.java @@ -0,0 +1,47 @@ +package org.embeddedt.modernfix.mixin; + +import com.google.common.collect.Multimap; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import org.embeddedt.modernfix.util.BakeReason; +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.callback.CallbackInfoReturnable; + +import java.util.Map; + +@Mixin(GameData.class) +public class GameDataMixin { + @Inject(method = "freezeData", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 1), remap = false) + private static void markFreezeBakeReason(CallbackInfo ci) { + BakeReason.currentBakeReason = BakeReason.FREEZE; + } + + @Inject(method = "freezeData", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/registries/GameData;fireRemapEvent(Ljava/util/Map;Z)V"), remap = false) + private static void markEmptyBakeReason1(CallbackInfo ci) { + BakeReason.currentBakeReason = null; + } + + @Inject(method = "revertTo", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 1), remap = false) + private static void markRevertBakeReason(CallbackInfo ci) { + BakeReason.currentBakeReason = BakeReason.REVERT; + } + + @Inject(method = "revertTo", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;forEach(Ljava/util/function/BiConsumer;)V", ordinal = 1, shift = At.Shift.AFTER), remap = false) + private static void markEmptyBakeReason2(CallbackInfo ci) { + BakeReason.currentBakeReason = null; + } + + @Inject(method = "injectSnapshot", at = @At("HEAD"), remap = false) + private static void markSnapshotInjectBakeReason(Map snapshot, boolean injectFrozenData, boolean isLocalWorld, CallbackInfoReturnable> cir) { + BakeReason.currentBakeReason = isLocalWorld ? BakeReason.LOCAL_SNAPSHOT_INJECT : BakeReason.REMOTE_SNAPSHOT_INJECT; + } + + @Inject(method = "injectSnapshot", at = @At("RETURN"), remap = false) + private static void markEmptyBakeReason2(Map snapshot, boolean injectFrozenData, boolean isLocalWorld, CallbackInfoReturnable> cir) { + BakeReason.currentBakeReason = null; + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/MinecraftMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/MinecraftMixin.java index 4250a21a..35f68d41 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/MinecraftMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/MinecraftMixin.java @@ -52,7 +52,9 @@ public abstract class MinecraftMixin { private Minecraft.PackManager skipFirstReload(Minecraft client, DynamicRegistries.Impl dynamicRegistries, Function worldStorageToDatapackFunction, Function4 quadFunction, boolean vanillaOnly, SaveFormat.LevelSave levelSave, String worldName, DynamicRegistries.Impl originalRegistries, Function levelSaveToDatapackFunction, Function4 quadFunction2, boolean vanillaOnly2, Minecraft.WorldSelectionType selectionType, boolean creating) throws InterruptedException, ExecutionException { if(!creating) { ModernFix.LOGGER.warn("Skipping first reload, this is still experimental"); + ModernFix.runningFirstInjection = true; ((ILevelSave)levelSave).runWorldPersistenceHooks(); + ModernFix.runningFirstInjection = false; return null; } else { /* allow reload */ diff --git a/src/main/java/org/embeddedt/modernfix/util/BakeReason.java b/src/main/java/org/embeddedt/modernfix/util/BakeReason.java new file mode 100644 index 00000000..1fba3027 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/util/BakeReason.java @@ -0,0 +1,9 @@ +package org.embeddedt.modernfix.util; + +public enum BakeReason { + FREEZE, + REMOTE_SNAPSHOT_INJECT, + LOCAL_SNAPSHOT_INJECT, + REVERT; + public static BakeReason currentBakeReason = null; +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 45ace3e9..2191fa1d 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1,3 +1,4 @@ public net.minecraft.client.Minecraft$WorldSelectionType public net.minecraft.client.renderer.RenderType$Type -public net.minecraft.client.renderer.RenderType$Type (Ljava/lang/String;Lnet/minecraft/client/renderer/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$State;)V \ No newline at end of file +public net.minecraft.client.renderer.RenderType$Type (Ljava/lang/String;Lnet/minecraft/client/renderer/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$State;)V +public net.minecraft.block.AbstractBlock$AbstractBlockState$Cache \ No newline at end of file diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index fa87bb38..8ae3a8ea 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -9,7 +9,10 @@ "ModFileResourcePackMixin", "VanillaPackMixin", "LevelSaveMixin", - "SaveFormatAccessor" + "SaveFormatAccessor", + "AbstractBlockStateMixin", + "GameDataMixin", + "BlockCallbacksMixin" ], "client": [ "MinecraftMixin",