mirror of
https://github.com/GTMEGA/EndlessIDs.git
synced 2026-11-13 00:47:27 +00:00
optimized chunk block id memory/network usage
This commit is contained in:
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) {
|
||||
|
||||
+20
-4
@@ -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();
|
||||
}
|
||||
+14
-5
@@ -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",
|
||||
|
||||
-20
@@ -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;
|
||||
}
|
||||
}
|
||||
+8
-18
@@ -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",
|
||||
|
||||
+136
-41
@@ -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) {
|
||||
|
||||
+12
-11
@@ -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;
|
||||
}
|
||||
}
|
||||
-19
@@ -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;
|
||||
}
|
||||
}
|
||||
+78
-5
@@ -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();
|
||||
}
|
||||
}
|
||||
+71
@@ -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
|
||||
|
||||
Reference in new issue
Block a user