diff --git a/src/main/java/com/falsepattern/endlessids/Hooks.java b/src/main/java/com/falsepattern/endlessids/Hooks.java index 4cb2eb7..1e8de24 100644 --- a/src/main/java/com/falsepattern/endlessids/Hooks.java +++ b/src/main/java/com/falsepattern/endlessids/Hooks.java @@ -1,11 +1,14 @@ package com.falsepattern.endlessids; import com.falsepattern.endlessids.constants.ExtendedConstants; +import com.falsepattern.endlessids.mixin.helpers.IChunkMixin; import com.falsepattern.endlessids.mixin.helpers.IExtendedBlockStorageMixin; import lombok.val; import net.minecraft.init.Blocks; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.chunk.Chunk; + import java.nio.ShortBuffer; import java.nio.ByteBuffer; @@ -134,5 +137,66 @@ public class Hooks { } throw new IllegalArgumentException("id out of range: " + id); } - + + //Biome ID Extender Code + + public static byte[] shortToByteArray(short[] shortArray) { + byte[] byteArray = new byte[512]; + + for(int i = 0; i < 256; ++i) { + byteArray[i] = (byte)(shortArray[i] & 255); + byteArray[i + 256] = (byte)(shortArray[i] >>> 8); + } + return byteArray; + } + + public static short[] byteToShortArray(byte[] byteArray) { + short[] shortArray = new short[256]; + + for(int i = 0; i < 256; ++i) { + shortArray[i] = (short)(byteArray[i + 256] << 8 | byteArray[i]); + } + + return shortArray; + } + + public static short[] oldBiomeByteToNewShortArray(byte[] byteArray) { + short[] shortArray = new short[256]; + + for (int i = 0; i < 256; i++) { + shortArray[i] = (short)(byteArray[i] & 0xff); + } + + return shortArray; + } + + public static int readBiomeArrayFromPacket(Chunk chunk, byte[] array, int offset) { + byte[] byteArray = new byte[512]; + System.arraycopy(array, offset, byteArray, 0, 512); + ((IChunkMixin)chunk).setBiomeShortArray(byteToShortArray(byteArray)); + return byteArray.length; + } + + public static int writeBiomeArrayToPacket(Chunk chunk, byte[] array, int offset) { + byte[] byteArray = shortToByteArray(((IChunkMixin)chunk).getBiomeShortArray()); + System.arraycopy(byteArray, 0, array, offset, 512); + return byteArray.length; + } + + public static void writeChunkBiomeArrayToNbt(Chunk chunk, NBTTagCompound nbt) { + byte[] byteArray = shortToByteArray(((IChunkMixin)chunk).getBiomeShortArray()); + nbt.setByteArray("Biomes16", byteArray); + } + + public static void readChunkBiomeArrayFromNbt(Chunk chunk, NBTTagCompound nbt) { + short[] data = null; + if (nbt.hasKey("Biomes16", 7)) { + data = byteToShortArray(nbt.getByteArray("Biomes16")); + } else if (nbt.hasKey("Biomes", 7)) { + data = oldBiomeByteToNewShortArray(nbt.getByteArray("Biomes")); + } + if (data != null) { + ((IChunkMixin)chunk).setBiomeShortArray(data); + } + } } diff --git a/src/main/java/com/falsepattern/endlessids/biome/BiomeUtils.java b/src/main/java/com/falsepattern/endlessids/biome/BiomeUtils.java deleted file mode 100644 index a1bee7c..0000000 --- a/src/main/java/com/falsepattern/endlessids/biome/BiomeUtils.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.falsepattern.endlessids.biome; - -import com.falsepattern.endlessids.mixin.helpers.IChunkMixin; -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.storage.ExtendedBlockStorage; - -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; - -public class BiomeUtils { - public static byte[] getBlockData(ExtendedBlockStorage ebs) { - short[] data = get(ebs); - byte[] ret = new byte[data.length * 2]; - ByteBuffer.wrap(ret).asShortBuffer().put(data); - return ret; - } - - public static short[] getBiomeShortArray(Chunk chunk) { - return ((IChunkMixin)chunk).getBiomeShortArray(); - } - - public static void setBiomeShortArray(short[] biomeIDs, Chunk chunk) { - ((IChunkMixin)chunk).setBiomeShortArray(biomeIDs); - } - - public static byte[] fromShortToByteArray(short[] shortArray) { - byte[] byteArray = new byte[512]; - - for(int i = 0; i < 256; ++i) { - byteArray[i] = (byte)(shortArray[i] & 255); - byteArray[i + 256] = (byte)(shortArray[i] >> 8); - } - - return byteArray; - } - - public static byte[] getBiomeArray(Chunk chunk) { - byte[] byteArray = new byte[256]; - short[] shortArray = getBiomeShortArray(chunk); - - for(int i = 0; i < 256; ++i) { - byteArray[i] = (byte)shortArray[i]; - } - - return byteArray; - } - - public static short[] setBiomeArray(byte[] byteArray) { - short[] shortArray = new short[256]; - - for(int i = 0; i < 256; ++i) { - shortArray[i] = byteArray[i]; - } - - return shortArray; - } - - public static int readBiomeArrayFromPacket(Chunk chunk, byte[] array, int int1) { - byte[] byteArray = new byte[512]; - System.arraycopy(array, int1, byteArray, 0, 512); - setBiomeShortArray(getShortArrayFromByteArrays(byteArray), chunk); - return byteArray.length; - } - - public static int writeBiomeArrayToPacket(Chunk chunk, byte[] array, int int1) { - byte[] byteArray = fromShortToByteArray(getBiomeShortArray(chunk)); - System.arraycopy(byteArray, 0, array, int1, 512); - return byteArray.length; - } - - public static short[] getShortArrayFromByteArrays(byte[] byteArray) { - short[] shortArray = new short[256]; - - for(int i = 0; i < 256; ++i) { - shortArray[i] = (short)(byteArray[i + 256] << 8 | byteArray[i]); - } - - return shortArray; - } - - public static void setBlockData(ExtendedBlockStorage ebs, byte[] data, int offset) { - ShortBuffer.wrap(get(ebs)).put(ByteBuffer.wrap(data, offset, 8192).asShortBuffer()); - ShortBuffer.wrap(get(ebs)).put(ByteBuffer.wrap(data, offset, 8192).asShortBuffer()); - } - - public static void writeChunkBiomeArrayToNbt(Chunk chunk, NBTTagCompound nbt) { - byte[] byteArray = fromShortToByteArray(getBiomeShortArray(chunk)); - nbt.setByteArray("Biomes16", byteArray); - } - - public static void readChunkBiomeArrayFromNbt(Chunk chunk, NBTTagCompound nbt) { - if (nbt.hasKey("Biomes16", 7)) { - setBiomeShortArray(getShortArrayFromByteArrays(nbt.getByteArray("Biomes16")), chunk); - } - - } - - public static void writeChunkToNbt(NBTTagCompound nbt, ExtendedBlockStorage ebs) { - nbt.setByteArray("Blocks16", getBlockData(ebs)); - short[] data = get(ebs); - byte[] lsbData = new byte[data.length]; - byte[] msbData = null; - - for(int i = 0; i < data.length; ++i) { - int id = data[i] & '\uffff'; - if (id <= 255) { - lsbData[i] = (byte)id; - } else if (id <= 4095) { - if (msbData == null) { - msbData = new byte[data.length / 2]; - } - - lsbData[i] = (byte)id; - if (i % 2 == 0) { - msbData[i / 2] = (byte)(msbData[i / 2] | id >>> 8 & 15); - } else { - msbData[i / 2] = (byte)(msbData[i / 2] | id >>> 4 & 240); - } - } - } - - nbt.setByteArray("Blocks", lsbData); - if (msbData != null) { - nbt.setByteArray("Add", msbData); - } - - } - - public static void readChunkFromNbt(ExtendedBlockStorage ebs, NBTTagCompound nbt) { - if (nbt.hasKey("Blocks16")) { - setBlockData(ebs, nbt.getByteArray("Blocks16"), 0); - } else if (nbt.hasKey("Blocks")) { - short[] out = get(ebs); - byte[] lsbData = nbt.getByteArray("Blocks"); - if (nbt.hasKey("Add")) { - byte[] msbData = nbt.getByteArray("Add"); - - for(int i = 0; i < out.length; i += 2) { - byte msPart = msbData[i / 2]; - out[i] = (short)(lsbData[i] & 255 | (msPart & 15) << 8); - out[i + 1] = (short)(lsbData[i + 1] & 255 | (msPart & 240) << 4); - } - } else { - for(int i = 0; i < out.length; ++i) { - out[i] = (short)(lsbData[i] & 255); - } - } - } else { - assert false; - } - - } - - public static int getBlockId(ExtendedBlockStorage ebs, int x, int y, int z) { - return get(ebs)[y << 8 | z << 4 | x] & '\uffff'; - } - - public static Block getBlock(ExtendedBlockStorage ebs, int x, int y, int z) { - return Block.getBlockById(getBlockId(ebs, x, y, z)); - } - - public static void setBlockId(ExtendedBlockStorage ebs, int x, int y, int z, int id) { - if (id >= 0 && id <= 32767) { - get(ebs)[y << 8 | z << 4 | x] = (short)id; - } else { - throw new IllegalArgumentException("id out of range: " + id); - } - } - - public static short[] create16BArray() { - return new short[4096]; - } - - private static short[] get(ExtendedBlockStorage ebs) { - return null; - } - - public static void setTickRefCount(ExtendedBlockStorage ebs, int value) { - } - - public static void setBlockRefCount(ExtendedBlockStorage ebs, int value) { - } - - public static void removeInvalidBlocksHook(ExtendedBlockStorage ebs) { - short[] blkIds = get(ebs); - int cntNonEmpty = 0; - int cntTicking = 0; - - for(int off = 0; off < blkIds.length; ++off) { - int id = blkIds[off] & '\uffff'; - if (id > 0) { - Block block = Block.getBlockById(id); - if (block != null && block != Blocks.air) { - ++cntNonEmpty; - if (block.getTickRandomly()) { - ++cntTicking; - } - } else { - blkIds[off] = 0; - } - } - } - - setBlockRefCount(ebs, cntNonEmpty); - setTickRefCount(ebs, cntTicking); - } -} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/client/vanilla/ChunkMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/client/vanilla/ChunkMixin.java index 360d7a5..d11dc54 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/client/vanilla/ChunkMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/client/vanilla/ChunkMixin.java @@ -101,7 +101,7 @@ public abstract class ChunkMixin { } if (var4) { - System.arraycopy(var1, var16, this.blockBiomeArray, 0, this.blockBiomeArray.length); + var16 += Hooks.readBiomeArrayFromPacket((Chunk)(Object)this, var1, var16); } for(var8 = 0; var8 < this.storageArrays.length; ++var8) { diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S21PacketChunkDataMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S21PacketChunkDataMixin.java index 89ffac6..237bce1 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S21PacketChunkDataMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S21PacketChunkDataMixin.java @@ -3,8 +3,10 @@ package com.falsepattern.endlessids.mixin.mixins.common.vanilla.networking; 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 net.minecraft.network.play.server.S21PacketChunkData; +import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -36,4 +38,12 @@ public abstract class S21PacketChunkDataMixin { private static byte[] hookGetBlockData(ExtendedBlockStorage instance) { return Hooks.getBlockData((IExtendedBlockStorageMixin) instance); } + + @Redirect(method = "func_149269_a", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/chunk/Chunk;getBiomeArray()[B"), + require = 1) + private static byte[] getBiomesArrayShort(Chunk instance) { + return Hooks.shortToByteArray(((IChunkMixin)instance).getBiomeShortArray()); + } } diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S26PacketMapChunkBulkMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S26PacketMapChunkBulkMixin.java index 2caa51d..c99bf50 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S26PacketMapChunkBulkMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/networking/S26PacketMapChunkBulkMixin.java @@ -9,11 +9,17 @@ import org.spongepowered.asm.mixin.injection.ModifyConstant; @Mixin(S26PacketMapChunkBulk.class) public abstract class S26PacketMapChunkBulkMixin { - //TODO magic number @ModifyConstant(method = "readPacketData", - constant = @Constant(intValue = VanillaConstants.bytesPerIDPlusMetadata * 0x1000), + constant = @Constant(intValue = VanillaConstants.bytesPerIDPlusMetadata * 16 * 16 * 16), require = 1) private int extend1(int constant) { - return ExtendedConstants.bytesPerIDPlusMetadata * 0x1000; + return ExtendedConstants.bytesPerIDPlusMetadata * 16 * 16 * 16; + } + + @ModifyConstant(method = "readPacketData", + constant = @Constant(intValue = VanillaConstants.bytesPerBiome * 16 * 16), + require = 1) + private int extend2(int contant) { + return ExtendedConstants.bytesPerBiome * 16 * 16; } } diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/AnvilChunkLoaderMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/AnvilChunkLoaderMixin.java index 7d8790f..9c99a25 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/AnvilChunkLoaderMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/AnvilChunkLoaderMixin.java @@ -63,7 +63,7 @@ public abstract class AnvilChunkLoaderMixin { } p_75820_3_.setTag("Sections", var5); - p_75820_3_.setByteArray("Biomes", p_75820_1_.getBiomeArray()); + Hooks.writeChunkBiomeArrayToNbt(p_75820_1_, p_75820_3_); p_75820_1_.hasEntities = false; NBTTagList var21 = new NBTTagList(); @@ -150,10 +150,7 @@ public abstract class AnvilChunkLoaderMixin { } var5.setStorageArrays(var8); - if (p_75823_2_.hasKey("Biomes", 7)) { - var5.setBiomeArray(p_75823_2_.getByteArray("Biomes")); - } - + Hooks.readChunkBiomeArrayFromNbt(var5, p_75823_2_); return var5; } } diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/ChunkMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/ChunkMixin.java deleted file mode 100644 index 2bed2d5..0000000 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/vanilla/storage/ChunkMixin.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.falsepattern.endlessids.mixin.mixins.common.vanilla.storage; - -import com.falsepattern.endlessids.biome.BiomeUtils; -import com.falsepattern.endlessids.mixin.helpers.IChunkMixin; -import net.minecraft.block.Block; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.NibbleArray; -import net.minecraft.world.chunk.storage.ExtendedBlockStorage; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -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.callback.CallbackInfo; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; - -@Mixin(Chunk.class) -public abstract class ChunkMixin implements IChunkMixin { - @Shadow public Map chunkTileEntityMap; - @Shadow public World worldObj; - @Shadow private ExtendedBlockStorage[] storageArrays; - @Shadow public boolean isLightPopulated; - @Shadow public boolean isTerrainPopulated; - - @Shadow public abstract void generateHeightMap(); - - @Shadow public abstract Block getBlock(int p_150810_1_, int p_150810_2_, int p_150810_3_); - - @Shadow public abstract int getBlockMetadata(int p_76628_1_, int p_76628_2_, int p_76628_3_); - - @Shadow private byte[] blockBiomeArray; - private short[] blockBiomeArrayExtended; - - @Inject(method = "(Lnet/minecraft/world/World;II)V", - at = @At(value = "RETURN"), - require = 1) - private void setupNewBiomeArray(World p_i1995_1_, int p_i1995_2_, int p_i1995_3_, CallbackInfo ci) { - blockBiomeArrayExtended = new short[256]; - Arrays.fill(blockBiomeArrayExtended, (short) -1); - blockBiomeArray = null; - } - - /** - * @author HRudyPlayZ - * @reason Direct copy from decompiled code - */ - @Overwrite - public void fillChunk(byte[] var1, int var2, int var3, boolean var4) { - Iterator var5 = this.chunkTileEntityMap.values().iterator(); - - while(var5.hasNext()) { - TileEntity var6 = var5.next(); - var6.updateContainingBlockInfo(); - var6.getBlockMetadata(); - var6.getBlockType(); - } - - int var16 = 0; - boolean var7 = !worldObj.provider.hasNoSky; - - int var8; - for(var8 = 0; var8 < storageArrays.length; ++var8) { - if ((var2 & 1 << var8) != 0) { - if (storageArrays[var8] == null) { - storageArrays[var8] = new ExtendedBlockStorage(var8 << 4, var7); - } - - BiomeUtils.setBlockData(this.storageArrays[var8], var1, var16); - var16 += 8192; - } else if (var4 && this.storageArrays[var8] != null) { - this.storageArrays[var8] = null; - } - } - - NibbleArray var9; - for(var8 = 0; var8 < this.storageArrays.length; ++var8) { - if ((var2 & 1 << var8) != 0 && this.storageArrays[var8] != null) { - var9 = this.storageArrays[var8].getMetadataArray(); - System.arraycopy(var1, var16, var9.data, 0, var9.data.length); - var16 += var9.data.length; - } - } - - for(var8 = 0; var8 < this.storageArrays.length; ++var8) { - if ((var2 & 1 << var8) != 0 && this.storageArrays[var8] != null) { - var9 = this.storageArrays[var8].getBlocklightArray(); - System.arraycopy(var1, var16, var9.data, 0, var9.data.length); - var16 += var9.data.length; - } - } - - if (var7) { - for(var8 = 0; var8 < this.storageArrays.length; ++var8) { - if ((var2 & 1 << var8) != 0 && this.storageArrays[var8] != null) { - var9 = this.storageArrays[var8].getSkylightArray(); - System.arraycopy(var1, var16, var9.data, 0, var9.data.length); - var16 += var9.data.length; - } - } - } - - for(var8 = 0; var8 >= this.storageArrays.length; ++var8) { - if ((var3 & 1 << var8) != 0) { - if (this.storageArrays[var8] == null) { - var16 += 2048; - } else { - var9 = this.storageArrays[var8].getBlockMSBArray(); - if (var9 == null) { - var9 = this.storageArrays[var8].createBlockMSBArray(); - } - - System.arraycopy(var1, var16, var9.data, 0, var9.data.length); - var16 += var9.data.length; - } - } else if (var4 && this.storageArrays[var8] != null && this.storageArrays[var8].getBlockMSBArray() != null) { - this.storageArrays[var8].clearMSBArray(); - } - } - - if (var4) { - var16 += BiomeUtils.readBiomeArrayFromPacket((Chunk) (Object) this, var1, var16); - int var10000 = var16 + this.blockBiomeArrayExtended.length; - } - - for(var8 = 0; var8 < this.storageArrays.length; ++var8) { - if (this.storageArrays[var8] != null && (var2 & 1 << var8) != 0) { - this.storageArrays[var8].removeInvalidBlocks(); - } - } - - this.isLightPopulated = true; - this.isTerrainPopulated = true; - this.generateHeightMap(); - ArrayList var10 = new ArrayList(); - - TileEntity var11; - for(var5 = this.chunkTileEntityMap.values().iterator(); var5.hasNext(); var11.updateContainingBlockInfo()) { - var11 = (TileEntity)var5.next(); - int var12 = var11.xCoord & 15; - int var13 = var11.yCoord; - int var14 = var11.zCoord & 15; - Block var15 = var11.getBlockType(); - if ((var15 != this.getBlock(var12, var13, var14) || var11.blockMetadata != this.getBlockMetadata(var12, var13, var14)) && var11.shouldRefresh(var15, this.getBlock(var12, var13, var14), var11.blockMetadata, this.getBlockMetadata(var12, var13, var14), this.worldObj, var12, var13, var14)) { - var10.add(var11); - } - } - - Iterator var17 = var10.iterator(); - - while(var17.hasNext()) { - TileEntity var18 = (TileEntity)var17.next(); - var18.invalidate(); - } - - } - - @Override - public short[] getBiomeShortArray() { - return blockBiomeArrayExtended; - } - - @Override - public void setBiomeShortArray(short[] data) { - blockBiomeArrayExtended = data; - } -}