Skip to content

Commit 2493d3e

Browse files
authored
Merge pull request #18 from GTNewHorizons/anvil-reordering
Pre-processing chunk NBT data
2 parents 36d9e91 + 4b776ce commit 2493d3e

File tree

1 file changed

+64
-24
lines changed

1 file changed

+64
-24
lines changed

src/main/java/com/gtnewhorizons/neid/mixins/early/minecraft/MixinAnvilChunkLoader.java

+64-24
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
package com.gtnewhorizons.neid.mixins.early.minecraft;
22

3+
import java.nio.ByteBuffer;
4+
35
import net.minecraft.nbt.NBTTagCompound;
6+
import net.minecraft.nbt.NBTTagList;
7+
import net.minecraft.world.World;
48
import net.minecraft.world.chunk.NibbleArray;
59
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
610
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
711

812
import org.spongepowered.asm.mixin.Mixin;
913
import org.spongepowered.asm.mixin.injection.At;
14+
import org.spongepowered.asm.mixin.injection.Inject;
1015
import org.spongepowered.asm.mixin.injection.Redirect;
16+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
17+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1118

1219
import com.gtnewhorizons.neid.Constants;
1320
import com.gtnewhorizons.neid.NEIDConfig;
1421
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
1522
import com.llamalad7.mixinextras.sugar.Local;
23+
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
1624

17-
@Mixin(AnvilChunkLoader.class)
25+
@Mixin(value = AnvilChunkLoader.class, priority = 1)
1826
public class MixinAnvilChunkLoader {
1927

28+
@Inject(method = "writeChunkToNBT", at = @At("HEAD"))
29+
private void neid$injectLevelTag(CallbackInfo ci, @Local NBTTagCompound tag) {
30+
tag.setBoolean("NEID", true);
31+
}
32+
2033
@Redirect(
2134
method = "writeChunkToNBT",
2235
at = @At(
@@ -91,6 +104,56 @@ public class MixinAnvilChunkLoader {
91104
}
92105
}
93106

107+
@Inject(
108+
method = "checkedReadChunkFromNBT__Async",
109+
at = @At(
110+
value = "INVOKE",
111+
target = "Lnet/minecraft/world/chunk/storage/AnvilChunkLoader;readChunkFromNBT(Lnet/minecraft/world/World;Lnet/minecraft/nbt/NBTTagCompound;)Lnet/minecraft/world/chunk/Chunk;"),
112+
remap = false)
113+
private void neid$preprocessOldChunk(CallbackInfoReturnable<Object[]> cir, @Local World world,
114+
@Local LocalRef<NBTTagCompound> tag) {
115+
NBTTagCompound level = tag.get().getCompoundTag("Level");
116+
117+
if (!level.hasKey("NEID")) {
118+
NBTTagList nbttaglist = level.getTagList("Sections", 10);
119+
for (int i = 0; i < nbttaglist.tagCount(); i++) {
120+
NBTTagCompound tag1 = nbttaglist.getCompoundTagAt(i);
121+
if (tag1.hasKey("Blocks") && !tag1.hasKey("Blocks16")) {
122+
final byte[] lsbData = tag1.getByteArray("Blocks");
123+
final short[] out = new short[Constants.BLOCKS_PER_EBS];
124+
if (tag1.hasKey("Add")) {
125+
final byte[] msbData = tag1.getByteArray("Add");
126+
for (int j = 0; j < out.length; j += 2) {
127+
final byte msPart = msbData[j / 2];
128+
out[j] = (short) ((lsbData[j] & 0xFF) | (msPart & 0xF) << 8);
129+
out[j + 1] = (short) ((lsbData[j + 1] & 0xFF) | (msPart & 0xF0) << 4);
130+
}
131+
} else {
132+
for (int j = 0; j < out.length; j++) {
133+
out[j] = (short) (lsbData[j] & 0xFF);
134+
}
135+
}
136+
final byte[] ret = new byte[out.length * 2];
137+
ByteBuffer.wrap(ret).asShortBuffer().put(out);
138+
tag1.setByteArray("Blocks16", ret);
139+
}
140+
if (tag1.hasKey("Data") && !tag1.hasKey("Data16")) {
141+
final byte[] metaData = tag1.getByteArray("Data");
142+
final short[] out = new short[Constants.BLOCKS_PER_EBS];
143+
for (int j = 0; j < out.length; j += 2) {
144+
final byte meta = metaData[j / 2];
145+
out[j] = (short) (meta & 0xF);
146+
out[j + 1] = (short) ((meta >> 4) & 0xF);
147+
}
148+
final byte[] ret = new byte[out.length * 2];
149+
ByteBuffer.wrap(ret).asShortBuffer().put(out);
150+
tag1.setByteArray("Data16", ret);
151+
}
152+
}
153+
level.setBoolean("NEID", true);
154+
}
155+
}
156+
94157
@Redirect(
95158
method = "readChunkFromNBT",
96159
at = @At(
@@ -102,21 +165,6 @@ public class MixinAnvilChunkLoader {
102165
IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs;
103166
if (nbt.hasKey("Blocks16")) {
104167
ebsMixin.setBlockData(nbt.getByteArray("Blocks16"), 0);
105-
} else if (nbt.hasKey("Blocks")) {
106-
final short[] out = ebsMixin.getBlock16BArray();
107-
final byte[] lsbData = nbt.getByteArray("Blocks");
108-
if (nbt.hasKey("Add")) {
109-
final byte[] msbData = nbt.getByteArray("Add");
110-
for (int i = 0; i < out.length; i += 2) {
111-
final byte msPart = msbData[i / 2];
112-
out[i] = (short) ((lsbData[i] & 0xFF) | (msPart & 0xF) << 8);
113-
out[i + 1] = (short) ((lsbData[i + 1] & 0xFF) | (msPart & 0xF0) << 4);
114-
}
115-
} else {
116-
for (int j = 0; j < out.length; ++j) {
117-
out[j] = (short) (lsbData[j] & 0xFF);
118-
}
119-
}
120168
} else {
121169
assert false;
122170
}
@@ -144,14 +192,6 @@ public class MixinAnvilChunkLoader {
144192
IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs;
145193
if (nbt.hasKey("Data16")) {
146194
ebsMixin.setBlockMeta(nbt.getByteArray("Data16"), 0);
147-
} else if (nbt.hasKey("Data")) {
148-
final short[] out = ebsMixin.getBlock16BMetaArray();
149-
final byte[] metaData = nbt.getByteArray("Data");
150-
for (int i = 0; i < out.length; i += 2) {
151-
final byte meta = metaData[i / 2];
152-
out[i] = (short) (meta & 0xF);
153-
out[i + 1] = (short) ((meta >> 4) & 0xF);
154-
}
155195
} else {
156196
assert false;
157197
}

0 commit comments

Comments
 (0)