From c31b1d23412e16c09cefdd300bb6cf5d30d32cee Mon Sep 17 00:00:00 2001 From: Darren Eberly Date: Mon, 9 Sep 2024 11:11:06 -0400 Subject: [PATCH 1/2] Pre-process chunk NBT data --- .../minecraft/MixinAnvilChunkLoader.java | 86 ++++++++++++++----- 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java b/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java index 0a31fb9..c13effa 100644 --- a/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java +++ b/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java @@ -1,22 +1,35 @@ package com.gtnewhorizons.neid.mixins.early.minecraft; +import java.nio.ByteBuffer; + import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; import net.minecraft.world.chunk.NibbleArray; import net.minecraft.world.chunk.storage.AnvilChunkLoader; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; 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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.gtnewhorizons.neid.Constants; import com.gtnewhorizons.neid.NEIDConfig; import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin; import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; @Mixin(AnvilChunkLoader.class) public class MixinAnvilChunkLoader { + @Inject(method = "writeChunkToNBT", at = @At("HEAD")) + private void neid$injectLevelTag(CallbackInfo ci, @Local NBTTagCompound tag) { + tag.setBoolean("NEID", true); + } + @Redirect( method = "writeChunkToNBT", at = @At( @@ -91,6 +104,56 @@ public class MixinAnvilChunkLoader { } } + @Inject( + method = "checkedReadChunkFromNBT__Async", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/chunk/storage/AnvilChunkLoader;readChunkFromNBT(Lnet/minecraft/world/World;Lnet/minecraft/nbt/NBTTagCompound;)Lnet/minecraft/world/chunk/Chunk;"), + remap = false) + private void neid$preprocessOldChunk(CallbackInfoReturnable cir, @Local World world, + @Local LocalRef tag) { + NBTTagCompound level = tag.get().getCompoundTag("Level"); + + if (!level.hasKey("NEID")) { + NBTTagList nbttaglist = level.getTagList("Sections", 10); + for (int i = 0; i < nbttaglist.tagCount(); i++) { + NBTTagCompound tag1 = nbttaglist.getCompoundTagAt(i); + if (tag1.hasKey("Blocks") && !tag1.hasKey("Blocks16")) { + final byte[] lsbData = tag1.getByteArray("Blocks"); + final short[] out = new short[Constants.BLOCKS_PER_EBS]; + if (tag1.hasKey("Add")) { + final byte[] msbData = tag1.getByteArray("Add"); + for (int j = 0; j < out.length; j += 2) { + final byte msPart = msbData[i / 2]; + out[i] = (short) ((lsbData[i] & 0xFF) | (msPart & 0xF) << 8); + out[i + 1] = (short) ((lsbData[i + 1] & 0xFF) | (msPart & 0xF0) << 4); + } + } else { + for (int j = 0; j < out.length; j++) { + out[j] = (short) (lsbData[j] & 0xFF); + } + } + final byte[] ret = new byte[out.length * 2]; + ByteBuffer.wrap(ret).asShortBuffer().put(out); + tag1.setByteArray("Blocks16", ret); + } + if (tag1.hasKey("Data") && !tag1.hasKey("Data16")) { + final byte[] metaData = tag1.getByteArray("Data"); + final short[] out = new short[Constants.BLOCKS_PER_EBS]; + for (int j = 0; j < out.length; j += 2) { + final byte meta = metaData[j / 2]; + out[j] = (short) (meta & 0xF); + out[j + 1] = (short) ((meta >> 4) & 0xF); + } + final byte[] ret = new byte[out.length * 2]; + ByteBuffer.wrap(ret).asShortBuffer().put(out); + tag1.setByteArray("Data16", ret); + } + } + level.setBoolean("NEID", true); + } + } + @Redirect( method = "readChunkFromNBT", at = @At( @@ -102,21 +165,6 @@ public class MixinAnvilChunkLoader { IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs; if (nbt.hasKey("Blocks16")) { ebsMixin.setBlockData(nbt.getByteArray("Blocks16"), 0); - } else if (nbt.hasKey("Blocks")) { - final short[] out = ebsMixin.getBlock16BArray(); - final byte[] lsbData = nbt.getByteArray("Blocks"); - if (nbt.hasKey("Add")) { - final byte[] msbData = nbt.getByteArray("Add"); - for (int i = 0; i < out.length; i += 2) { - final byte msPart = msbData[i / 2]; - out[i] = (short) ((lsbData[i] & 0xFF) | (msPart & 0xF) << 8); - out[i + 1] = (short) ((lsbData[i + 1] & 0xFF) | (msPart & 0xF0) << 4); - } - } else { - for (int j = 0; j < out.length; ++j) { - out[j] = (short) (lsbData[j] & 0xFF); - } - } } else { assert false; } @@ -144,14 +192,6 @@ public class MixinAnvilChunkLoader { IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs; if (nbt.hasKey("Data16")) { ebsMixin.setBlockMeta(nbt.getByteArray("Data16"), 0); - } else if (nbt.hasKey("Data")) { - final short[] out = ebsMixin.getBlock16BMetaArray(); - final byte[] metaData = nbt.getByteArray("Data"); - for (int i = 0; i < out.length; i += 2) { - final byte meta = metaData[i / 2]; - out[i] = (short) (meta & 0xF); - out[i + 1] = (short) ((meta >> 4) & 0xF); - } } else { assert false; } From 4b776cec9e45e3411ee1605832f5e0f7f649164c Mon Sep 17 00:00:00 2001 From: Darren Eberly Date: Mon, 9 Sep 2024 11:58:00 -0400 Subject: [PATCH 2/2] fix --- .../mixins/early/minecraft/MixinAnvilChunkLoader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java b/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java index c13effa..aab3dbe 100644 --- a/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java +++ b/src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java @@ -22,7 +22,7 @@ import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.ref.LocalRef; -@Mixin(AnvilChunkLoader.class) +@Mixin(value = AnvilChunkLoader.class, priority = 1) public class MixinAnvilChunkLoader { @Inject(method = "writeChunkToNBT", at = @At("HEAD")) @@ -124,9 +124,9 @@ public class MixinAnvilChunkLoader { if (tag1.hasKey("Add")) { final byte[] msbData = tag1.getByteArray("Add"); for (int j = 0; j < out.length; j += 2) { - final byte msPart = msbData[i / 2]; - out[i] = (short) ((lsbData[i] & 0xFF) | (msPart & 0xF) << 8); - out[i + 1] = (short) ((lsbData[i + 1] & 0xFF) | (msPart & 0xF0) << 4); + final byte msPart = msbData[j / 2]; + out[j] = (short) ((lsbData[j] & 0xFF) | (msPart & 0xF) << 8); + out[j + 1] = (short) ((lsbData[j + 1] & 0xFF) | (msPart & 0xF0) << 4); } } else { for (int j = 0; j < out.length; j++) {