more robust array sizing

This commit is contained in:
FalsePattern committed 2024-06-06 22:05:27 +02:00
1 parent a432bdeb04
commit 06b033e179
8 files changed
+104 -29

No files matched your search

@@ -16,6 +16,9 @@ public class ExtendedConstants {
public static final int maximumPotionIDs = 65536;
public static final int maximumEnchantmentIDs = 32768;
public static final int blocksPerSubChunk = 16 * 16 * 16;
public static final int subChunkNibbleArraySize = 16 * 16 * 16;
//Align with max item metadata for spawn eggs. Will be treated as short in netcode
public static final int bitsPerEntity = 15;
@@ -4,6 +4,7 @@ import com.falsepattern.chunk.api.ArrayUtil;
import com.falsepattern.chunk.api.DataManager;
import com.falsepattern.endlessids.Tags;
import com.falsepattern.endlessids.mixin.helpers.SubChunkBlockHook;
import com.falsepattern.endlessids.util.DataUtil;
import lombok.val;
import lombok.var;
import org.jetbrains.annotations.NotNull;
@@ -16,6 +17,9 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.nio.ByteBuffer;
import static com.falsepattern.endlessids.constants.ExtendedConstants.blocksPerSubChunk;
import static com.falsepattern.endlessids.util.DataUtil.*;
public class BlockIDManager implements DataManager.PacketDataManager, DataManager.SubChunkDataManager {
@Override
@@ -141,20 +145,20 @@ public class BlockIDManager implements DataManager.PacketDataManager, DataManage
}
//NotEnoughIDs world compatibility
public static void readSectionFromNBTNotEnoughIDsDFU(SubChunkBlockHook subChunk, NBTTagCompound nbt) {
public static void readSubChunkFromNBTNotEnoughIDsDFU(SubChunkBlockHook subChunk, NBTTagCompound nbt) {
val data = nbt.getByteArray("Blocks16");
val dataShort = new short[data.length >>> 1];
ByteBuffer.wrap(data).asShortBuffer().get(dataShort);
val b1 = new byte[dataShort.length];
val b2L = new byte[dataShort.length >>> 1];
val b2H = new byte[dataShort.length >>> 1];
val b1 = new byte[blocksPerSubChunk];
val b2L = new byte[blocksPerSubChunk >>> 1];
val b2H = new byte[blocksPerSubChunk >>> 1];
for (int i = 0; i < dataShort.length; i++) {
val s = dataShort[i];
val nI = i >>> 1;
val mI = (i & 1) * 4;
b1[i] = (byte) (s & 0x00FF);
b2L[nI] |= ((s & 0x0F00) >>> 8) << mI;
b2H[nI] |= ((s & 0xF000) >>> 12) << mI;
b2L[nI] |= (byte) (((s & 0x0F00) >>> 8) << mI);
b2H[nI] |= (byte) (((s & 0xF000) >>> 12) << mI);
}
subChunk.setB1(b1);
subChunk.setB2Low(new NibbleArray(b2L, 4));
@@ -165,7 +169,7 @@ public class BlockIDManager implements DataManager.PacketDataManager, DataManage
public void readSubChunkFromNBT(Chunk chunk, ExtendedBlockStorage subChunkVanilla, NBTTagCompound nbt) {
val subChunk = (SubChunkBlockHook) subChunkVanilla;
if (nbt.hasKey("Blocks16")) {
readSectionFromNBTNotEnoughIDsDFU(subChunk, nbt);
readSubChunkFromNBTNotEnoughIDsDFU(subChunk, nbt);
return;
}
assert nbt.hasKey("Blocks");
@@ -174,10 +178,10 @@ public class BlockIDManager implements DataManager.PacketDataManager, DataManage
final byte[] b2High = nbt.hasKey("BlocksB2Hi") ? nbt.getByteArray("BlocksB2Hi") : null;
final byte[] b3 = nbt.hasKey("BlocksB3") ? nbt.getByteArray("BlocksB3") : null;
subChunk.setB1(b1);
subChunk.setB2Low(b2Low == null ? null : new NibbleArray(b2Low, 4));
subChunk.setB2High(b2High == null ? null : new NibbleArray(b2High, 4));
subChunk.setB3(b3);
subChunk.setB1(ensureSubChunkByteArray(b1));
subChunk.setB2Low(ensureSubChunkNibbleArray(b2Low));
subChunk.setB2High(ensureSubChunkNibbleArray(b2High));
subChunk.setB3(ensureSubChunkByteArray(b3));
}
@Override
@@ -4,6 +4,7 @@ import com.falsepattern.chunk.api.ArrayUtil;
import com.falsepattern.chunk.api.DataManager;
import com.falsepattern.endlessids.Tags;
import com.falsepattern.endlessids.mixin.helpers.SubChunkBlockHook;
import com.falsepattern.endlessids.util.DataUtil;
import lombok.val;
import lombok.var;
import org.jetbrains.annotations.NotNull;
@@ -16,6 +17,8 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.nio.ByteBuffer;
import static com.falsepattern.endlessids.constants.ExtendedConstants.blocksPerSubChunk;
public class BlockMetaManager implements DataManager.PacketDataManager, DataManager.SubChunkDataManager {
@Override
@@ -118,17 +121,42 @@ public class BlockMetaManager implements DataManager.PacketDataManager, DataMana
}
}
//NotEnoughIDs world compatibility
private void readSubChunkFromNBTNotEnoughIDsDFU(SubChunkBlockHook subChunk, NBTTagCompound nbt) {
val data = nbt.getByteArray("Data16");
val dataShort = new short[data.length >>> 1];
ByteBuffer.wrap(data).asShortBuffer().get(dataShort);
val m1Low = new byte[blocksPerSubChunk >>> 1];
val m1High = new byte[blocksPerSubChunk >>> 1];
val m2 = new byte[blocksPerSubChunk];
for (int i = 0; i < dataShort.length; i++) {
val s = dataShort[i];
val nI = i >>> 1;
val mI = (i & 1) * 4;
m1Low[nI] |= (byte) ((s & 0x000F) << mI);
m1High[nI] |= (byte) (((s & 0x00F0) >>> 4) << mI);
m2[i] = (byte) ((s & 0xFF00) >>> 8);
}
subChunk.setM1Low(new NibbleArray(m1Low, 4));
subChunk.setM1High(new NibbleArray(m1High, 4));
subChunk.setM2(m2);
}
@Override
public void readSubChunkFromNBT(Chunk chunk, ExtendedBlockStorage subChunkVanilla, NBTTagCompound nbt) {
val subChunk = (SubChunkBlockHook) subChunkVanilla;
if (nbt.hasKey("Data16")) {
readSubChunkFromNBTNotEnoughIDsDFU(subChunk, nbt);
return;
}
assert nbt.hasKey("Data");
val m1Low = nbt.getByteArray("Data");
final byte[] m1High = nbt.hasKey("Data1High") ? nbt.getByteArray("Data1High") : null;
final byte[] m2 = nbt.hasKey("Data2") ? nbt.getByteArray("Data2") : null;
subChunk.setM1Low(new NibbleArray(m1Low, 4));
subChunk.setM1High(m1High == null ? null : new NibbleArray(m1High, 4));
subChunk.setM2(m2);
subChunk.setM1Low(DataUtil.ensureSubChunkNibbleArray(m1Low));
subChunk.setM1High(DataUtil.ensureSubChunkNibbleArray(m1High));
subChunk.setM2(DataUtil.ensureSubChunkByteArray(m2));
}
@Override
@@ -21,6 +21,8 @@ import net.minecraft.init.Blocks;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import static com.falsepattern.endlessids.constants.ExtendedConstants.blocksPerSubChunk;
@Mixin(ExtendedBlockStorage.class)
public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook {
@Shadow
@@ -198,7 +200,7 @@ public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook {
@Override
public NibbleArray createB2Low() {
return (blockMSBArray = new NibbleArray(blockLSBArray.length, 4));
return (blockMSBArray = new NibbleArray(blocksPerSubChunk, 4));
}
@Override
@@ -213,7 +215,7 @@ public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook {
@Override
public NibbleArray createB2High() {
return (b2High = new NibbleArray(blockLSBArray.length, 4));
return (b2High = new NibbleArray(blocksPerSubChunk, 4));
}
@Override
@@ -228,7 +230,7 @@ public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook {
@Override
public byte[] createB3() {
return b3 = new byte[blockLSBArray.length];
return b3 = new byte[blocksPerSubChunk];
}
@Override
@@ -253,7 +255,7 @@ public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook {
@Override
public NibbleArray createM1High() {
return (m1High = new NibbleArray(blockLSBArray.length, 4));
return (m1High = new NibbleArray(blocksPerSubChunk, 4));
}
@Override
@@ -268,7 +270,7 @@ public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook {
@Override
public byte[] createM2() {
return (m2 = new byte[blockLSBArray.length]);
return (m2 = new byte[blocksPerSubChunk]);
}
@Override
@@ -0,0 +1,17 @@
package com.falsepattern.endlessids.util;
import net.minecraft.world.chunk.NibbleArray;
import java.util.Arrays;
import static com.falsepattern.endlessids.constants.ExtendedConstants.blocksPerSubChunk;
public class DataUtil {
public static byte[] ensureSubChunkByteArray(byte[] arr) {
return arr == null ? null : arr.length == blocksPerSubChunk ? arr : Arrays.copyOf(arr, blocksPerSubChunk);
}
public static NibbleArray ensureSubChunkNibbleArray(byte[] data) {
return data == null ? null : new NibbleArray(data.length == (blocksPerSubChunk >>> 1) ? data : Arrays.copyOf(data, (blocksPerSubChunk >>> 1)), 4);
}
}