reimplemented metadata storage, now it's optimized like IDs

This commit is contained in:
FalsePattern committed 2023-03-03 08:55:08 +01:00
1 parent f98d2c98e3
commit 0b968923df
7 files changed
+284 -76

No files matched your search

@@ -32,7 +32,7 @@ public class Hooks {
}
}
}
return ebs.getStorageFlag();
return ebs.getEBSMSBMask();
}
public static void setBlockData(final IExtendedBlockStorageMixin ebs, final byte[] data, int offset, final int storageFlag) {
@@ -73,16 +73,6 @@ public class Hooks {
System.arraycopy(data, offset, b3, 0, b3.length);
}
public static void getBlockMeta(final IExtendedBlockStorageMixin ebs, final byte[] data, final int offset) {
val meta = ebs.getMetaArray();
Unsafer.arraycopy(meta, 0, data, offset, meta.length);
}
public static void setBlockMeta(final IExtendedBlockStorageMixin ebs, final byte[] data, final int offset) {
val meta = ebs.getMetaArray();
Unsafer.arraycopy(data, offset, meta, 0, meta.length);
}
public static void writeBlockDataToNBT(final NBTTagCompound nbt, final IExtendedBlockStorageMixin ebs) {
val b1 = ebs.getB1();
val b2Low = ebs.getB2Low();
@@ -121,6 +111,75 @@ public class Hooks {
ebs.setB3(b3);
}
public static int getBlockMeta(final IExtendedBlockStorageMixin ebs, final byte[] data, int offset) {
val m1Low = ebs.getM1Low();
System.arraycopy(m1Low.data, 0, data, offset, m1Low.data.length);
offset += m1Low.data.length;
val m1High = ebs.getM1High();
if (m1High != null) {
System.arraycopy(m1High.data, 0, data, offset, m1High.data.length);
offset += m1High.data.length;
val m2 = ebs.getM2();
if (m2 != null) {
System.arraycopy(m2, 0, data, offset, m2.length);
}
}
return ebs.getEBSMask();
}
public static void setBlockMeta(final IExtendedBlockStorageMixin ebs, final byte[] data, int offset, final int storageFlag) {
val m1Low = ebs.getM1Low();
System.arraycopy(data, offset, m1Low.data, 0, m1Low.data.length);
offset += m1Low.data.length;
if (storageFlag == 0b01) {
ebs.clearM1High();
ebs.clearM2();
return;
}
var m1High = ebs.getM1High();
if (m1High == null) {
m1High = ebs.createM1High();
}
System.arraycopy(data, offset, m1High.data, 0, m1High.data.length);
if (storageFlag == 0b10) {
ebs.clearM2();
return;
}
var m2 = ebs.getM2();
if (m2 == null) {
m2 = ebs.createM2();
}
System.arraycopy(data, offset, m2, 0, m2.length);
}
public static void writeBlockMetaToNBT(IExtendedBlockStorageMixin ebs, NBTTagCompound nbt) {
val m1Low = ebs.getM1Low();
val m1High = ebs.getM1High();
val m2 = ebs.getM2();
nbt.setByteArray("Data", m1Low.data);
if (m1High != null) {
nbt.setByteArray("Data1High", m1High.data);
}
if (m2 != null) {
nbt.setByteArray("Data2", m2);
}
}
public static void readBlockMetaFromNBT(IExtendedBlockStorageMixin ebs, NBTTagCompound nbt) {
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;
ebs.setM1Low(new NibbleArray(m1Low, 4));
if (m1High == null) {
ebs.clearM1High();
} else {
ebs.setM1High(new NibbleArray(m1High, 4));
}
ebs.setM2(m2);
}
public static int getIdFromBlockWithCheck(final Block block, final Block oldBlock) {
final int id = Block.getIdFromBlock(block);
if (GeneralConfig.catchUnregisteredBlocks && id == -1) {
@@ -203,9 +262,9 @@ public class Hooks {
}
if (nbt.hasKey("Biomes16v2", 7)) {
byteToShortArray(nbt.getByteArray("Biomes16v2"), 0, data, 0, data.length * 2);
} else if (nbt.hasKey("Biomes16", 7)) {
} else if (nbt.hasKey("Biomes16", 7)) { //NotEnoughBiomes DFU
byteToShortArrayLegacy(nbt.getByteArray("Biomes16"), data);
} else if (nbt.hasKey("Biomes", 7)) {
} else if (nbt.hasKey("Biomes", 7)) { //Vanilla DFU
scatter(nbt.getByteArray("Biomes"), data);
} else {
put = false;
@@ -214,17 +273,4 @@ public class Hooks {
((IChunkMixin) chunk).setBiomeShortArray(data);
}
}
public static void readBlockMetaFromNBT(IExtendedBlockStorageMixin instance, NBTTagCompound nbt) {
short[] data = instance.getMetaArray();
if (nbt.hasKey("Data16", 7)) {
byteToShortArray(nbt.getByteArray("Data16"), 0, data, 0, data.length * 2);
} else {
scatter(nbt.getByteArray("Data"), data);
}
}
public static void writeBlockMetaToNBT(IExtendedBlockStorageMixin instance, NBTTagCompound nbt) {
nbt.setByteArray("Data16", shortToByteArray(instance.getMetaArray()));
}
}
@@ -31,9 +31,29 @@ public interface IExtendedBlockStorageMixin {
byte[] createB3();
int getStorageFlag();
int getEBSMask();
int getEBSMSBMask();
int getID(int x, int y, int z);
short[] getMetaArray();
NibbleArray getM1Low();
void setM1Low(NibbleArray m1Low);
NibbleArray getM1High();
void setM1High(NibbleArray m1High);
void clearM1High();
NibbleArray createM1High();
byte[] getM2();
void setM2(byte[] m2);
void clearM2();
byte[] createM2();
}
@@ -1,13 +1,13 @@
package com.falsepattern.endlessids.mixin.mixins.client.blockitem.vanilla;
import com.falsepattern.endlessids.Hooks;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import lombok.val;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -23,10 +23,25 @@ import java.util.Iterator;
public abstract class ChunkMixin {
//This is needed because the array is not a field, but a local, and local arraylength overriding does not exist
private static byte[][] fakeArrays;
private static NibbleArray fakeNarray;
private static NibbleArray[] fakeNarrays;
@Shadow
private ExtendedBlockStorage[] storageArrays;
private int ebsData;
@ModifyVariable(method = "fillChunk",
at = @At("HEAD"),
ordinal = 0,
argsOnly = true)
private int extractEBSData(int ebs) {
ebsData = ebs;
int result = 0;
for (int i = 0; i < 16; i++) {
result |= ((ebs >>> (i << 1)) & 0b11) > 0 ? 1 << i : 0;
}
return result;
}
@Redirect(method = "fillChunk",
at = @At(value = "FIELD",
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;",
@@ -46,7 +61,7 @@ public abstract class ChunkMixin {
locals = LocalCapture.CAPTURE_FAILHARD,
require = 1)
private void blockData(byte[] p_76607_1_, int p_76607_2_, int p_76607_3_, boolean p_76607_4_, CallbackInfo ci, Iterator iterator, int k, boolean flag1, int l) {
val storageFlag = (p_76607_3_ >>> l) & 0b11;
val storageFlag = (p_76607_3_ >>> (l << 1)) & 0b11;
Hooks.setBlockData((IExtendedBlockStorageMixin) this.storageArrays[l], p_76607_1_, k, storageFlag);
}
@@ -62,7 +77,7 @@ public abstract class ChunkMixin {
fakeArrays[2] = new byte[16 * 16 * 16 * 4 / 2];
fakeArrays[3] = new byte[16 * 16 * 16 * 6 / 2];
}
return fakeArrays[((IExtendedBlockStorageMixin) instance).getStorageFlag()];
return fakeArrays[((IExtendedBlockStorageMixin) instance).getEBSMSBMask()];
}
@Redirect(method = "fillChunk",
@@ -81,7 +96,8 @@ public abstract class ChunkMixin {
locals = LocalCapture.CAPTURE_FAILHARD,
require = 1)
private void hookSetBlockMeta(byte[] p_76607_1_, int p_76607_2_, int p_76607_3_, boolean p_76607_4_, CallbackInfo ci, Iterator iterator, int k, boolean flag1, int l) {
Hooks.setBlockMeta((IExtendedBlockStorageMixin) this.storageArrays[l], p_76607_1_, k);
val storageFlag = (ebsData >>> (l << 1)) & 0b11;
Hooks.setBlockMeta((IExtendedBlockStorageMixin) this.storageArrays[l], p_76607_1_, k, storageFlag);
}
@Redirect(method = "fillChunk",
@@ -89,7 +105,13 @@ public abstract class ChunkMixin {
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getMetadataArray()Lnet/minecraft/world/chunk/NibbleArray;"),
require = 1)
private NibbleArray hookSetBlockMetaNoArray(ExtendedBlockStorage instance) {
return fakeNarray != null ? fakeNarray : (fakeNarray = new NibbleArray(null, 0));
if (fakeNarrays == null) {
fakeNarrays = new NibbleArray[3];
fakeNarrays[0] = new NibbleArray(new byte[]{(byte)0b01}, 0);
fakeNarrays[1] = new NibbleArray(new byte[]{(byte)0b10}, 0);
fakeNarrays[2] = new NibbleArray(new byte[]{(byte)0b100}, 0);
}
return fakeNarrays[((IExtendedBlockStorageMixin)instance).getEBSMask() - 1];
}
@Redirect(method = "fillChunk",
@@ -103,7 +125,7 @@ public abstract class ChunkMixin {
expect = 2,
require = 2)
private int hookSetBlockMetaFakeBytesLength(byte[] array) {
return 16 * 16 * 16 * (ExtendedConstants.nibblesPerMetadata >>> 1);
return 16 * 16 * 16 * (array[0] & 0xFF) / 2;
}
@Redirect(method = "fillChunk",
@@ -27,29 +27,18 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
private int blockRefCount;
@Shadow
private int tickRefCount;
@Shadow
private byte[] blockLSBArray;
@Shadow
private NibbleArray blockMetadataArray;
@Shadow
private NibbleArray blockMSBArray;
private NibbleArray b2High;
private byte[] b3;
private short[] metaArray;
@Override
public short[] getMetaArray() {
return metaArray;
}
@Inject(method = "<init>",
at = @At(value = "RETURN"),
require = 1)
private void init(CallbackInfo ci) {
blockMetadataArray = null;
metaArray = new short[16 * 16 * 16];
}
@Shadow
private NibbleArray blockMetadataArray;
private NibbleArray m1High;
private byte[] m2;
public int getID(int x, int y, int z) {
int index = y << 8 | z << 4 | x;
@@ -71,14 +60,14 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
blockLSBArray[index] = (byte) (id & 0xFF);
if (id > 0xFF) {
if (blockMSBArray == null) {
blockMSBArray = new NibbleArray(blockLSBArray.length, 4);
createB2Low();
}
if (id > 0xFFF) {
if (b2High == null) {
b2High = new NibbleArray(blockLSBArray.length, 4);
createB2High();
}
if (id > 0xFFFF && b3 == null) {
b3 = new byte[blockLSBArray.length];
createB3();
}
}
}
@@ -133,8 +122,14 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
*/
@Overwrite
public int getExtBlockMetadata(int x, int y, int z) {
int index = y << 8 | z << 4 | x;
return metaArray[index] & 0xFFFF;
int meta = blockMetadataArray.get(x, y, z);
if (m1High != null) {
meta |= m1High.get(x, y, z) << 4;
if (m2 != null) {
meta |= (m2[(y << 8) | (z << 4) | x] & 0xFF) << 8;
}
}
return meta;
}
/**
@@ -143,8 +138,21 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
*/
@Overwrite
public void setExtBlockMetadata(int x, int y, int z, int meta) {
int index = y << 8 | z << 4 | x;
metaArray[index] = (short) (meta & 0xFFFF);
blockMetadataArray.set(x, y, z, meta & 0xF);
if (meta > 0xF) {
if (m1High == null) {
createM1High();
}
if (meta > 0xFF && m2 == null) {
createM2();
}
}
if (m1High != null) {
m1High.set(x, y, z, (meta >>> 4) & 0xF);
if (m2 != null) {
m2[(y << 8) | (z << 4) | x] = (byte) ((meta >>> 8) & 0xFF);
}
}
}
@Redirect(method = "removeInvalidBlocks",
@@ -239,7 +247,57 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
}
@Override
public int getStorageFlag() {
public NibbleArray getM1Low() {
return blockMetadataArray;
}
@Override
public void setM1Low(NibbleArray m1Low) {
blockMetadataArray = m1Low;
}
@Override
public NibbleArray getM1High() {
return m1High;
}
@Override
public void setM1High(NibbleArray m1High) {
this.m1High = m1High;
}
@Override
public void clearM1High() {
m1High = null;
}
@Override
public NibbleArray createM1High() {
return (m1High = new NibbleArray(blockLSBArray.length, 4));
}
@Override
public byte[] getM2() {
return m2;
}
@Override
public void setM2(byte[] m2) {
this.m2 = m2;
}
@Override
public void clearM2() {
m2 = null;
}
@Override
public byte[] createM2() {
return (m2 = new byte[blockLSBArray.length]);
}
@Override
public int getEBSMSBMask() {
if (blockMSBArray == null) {
return 0b00;
}
@@ -252,6 +310,17 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
return 0b11;
}
@Override
public int getEBSMask() {
if (m1High == null) {
return 0b01;
}
if (m2 == null) {
return 0b10;
}
return 0b11;
}
@Inject(method = {"getBlockMSBArray", "createBlockMSBArray"},
at = @At("HEAD"))
private void crashMSBArray(CallbackInfoReturnable<NibbleArray> cir) {
@@ -1,10 +1,10 @@
package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla;
import com.falsepattern.endlessids.Hooks;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import lombok.val;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -20,7 +20,7 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
@Mixin(S21PacketChunkData.class)
public abstract class S21PacketChunkDataMixin {
private static byte[][] fakeArrays;
private static NibbleArray fakeNarray;
private static NibbleArray[] fakeNarrays;
@Redirect(method = "func_149269_a",
at = @At(value = "INVOKE",
@@ -38,7 +38,7 @@ public abstract class S21PacketChunkDataMixin {
require = 1)
private static void hookGetBlockData(Chunk p_149269_0_, boolean p_149269_1_, int p_149269_2_, CallbackInfoReturnable<S21PacketChunkData.Extracted> cir, int j, ExtendedBlockStorage[] aextendedblockstorage, int k, S21PacketChunkData.Extracted extracted, byte[] abyte, int l) {
val ebs = (IExtendedBlockStorageMixin) aextendedblockstorage[l];
extracted.field_150281_c |= Hooks.getBlockData(ebs, abyte, j) << l * 2;
extracted.field_150281_c |= Hooks.getBlockData(ebs, abyte, j) << (l << 1);
}
@Redirect(method = "func_149269_a",
@@ -53,7 +53,7 @@ public abstract class S21PacketChunkDataMixin {
fakeArrays[2] = new byte[16 * 16 * 16 * 4 / 2];
fakeArrays[3] = new byte[16 * 16 * 16 * 6 / 2];
}
return fakeArrays[((IExtendedBlockStorageMixin) instance).getStorageFlag()];
return fakeArrays[((IExtendedBlockStorageMixin) instance).getEBSMSBMask()];
}
@Redirect(method = "func_149269_a",
@@ -73,7 +73,10 @@ public abstract class S21PacketChunkDataMixin {
locals = LocalCapture.CAPTURE_FAILHARD,
require = 1)
private static void hookGetBlockMeta(Chunk p_149269_0_, boolean p_149269_1_, int p_149269_2_, CallbackInfoReturnable<S21PacketChunkData.Extracted> cir, int j, ExtendedBlockStorage[] aextendedblockstorage, int k, S21PacketChunkData.Extracted extracted, byte[] abyte, int l) {
Hooks.getBlockMeta((IExtendedBlockStorageMixin) aextendedblockstorage[l], abyte, j);
if (l == 0) {
extracted.field_150280_b = 0;
}
extracted.field_150280_b |= Hooks.getBlockMeta((IExtendedBlockStorageMixin) aextendedblockstorage[l], abyte, j) << (l << 1);
}
@Redirect(method = "func_149269_a",
@@ -81,7 +84,13 @@ public abstract class S21PacketChunkDataMixin {
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getMetadataArray()Lnet/minecraft/world/chunk/NibbleArray;"),
require = 1)
private static NibbleArray hookGetBlockMetaNoArray(ExtendedBlockStorage instance) {
return fakeNarray != null ? fakeNarray : (fakeNarray = new NibbleArray(null, 0));
if (fakeNarrays == null) {
fakeNarrays = new NibbleArray[3];
fakeNarrays[0] = new NibbleArray(new byte[]{(byte)0b01}, 0);
fakeNarrays[1] = new NibbleArray(new byte[]{(byte)0b10}, 0);
fakeNarrays[2] = new NibbleArray(new byte[]{(byte)0b100}, 0);
}
return fakeNarrays[((IExtendedBlockStorageMixin)instance).getEBSMask() - 1];
}
@Redirect(method = "func_149269_a",
@@ -95,7 +104,7 @@ public abstract class S21PacketChunkDataMixin {
expect = 2,
require = 2)
private static int hookGetBlockMetaFakeBytesLength(byte[] array) {
return 16 * 16 * 16 * (ExtendedConstants.nibblesPerMetadata >>> 1);
return 16 * 16 * 16 * (array[0] & 0xFF) / 2;
}
@Redirect(method = "func_149269_a",
@@ -1,5 +1,6 @@
package com.falsepattern.endlessids.mixin.mixins.common.vanilla;
import com.falsepattern.endlessids.config.GeneralConfig;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.constants.VanillaConstants;
import io.netty.buffer.ByteBuf;
@@ -49,19 +50,34 @@ public abstract class S21PacketChunkDataMixin {
@Inject(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 1),
ordinal = 0),
require = 1)
private void extendWrite(PacketBuffer p_148840_1_, CallbackInfo ci) {
p_148840_1_.writeInt(this.field_149280_d);
if (GeneralConfig.extendBlockItem) {
p_148840_1_.writeInt(this.field_149283_c);
p_148840_1_.writeInt(this.field_149280_d);
} else {
p_148840_1_.writeShort((short)(this.field_149283_c & 65535));
p_148840_1_.writeShort((short)(this.field_149280_d & 65535));
}
p_148840_1_.writeInt(this.field_149278_f.length);
}
@Redirect(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 0),
require = 1)
private ByteBuf suppressOldWrite1(PacketBuffer instance, int p_writeShort_1_) {
return null;
}
@Redirect(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 1),
require = 1)
private ByteBuf suppressOldWrite(PacketBuffer instance, int p_writeShort_1_) {
private ByteBuf suppressOldWrite2(PacketBuffer instance, int p_writeShort_1_) {
return null;
}
@@ -73,8 +89,13 @@ public abstract class S21PacketChunkDataMixin {
this.field_149284_a = data.readInt();
this.field_149282_b = data.readInt();
this.field_149279_g = data.readBoolean();
this.field_149283_c = data.readShort();
this.field_149280_d = data.readInt();
if (GeneralConfig.extendBlockItem) {
this.field_149283_c = data.readInt();
this.field_149280_d = data.readInt();
} else {
this.field_149283_c = data.readShort();
this.field_149280_d = data.readShort();
}
int length = data.readInt();
this.field_149285_h = data.readInt();
@@ -1,5 +1,6 @@
package com.falsepattern.endlessids.mixin.mixins.common.vanilla;
import com.falsepattern.endlessids.config.GeneralConfig;
import io.netty.buffer.ByteBuf;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -34,20 +35,35 @@ public abstract class S26PacketMapChunkBulkMixin {
@Inject(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 2),
ordinal = 1),
locals = LocalCapture.CAPTURE_FAILHARD,
require = 1)
private void extendWrite(PacketBuffer p_148840_1_, CallbackInfo ci, int i) {
p_148840_1_.writeInt(this.field_149262_d[i]);
if (GeneralConfig.extendBlockItem) {
p_148840_1_.writeInt(this.field_149265_c[i]);
p_148840_1_.writeInt(this.field_149262_d[i]);
} else {
p_148840_1_.writeShort((short)(this.field_149265_c[i] & 65535));
p_148840_1_.writeShort((short)(this.field_149262_d[i] & 65535));
}
p_148840_1_.writeInt(this.field_149260_f[i].length);
}
@Redirect(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 1),
require = 1)
private ByteBuf suppressOldWrite1(PacketBuffer instance, int p_writeShort_1_) {
return null;
}
@Redirect(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 2),
require = 1)
private ByteBuf suppressOldWrite(PacketBuffer instance, int p_writeShort_1_) {
private ByteBuf suppressOldWrite2(PacketBuffer instance, int p_writeShort_1_) {
return null;
}
@@ -64,8 +80,13 @@ public abstract class S26PacketMapChunkBulkMixin {
for (int j = 0; j < short1; ++j) {
this.field_149266_a[j] = data.readInt();
this.field_149264_b[j] = data.readInt();
this.field_149265_c[j] = data.readShort();
this.field_149262_d[j] = data.readInt();
if (GeneralConfig.extendBlockItem) {
this.field_149265_c[j] = data.readInt();
this.field_149262_d[j] = data.readInt();
} else {
this.field_149265_c[j] = data.readShort();
this.field_149262_d[j] = data.readShort();
}
byte[] dataBytes = new byte[data.readInt()];
this.field_149260_f[j] = dataBytes;
System.arraycopy(abyte, i, dataBytes, 0, dataBytes.length);