optimized chunk block id memory/network usage

This commit is contained in:
FalsePattern committed 2023-03-02 22:41:36 +01:00
1 parent 818f201f30
commit 6f832f4905
11 files changed
+423 -222

No files matched your search

@@ -5,26 +5,74 @@ import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.mixin.helpers.IChunkMixin;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import lombok.val;
import lombok.var;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
public class Hooks {
public static void getBlockData(final IExtendedBlockStorageMixin ebs, final byte[] data, final int offset) {
val lsb = ebs.getLSB();
val msb = ebs.getMSB();
Unsafer.arraycopy(lsb, 0, data, offset, lsb.length);
System.arraycopy(msb, 0, data, offset + lsb.length * 2, msb.length);
public static int getBlockData(final IExtendedBlockStorageMixin ebs, final byte[] data, int offset) {
val b1 = ebs.getB1();
System.arraycopy(b1, 0, data, offset, b1.length);
offset += b1.length;
val b2Low = ebs.getB2Low();
if (b2Low != null) {
System.arraycopy(b2Low.data, 0, data, offset, b2Low.data.length);
offset += b2Low.data.length;
val b2High = ebs.getB2High();
if (b2High != null) {
System.arraycopy(b2High.data, 0, data, offset, b2High.data.length);
offset += b2High.data.length;
val b3 = ebs.getB3();
if (b3 != null) {
System.arraycopy(b3, 0, data, offset, b3.length);
}
}
}
return ebs.getStorageFlag();
}
public static void setBlockData(final IExtendedBlockStorageMixin ebs, final byte[] data, final int offset) {
val lsb = ebs.getLSB();
val msb = ebs.getMSB();
Unsafer.arraycopy(data, offset, lsb, 0, lsb.length);
System.arraycopy(data, offset + lsb.length * 2, msb, 0, msb.length);
public static void setBlockData(final IExtendedBlockStorageMixin ebs, final byte[] data, int offset, final int storageFlag) {
val b1 = ebs.getB1();
System.arraycopy(data, offset, b1, 0, b1.length);
offset += b1.length;
if (storageFlag == 0b00) {
ebs.clearB2Low();
ebs.clearB2High();
ebs.clearB3();
return;
}
var b2Low = ebs.getB2Low();
if (b2Low == null) {
b2Low = ebs.createB2Low();
}
System.arraycopy(data, offset, b2Low.data, 0, b2Low.data.length);
offset += b2Low.data.length;
if (storageFlag == 0b01) {
ebs.clearB2High();
ebs.clearB3();
return;
}
var b2High = ebs.getB2High();
if (b2High == null) {
b2High = ebs.createB2High();
}
System.arraycopy(data, offset, b2High.data, 0, b2High.data.length);
offset += b2High.data.length;
if (storageFlag == 0b10) {
ebs.clearB3();
return;
}
var b3 = ebs.getB3();
if (b3 == null) {
b3 = ebs.createB3();
}
System.arraycopy(data, offset, b3, 0, b3.length);
}
public static void getBlockMeta(final IExtendedBlockStorageMixin ebs, final byte[] data, final int offset) {
@@ -38,103 +86,41 @@ public class Hooks {
}
public static void writeBlockDataToNBT(final NBTTagCompound nbt, final IExtendedBlockStorageMixin ebs) {
val ebsLSB = ebs.getLSB();
val ebsMSB = ebs.getMSB();
val byte1Data = new byte[ebsLSB.length];
byte[] byte2BottomNibbleData = null;
byte[] byte2TopNibbleData = null;
byte[] byte3Data = null;
for (int i = 0; i < ebsLSB.length; ++i) {
if (ebsMSB[i] != 0) {
if (byte3Data == null) {
byte3Data = new byte[ebsLSB.length];
}
byte3Data[i] = ebsMSB[i];
}
val idLSB = (ebsLSB[i] & 0xFFFF);
byte1Data[i] = (byte) (idLSB & 0xFF);
if (idLSB <= 0xFF) {
continue;
}
val nibbleIndex = i >> 1;
val nibbleShift = (i & 1) * 4;
if (byte2BottomNibbleData == null) {
byte2BottomNibbleData = new byte[ebsLSB.length / 2];
}
byte2BottomNibbleData[nibbleIndex] |= ((idLSB >>> 8) & 0xF) << nibbleShift;
if (idLSB <= 0xFFF) {
continue;
}
if (byte2TopNibbleData == null) {
byte2TopNibbleData = new byte[ebsLSB.length / 2];
}
byte2TopNibbleData[nibbleIndex] |= ((idLSB >>> 12) & 0xF) << nibbleShift;
val b1 = ebs.getB1();
val b2Low = ebs.getB2Low();
val b2High = ebs.getB2High();
val b3 = ebs.getB3();
nbt.setByteArray("Blocks", b1);
if (b2Low != null) {
nbt.setByteArray("Add", b2Low.data);
}
nbt.setByteArray("Blocks", byte1Data);
if (byte2BottomNibbleData != null) {
nbt.setByteArray("Add", byte2BottomNibbleData);
if (b2High != null) {
nbt.setByteArray("BlocksB2Hi", b2High.data);
}
if (byte2TopNibbleData != null) {
nbt.setByteArray("BlocksB2Hi", byte2TopNibbleData);
}
if (byte3Data != null) {
nbt.setByteArray("BlocksB3", byte3Data);
if (b3 != null) {
nbt.setByteArray("BlocksB3", b3);
}
}
public static void readBlockDataFromNBT(final IExtendedBlockStorageMixin ebs, final NBTTagCompound nbt) {
assert nbt.hasKey("Blocks");
val byte1Data = nbt.getByteArray("Blocks");
val byte2BottomNibbleData = nbt.hasKey("Add") ? nbt.getByteArray("Add") : null;
val byte2TopNibbleData = nbt.hasKey("BlocksB2Hi") ? nbt.getByteArray("BlocksB2Hi") : null;
val byte3Data = nbt.hasKey("BlocksB3") ? nbt.getByteArray("BlocksB3") : null;
val b1 = nbt.getByteArray("Blocks");
final byte[] b2Low = nbt.hasKey("Add") ? nbt.getByteArray("Add") : null;
final byte[] b2High = nbt.hasKey("BlocksB2Hi") ? nbt.getByteArray("BlocksB2Hi") : null;
final byte[] b3 = nbt.hasKey("BlocksB3") ? nbt.getByteArray("BlocksB3") : null;
val lsb = ebs.getLSB();
val msb = ebs.getMSB();
for (int i = 0; i < lsb.length; i++) {
if (byte3Data != null) {
msb[i] = byte3Data[i];
}
int nibbleShift = (i & 1) * 4;
int id = byte1Data[i] & 0xFF;
if (byte2BottomNibbleData != null) {
id |= ((byte2BottomNibbleData[i >> 1] >> nibbleShift) & 0xF) << 8;
}
if (byte2TopNibbleData != null) {
id |= ((byte2TopNibbleData[i >> 1] >> nibbleShift) & 0xF) << 12;
}
lsb[i] = (short) id;
ebs.setB1(b1);
if (b2Low == null) {
ebs.clearB2Low();
} else {
ebs.setB2Low(new NibbleArray(b2Low, 4));
}
}
public static void removeInvalidBlocksHook(final IExtendedBlockStorageMixin ebs) {
val blkIdsLSB = ebs.getLSB();
val blkIdsMSB = ebs.getMSB();
int cntNonEmpty = 0;
int cntTicking = 0;
for (int off = 0; off < blkIdsLSB.length; ++off) {
final int id =
((blkIdsLSB[off] & 0xFFFF) | ((blkIdsMSB[off] & 0xFF) << 16)) & ExtendedConstants.blockIDMask;
if (id > 0) {
final Block block = (Block) Block.blockRegistry.getObjectById(id);
if (block == null) {
if (GeneralConfig.removeInvalidBlocks) {
blkIdsLSB[off] = 0;
}
} else if (block != Blocks.air) {
++cntNonEmpty;
if (block.getTickRandomly()) {
++cntTicking;
}
}
}
if (b2High == null) {
ebs.clearB2High();
} else {
ebs.setB2High(new NibbleArray(b2High, 4));
}
ebs.setBlockRefCount(cntNonEmpty);
ebs.setTickRefCount(cntTicking);
ebs.setB3(b3);
}
public static int getIdFromBlockWithCheck(final Block block, final Block oldBlock) {
@@ -1,13 +1,29 @@
package com.falsepattern.endlessids.mixin.helpers;
import net.minecraft.world.chunk.NibbleArray;
public interface IExtendedBlockStorageMixin {
void setBlockRefCount(int value);
byte[] getB1();
void setB1(byte[] data);
void setTickRefCount(int value);
NibbleArray getB2Low();
void setB2Low(NibbleArray data);
void clearB2Low();
NibbleArray createB2Low();
short[] getLSB();
NibbleArray getB2High();
void setB2High(NibbleArray data);
void clearB2High();
NibbleArray createB2High();
byte[] getMSB();
byte[] getB3();
void setB3(byte[] data);
void clearB3();
byte[] createB3();
int getStorageFlag();
int getID(int x, int y, int z);
short[] getMetaArray();
}
@@ -3,6 +3,7 @@ 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;
@@ -25,9 +26,6 @@ public abstract class ChunkMixin {
@Shadow
private ExtendedBlockStorage[] storageArrays;
//This is needed because the array is not a field, but a local, and local arraylength overriding does not exist
private static byte[] fakeArray;
@Redirect(method = "fillChunk",
at = @At(value = "FIELD",
target = "Lnet/minecraft/world/chunk/Chunk;storageArrays:[Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;",
@@ -47,15 +45,26 @@ 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) {
Hooks.setBlockData((IExtendedBlockStorageMixin) this.storageArrays[l], p_76607_1_, k);
val storageFlag = (p_76607_3_ >>> l) & 0b11;
Hooks.setBlockData((IExtendedBlockStorageMixin) this.storageArrays[l], p_76607_1_, k, storageFlag);
}
//This is needed because the array is not a field, but a local, and local arraylength overriding does not exist
private static byte[][] fakeArrays;
@Redirect(method = "fillChunk",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockLSBArray()[B"),
require = 1)
private byte[] fakeLSBArray(ExtendedBlockStorage instance) {
return fakeArray != null ? fakeArray : (fakeArray = new byte[16 * 16 * 16 * ExtendedConstants.bytesPerID]);
if (fakeArrays == null) {
fakeArrays = new byte[4][];
fakeArrays[0] = new byte[16 * 16 * 16 * 2 / 2];
fakeArrays[1] = new byte[16 * 16 * 16 * 3 / 2];
fakeArrays[2] = new byte[16 * 16 * 16 * 4 / 2];
fakeArrays[3] = new byte[16 * 16 * 16 * 6 / 2];
}
return fakeArrays[((IExtendedBlockStorageMixin)instance).getStorageFlag()];
}
@Redirect(method = "fillChunk",
@@ -1,20 +0,0 @@
package com.falsepattern.endlessids.mixin.mixins.common.biome.vanilla;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.constants.VanillaConstants;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
@Mixin(S26PacketMapChunkBulk.class)
public abstract class S26PacketMapChunkBulkMixin {
@ModifyConstant(method = "readPacketData",
constant = @Constant(intValue = VanillaConstants.bytesPerBiome * 16 * 16),
require = 1)
private int extend2(int contant) {
return ExtendedConstants.bytesPerBiome * 16 * 16;
}
}
@@ -3,6 +3,7 @@ package com.falsepattern.endlessids.mixin.mixins.common.blockitem.ubc;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import exterminatorJeff.undergroundBiomes.worldGen.BiomeUndergroundDecorator;
import exterminatorJeff.undergroundBiomes.worldGen.OreUBifier;
import lombok.val;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -16,7 +17,7 @@ import java.util.logging.Logger;
remap = false)
public abstract class BiomeUndergroundDecoratorMixin {
private static NibbleArray fakeArray;
private ThreadLocal<IExtendedBlockStorageMixin> ebs;
private IExtendedBlockStorageMixin ebs;
@Redirect(method = {"replaceChunkOres(IILnet/minecraft/world/World;)V",
"replaceChunkOres(Lnet/minecraft/world/chunk/IChunkProvider;II)V"},
@@ -24,13 +25,10 @@ public abstract class BiomeUndergroundDecoratorMixin {
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockLSBArray()[B",
remap = true),
require = 2)
private byte[] returnMSBasLSB(ExtendedBlockStorage instance) {
if (ebs == null) {
ebs = new ThreadLocal<>();
}
private byte[] returnLSB(ExtendedBlockStorage instance) {
IExtendedBlockStorageMixin iebs = (IExtendedBlockStorageMixin) instance;
ebs.set(iebs);
return iebs.getMSB();
ebs = iebs;
return iebs.getB1();
}
@Redirect(method = {"replaceChunkOres(IILnet/minecraft/world/World;)V",
@@ -50,17 +48,9 @@ public abstract class BiomeUndergroundDecoratorMixin {
remap = true),
require = 2)
private int returnRestOfID(NibbleArray instance, int x, int y, int z) {
return ebs.get().getLSB()[y << 8 | z << 4 | x] & 0xFFFF;
}
@Redirect(method = {"replaceChunkOres(IILnet/minecraft/world/World;)V",
"replaceChunkOres(Lnet/minecraft/world/chunk/IChunkProvider;II)V"},
at = @At(value = "INVOKE",
target = "LexterminatorJeff/undergroundBiomes/worldGen/OreUBifier;blockReplacer(I)LexterminatorJeff/undergroundBiomes/worldGen/OreUBifier$BlockReplacer;"),
require = 2)
private OreUBifier.BlockReplacer reshuffleID(OreUBifier instance, int blockID) {
blockID = ((blockID & 0xFF) << 16) | ((blockID & 0xFFFF00) >>> 8);
return instance.blockReplacer(blockID);
val id = ebs.getID(x, y, z) >>> 8;
ebs = null;
return id;
}
@Redirect(method = "correctBiomeDecorators",
@@ -3,9 +3,10 @@ package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla;
import com.falsepattern.endlessids.EndlessIDs;
import com.falsepattern.endlessids.Hooks;
import com.falsepattern.endlessids.Tags;
import com.falsepattern.endlessids.config.GeneralConfig;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import lombok.val;
import org.objectweb.asm.Opcodes;
import lombok.var;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
@@ -28,30 +29,12 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
private int tickRefCount;
@Shadow private byte[] blockLSBArray;
@Shadow private NibbleArray blockMetadataArray;
private short[] lsbArray;
private byte[] msbArray;
@Shadow private NibbleArray blockMSBArray;
private NibbleArray b2High;
private byte[] b3;
private short[] metaArray;
@Override
public void setBlockRefCount(int value) {
blockRefCount = value;
}
@Override
public void setTickRefCount(int value) {
tickRefCount = value;
}
@Override
public short[] getLSB() {
return lsbArray;
}
@Override
public byte[] getMSB() {
return msbArray;
}
@Override
public short[] getMetaArray() {
return metaArray;
@@ -61,26 +44,50 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
at = @At(value = "RETURN"),
require = 1)
private void init(CallbackInfo ci) {
blockLSBArray = null;
blockMetadataArray = null;
lsbArray = new short[16 * 16 * 16];
msbArray = new byte[16 * 16 * 16];
metaArray = new short[16 * 16 * 16];
}
private int getID(int x, int y, int z) {
public int getID(int x, int y, int z) {
int index = y << 8 | z << 4 | x;
int lsb = lsbArray[index] & 0xFFFF;
int msb = (msbArray[index] & 0xFF) << 16;
return lsb | msb;
int id = blockLSBArray[index] & 0xFF;
if (blockMSBArray != null) {
id |= blockMSBArray.get(x, y, z) << 8;
if (b2High != null) {
id |= b2High.get(x, y, z) << 12;
if (b3 != null) {
id |= (b3[index] & 0xFF) << 16;
}
}
}
return id;
}
private void setID(int x, int y, int z, int id) {
int index = y << 8 | z << 4 | x;
int lsb = id & 0xFFFF;
int msb = (id >>> 16) & 0xFF;
lsbArray[index] = (short) lsb;
msbArray[index] = (byte) msb;
blockLSBArray[index] = (byte) (id & 0xFF);
if (id > 0xFF) {
if (blockMSBArray == null) {
blockMSBArray = new NibbleArray(blockLSBArray.length, 4);
}
if (id > 0xFFF) {
if (b2High == null) {
b2High = new NibbleArray(blockLSBArray.length, 4);
}
if (id > 0xFFFF && b3 == null) {
b3 = new byte[blockLSBArray.length];
}
}
}
if (blockMSBArray != null) {
blockMSBArray.set(x, y, z, (id >>> 8) & 0xF);
if (b2High != null) {
b2High.set(x, y, z, (id >>> 12) & 0xF);
if (b3 != null) {
b3[index] = (byte) ((id >>> 16) & 0xFF);
}
}
}
}
/**
@@ -137,13 +144,17 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
metaArray[index] = (short)(meta & 0xFFFF);
}
/**
* @author FalsePattern
* @reason Direct port from dumped code
*/
@Overwrite
public void removeInvalidBlocks() {
Hooks.removeInvalidBlocksHook(this);
@Redirect(method = "removeInvalidBlocks",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockByExtId(III)Lnet/minecraft/block/Block;"),
require = 1)
private Block removeInvalidBlocks(ExtendedBlockStorage instance, int x, int y, int z) {
var block = instance.getBlockByExtId(x, y, z);
if (block == null && GeneralConfig.removeInvalidBlocks) {
instance.func_150818_a(x, y, z, Blocks.air);
block = Blocks.air;
}
return block;
}
private UnsupportedOperationException emergencyCrash() {
@@ -154,6 +165,90 @@ public abstract class ExtendedBlockStorageMixin implements IExtendedBlockStorage
return new UnsupportedOperationException(crashMSG);
}
@Override
public byte[] getB1() {
return blockLSBArray;
}
@Override
public void setB1(byte[] data) {
blockLSBArray = data;
}
@Override
public NibbleArray getB2Low() {
return blockMSBArray;
}
@Override
public void clearB2Low() {
blockMSBArray = null;
}
@Override
public void setB2Low(NibbleArray data) {
blockMSBArray = data;
}
@Override
public NibbleArray createB2Low() {
return (blockMSBArray = new NibbleArray(blockLSBArray.length, 4));
}
@Override
public NibbleArray getB2High() {
return b2High;
}
@Override
public void setB2High(NibbleArray data) {
b2High = data;
}
@Override
public void clearB2High() {
b2High = null;
}
@Override
public NibbleArray createB2High() {
return (b2High = new NibbleArray(blockLSBArray.length, 4));
}
@Override
public byte[] getB3() {
return b3;
}
@Override
public void setB3(byte[] data) {
b3 = data;
}
@Override
public void clearB3() {
b3 = null;
}
@Override
public byte[] createB3() {
return b3 = new byte[blockLSBArray.length];
}
@Override
public int getStorageFlag() {
if (blockMSBArray == null) {
return 0b00;
}
if (b2High == null) {
return 0b01;
}
if (b3 == 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.EndlessIDs;
import com.falsepattern.endlessids.Hooks;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.constants.VanillaConstants;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import lombok.val;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
@@ -37,16 +37,24 @@ public abstract class S21PacketChunkDataMixin {
locals = LocalCapture.CAPTURE_FAILHARD,
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) {
Hooks.getBlockData((IExtendedBlockStorageMixin) aextendedblockstorage[l], abyte, j);
val ebs = (IExtendedBlockStorageMixin) aextendedblockstorage[l];
extracted.field_150281_c |= Hooks.getBlockData(ebs, abyte, j) << l * 2;
}
private static byte[] fakeArray;
private static byte[][] fakeArrays;
@Redirect(method = "func_149269_a",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockLSBArray()[B"),
require = 1)
private static byte[] hookGetBlockDataFakeArray(ExtendedBlockStorage instance) {
return fakeArray != null ? fakeArray : (fakeArray = new byte[16 * 16 * 16 * ExtendedConstants.bytesPerID]);
if (fakeArrays == null) {
fakeArrays = new byte[4][];
fakeArrays[0] = new byte[16 * 16 * 16 * 2 / 2];
fakeArrays[1] = new byte[16 * 16 * 16 * 3 / 2];
fakeArrays[2] = new byte[16 * 16 * 16 * 4 / 2];
fakeArrays[3] = new byte[16 * 16 * 16 * 6 / 2];
}
return fakeArrays[((IExtendedBlockStorageMixin)instance).getStorageFlag()];
}
@Redirect(method = "func_149269_a",
@@ -103,11 +111,4 @@ public abstract class S21PacketChunkDataMixin {
private static void hookGetBlockMetaNoCopy(Object src, int srcPos, Object dest, int destPos, int length) {
}
@ModifyConstant(method = "readPacketData",
constant = @Constant(intValue = VanillaConstants.bytesPerEBS),
require = 1)
private int increaseReadSize(int constant) {
return ExtendedConstants.bytesPerEBS;
}
}
@@ -1,19 +0,0 @@
package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.constants.VanillaConstants;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
@Mixin(S26PacketMapChunkBulk.class)
public abstract class S26PacketMapChunkBulkMixin {
@ModifyConstant(method = "readPacketData",
constant = @Constant(intValue = VanillaConstants.bytesPerIDPlusMetadata * 16 * 16 * 16),
require = 1)
private int extend1(int constant) {
return ExtendedConstants.bytesPerIDPlusMetadata * 16 * 16 * 16;
}
}
@@ -1,26 +1,99 @@
package com.falsepattern.endlessids.mixin.mixins.common.vanilla;
import com.falsepattern.endlessids.Hooks;
import com.falsepattern.endlessids.constants.ExtendedConstants;
import com.falsepattern.endlessids.constants.VanillaConstants;
import com.falsepattern.endlessids.mixin.helpers.IChunkMixin;
import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin;
import io.netty.buffer.ByteBuf;
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.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.S21PacketChunkData;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
@Mixin(S21PacketChunkData.class)
public abstract class S21PacketChunkDataMixin {
@Shadow private int field_149280_d;
@Shadow private byte[] field_149278_f;
@Shadow private int field_149284_a;
@Shadow private int field_149282_b;
@Shadow private boolean field_149279_g;
@Shadow private int field_149283_c;
@Shadow private int field_149285_h;
@Shadow private static byte[] field_149286_i;
@ModifyConstant(method = {"<clinit>", "func_149275_c"},
constant = @Constant(intValue = VanillaConstants.bytesPerChunk),
require = 1)
private static int increasePacketSize(int constant) {
return ExtendedConstants.bytesPerChunk;
}
@Inject(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 1),
require = 1)
private void extendWrite(PacketBuffer p_148840_1_, CallbackInfo ci) {
p_148840_1_.writeInt(this.field_149280_d);
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 = 1),
require = 1)
private ByteBuf suppressOldWrite(PacketBuffer instance, int p_writeShort_1_) {
return null;
}
@Inject(method = "readPacketData",
at = @At("HEAD"),
require = 1,
cancellable = true)
private void customRead(PacketBuffer data, CallbackInfo ci) throws IOException {
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();
int length = data.readInt();
this.field_149285_h = data.readInt();
if (field_149286_i.length < this.field_149285_h) {
field_149286_i = new byte[this.field_149285_h];
}
data.readBytes(field_149286_i, 0, this.field_149285_h);
this.field_149278_f = new byte[length];
Inflater inflater = new Inflater();
inflater.setInput(field_149286_i, 0, this.field_149285_h);
try {
inflater.inflate(this.field_149278_f);
} catch (DataFormatException dataformatexception) {
throw new IOException("Bad compressed data format");
} finally {
inflater.end();
}
ci.cancel();
}
}
@@ -0,0 +1,71 @@
package com.falsepattern.endlessids.mixin.mixins.common.vanilla;
import io.netty.buffer.ByteBuf;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.S26PacketMapChunkBulk;
import java.util.zip.Inflater;
@Mixin(S26PacketMapChunkBulk.class)
public abstract class S26PacketMapChunkBulkMixin {
@Shadow private int[] field_149262_d;
@Shadow private byte[][] field_149260_f;
@Shadow private int[] field_149266_a;
@Shadow private int[] field_149264_b;
@Shadow private int[] field_149265_c;
@Inject(method = "writePacketData",
at = @At(value = "INVOKE",
target = "Lnet/minecraft/network/PacketBuffer;writeShort(I)Lio/netty/buffer/ByteBuf;",
ordinal = 2),
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]);
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 = 2),
require = 1)
private ByteBuf suppressOldWrite(PacketBuffer instance, int p_writeShort_1_) {
return null;
}
@Inject(method = "readPacketData",
at = @At(value = "INVOKE",
target = "Ljava/util/zip/Inflater;inflate([B)I",
shift = At.Shift.AFTER),
require = 1,
locals = LocalCapture.CAPTURE_FAILHARD,
cancellable = true)
private void customRead(PacketBuffer data, CallbackInfo ci, short short1, byte[] abyte, Inflater inflater) {
int i = 0;
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();
byte[] dataBytes = new byte[data.readInt()];
this.field_149260_f[j] = dataBytes;
System.arraycopy(abyte, i, dataBytes, 0, dataBytes.length);
i += dataBytes.length;
}
ci.cancel();
}
}
@@ -19,6 +19,7 @@ public enum Mixin implements IMixin {
//region common
//region vanilla
S21PacketChunkDataMixin(Side.COMMON, always(), "vanilla.S21PacketChunkDataMixin"),
S26PacketMapChunkBulkMixin(Side.COMMON, always(), "vanilla.S26PacketMapChunkBulkMixin"),
//endregion vanilla
//region AntiIDConflict
AIDCAntiIdConflictBaseMixin(Side.COMMON, require(TargetedMod.ANTIIDCONFLICT), "antiidconflict.AntiIdConflictBaseMixin"),
@@ -38,7 +39,6 @@ public enum Mixin implements IMixin {
GenLayerRiverMixMixin(Side.COMMON, condition(() -> GeneralConfig.extendBiome).and(avoid(TargetedMod.DRAGONAPI)), "biome.vanilla.GenLayerRiverMixMixin"),
GenLayerVoronoiZoomMixin(Side.COMMON, condition(() -> GeneralConfig.extendBiome), "biome.vanilla.GenLayerVoronoiZoomMixin"),
S21PacketChunkDataMixinBiome(Side.COMMON, condition(() -> GeneralConfig.extendBiome), "biome.vanilla.S21PacketChunkDataMixin"),
S26PacketMapChunkBulkMixinBiome(Side.COMMON, condition(() -> GeneralConfig.extendBiome), "biome.vanilla.S26PacketMapChunkBulkMixin"),
//endregion vanilla
//region AbyssalCraft
AbyssalCraftMixin(Side.COMMON, condition(() -> GeneralConfig.extendBiome).and(require(TargetedMod.ABYSSALCRAFT)), "biome.abyssalcraft.AbyssalCraftMixin"),
@@ -173,7 +173,6 @@ public enum Mixin implements IMixin {
S21PacketChunkDataMixinBlockItem(Side.COMMON, condition(() -> GeneralConfig.extendBlockItem), "blockitem.vanilla.S21PacketChunkDataMixin"),
S22PacketMultiBlockChangeMixin(Side.COMMON, condition(() -> GeneralConfig.extendBlockItem), "blockitem.vanilla.S22PacketMultiBlockChangeMixin"),
S24PacketBlockActionMixin(Side.COMMON, condition(() -> GeneralConfig.extendBlockItem), "blockitem.vanilla.S24PacketBlockActionMixin"),
S26PacketMapChunkBulkMixinBlockItem(Side.COMMON, condition(() -> GeneralConfig.extendBlockItem), "blockitem.vanilla.S26PacketMapChunkBulkMixin"),
StatListMixin(Side.COMMON, condition(() -> GeneralConfig.extendBlockItem), "blockitem.vanilla.StatListMixin"),
WorldMixin(Side.COMMON, condition(() -> GeneralConfig.extendBlockItem), "blockitem.vanilla.WorldMixin"),
//endregion vanilla