Skip to content

Commit

Permalink
Merge pull request #18 from GTNewHorizons/anvil-reordering
Browse files Browse the repository at this point in the history
Pre-processing chunk NBT data
  • Loading branch information
boubou19 authored Sep 10, 2024
2 parents 36d9e91 + 4b776ce commit 2493d3e
Showing 1 changed file with 64 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -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)
@Mixin(value = AnvilChunkLoader.class, priority = 1)
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(
Expand Down Expand Up @@ -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<Object[]> cir, @Local World world,
@Local LocalRef<NBTTagCompound> 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[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++) {
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(
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 2493d3e

Please sign in to comment.