diff --git a/build.gradle b/build.gradle index 0a0eb84..7620bfa 100644 --- a/build.gradle +++ b/build.gradle @@ -23,7 +23,7 @@ dependencies { } teavm.js { - obfuscated = true + obfuscated = false sourceMap = false targetFileName = "../classes.js" optimization = org.teavm.gradle.api.OptimizationLevel.AGGRESSIVE diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/AbstractByteBuf.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/AbstractByteBuf.java index 65a691a..16ffe0f 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/AbstractByteBuf.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/AbstractByteBuf.java @@ -848,7 +848,7 @@ public abstract class AbstractByteBuf extends ByteBuf { } return writtenBytes; } - + @Override public ByteBuf writeZero(int length) { if (length == 0) { @@ -971,12 +971,12 @@ public abstract class AbstractByteBuf extends ByteBuf { // Causes infinite loop /* - ByteBuf unwrapped = unwrap(); - if (unwrapped != null) { - buf.append(", unwrapped: ").append(unwrapped); - } - */ - + * ByteBuf unwrapped = unwrap(); + * if (unwrapped != null) { + * buf.append(", unwrapped: ").append(unwrapped); + * } + */ + buf.append(')'); return buf.toString(); } diff --git a/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/Unpooled.java b/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/Unpooled.java index d25666a..ced315e 100644 --- a/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/Unpooled.java +++ b/src/main/java/net/lax1dude/eaglercraft/v1_8/netty/Unpooled.java @@ -5,14 +5,21 @@ import java.nio.ByteBuffer; /** * Copyright (c) 2022 lax1dude. All Rights Reserved. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * @@ -44,4 +51,8 @@ public class Unpooled { public static ByteBuf wrappedBuffer(ByteBuf buf) { return buf.duplicate(); } + + public static ByteBuf wrappedBuffer(byte[] array) { + return ByteBuf.allocate(ByteBuffer.wrap(array), Integer.MAX_VALUE); + } } diff --git a/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java b/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java index 3974f58..f55a9c1 100644 --- a/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java +++ b/src/main/java/net/minecraft/client/network/NetHandlerPlayClient.java @@ -101,6 +101,7 @@ import net.minecraft.inventory.InventoryBasic; import net.minecraft.item.Item; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; import net.minecraft.network.play.INetHandlerPlayClient; @@ -146,7 +147,6 @@ import net.minecraft.network.play.server.S22PacketMultiBlockChange.BlockUpdateDa import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraft.network.play.server.S24PacketBlockAction; import net.minecraft.network.play.server.S25PacketBlockBreakAnim; -import net.minecraft.network.play.server.S26PacketMapChunkBulk; import net.minecraft.network.play.server.S27PacketExplosion; import net.minecraft.network.play.server.S28PacketEffect; import net.minecraft.network.play.server.S29PacketSoundEffect; @@ -724,25 +724,30 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient { * for re-rendering and lighting recalculation */ public void handleChunkData(S21PacketChunkData packetIn) { - if (packetIn.func_149274_i()) { - if (packetIn.getExtractedSize() == 0) { - this.clientWorldController.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), false); - return; - } - + if (packetIn.doChunkLoad()) { this.clientWorldController.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), true); } this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 256, (packetIn.getChunkZ() << 4) + 15); Chunk chunk = this.clientWorldController.getChunkFromChunkCoords(packetIn.getChunkX(), packetIn.getChunkZ()); - chunk.fillChunk(packetIn.func_149272_d(), packetIn.getExtractedSize(), packetIn.func_149274_i()); + chunk.fillChunk(packetIn.getReadBuffer(), packetIn.getExtractedSize(), packetIn.doChunkLoad()); this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 256, (packetIn.getChunkZ() << 4) + 15); - if (!packetIn.func_149274_i() || !(this.clientWorldController.provider instanceof WorldProviderSurface)) { + + if (!packetIn.doChunkLoad() || !(this.clientWorldController.provider instanceof WorldProviderSurface)) { chunk.resetRelightChecks(); } + for (NBTTagCompound nbttagcompound : packetIn.func_189554_f()) { + BlockPos blockpos = new BlockPos(nbttagcompound.getInteger("x"), nbttagcompound.getInteger("y"), + nbttagcompound.getInteger("z")); + TileEntity tileentity = this.clientWorldController.getTileEntity(blockpos); + + if (tileentity != null) { + tileentity.readFromNBT(nbttagcompound); + } + } } /** @@ -1233,24 +1238,6 @@ public class NetHandlerPlayClient implements INetHandlerPlayClient { packetIn.getProgress()); } - public void handleMapChunkBulk(S26PacketMapChunkBulk packetIn) { - for (int i = 0; i < packetIn.getChunkCount(); ++i) { - int j = packetIn.getChunkX(i); - int k = packetIn.getChunkZ(i); - this.clientWorldController.doPreChunk(j, k, true); - this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 256, - (k << 4) + 15); - Chunk chunk = this.clientWorldController.getChunkFromChunkCoords(j, k); - chunk.fillChunk(packetIn.getChunkBytes(i), packetIn.getChunkSize(i), true); - this.clientWorldController.markBlockRangeForRenderUpdate(j << 4, 0, k << 4, (j << 4) + 15, 256, - (k << 4) + 15); - if (!(this.clientWorldController.provider instanceof WorldProviderSurface)) { - chunk.resetRelightChecks(); - } - } - - } - public void handleChangeGameState(S2BPacketChangeGameState packetIn) { EntityPlayerSP entityplayersp = this.gameController.thePlayer; int i = packetIn.getGameState(); diff --git a/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java b/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java index ddd4b9e..299fc89 100644 --- a/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java +++ b/src/main/java/net/minecraft/entity/player/EntityPlayerMP.java @@ -51,7 +51,6 @@ import net.minecraft.network.play.server.S1DPacketEntityEffect; import net.minecraft.network.play.server.S1EPacketRemoveEntityEffect; import net.minecraft.network.play.server.S1FPacketSetExperience; import net.minecraft.network.play.server.S21PacketChunkData; -import net.minecraft.network.play.server.S26PacketMapChunkBulk; import net.minecraft.network.play.server.S29PacketSoundEffect; import net.minecraft.network.play.server.S2BPacketChangeGameState; import net.minecraft.network.play.server.S2DPacketOpenWindow; @@ -345,11 +344,9 @@ public class EntityPlayerMP extends EntityPlayer implements ICrafting { } if (!arraylist.isEmpty()) { - if (arraylist.size() == 1) { + for (int k = 0; k < arraylist.size(); ++k) { this.playerNetServerHandler - .sendPacket(new S21PacketChunkData((Chunk) arraylist.get(0), true, '\uffff')); - } else { - this.playerNetServerHandler.sendPacket(new S26PacketMapChunkBulk(arraylist)); + .sendPacket(new S21PacketChunkData((Chunk) arraylist.get(k), true, '\uffff')); } for (int i = 0, l = arraylist1.size(); i < l; ++i) { diff --git a/src/main/java/net/minecraft/network/EnumConnectionState.java b/src/main/java/net/minecraft/network/EnumConnectionState.java index c328ea4..38fe76a 100644 --- a/src/main/java/net/minecraft/network/EnumConnectionState.java +++ b/src/main/java/net/minecraft/network/EnumConnectionState.java @@ -71,7 +71,6 @@ import net.minecraft.network.play.server.S22PacketMultiBlockChange; import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraft.network.play.server.S24PacketBlockAction; import net.minecraft.network.play.server.S25PacketBlockBreakAnim; -import net.minecraft.network.play.server.S26PacketMapChunkBulk; import net.minecraft.network.play.server.S27PacketExplosion; import net.minecraft.network.play.server.S28PacketEffect; import net.minecraft.network.play.server.S29PacketSoundEffect; @@ -184,7 +183,7 @@ public enum EnumConnectionState { this.registerPacket(EnumPacketDirection.CLIENTBOUND, S23PacketBlockChange.class); this.registerPacket(EnumPacketDirection.CLIENTBOUND, S24PacketBlockAction.class); this.registerPacket(EnumPacketDirection.CLIENTBOUND, S25PacketBlockBreakAnim.class); - this.registerPacket(EnumPacketDirection.CLIENTBOUND, S26PacketMapChunkBulk.class); + this.registerPacket(EnumPacketDirection.CLIENTBOUND, new PlaceholderPacket().getClass()); this.registerPacket(EnumPacketDirection.CLIENTBOUND, S27PacketExplosion.class); this.registerPacket(EnumPacketDirection.CLIENTBOUND, S28PacketEffect.class); this.registerPacket(EnumPacketDirection.CLIENTBOUND, S29PacketSoundEffect.class); diff --git a/src/main/java/net/minecraft/network/PacketBuffer.java b/src/main/java/net/minecraft/network/PacketBuffer.java index 3ebf078..ed839d6 100644 --- a/src/main/java/net/minecraft/network/PacketBuffer.java +++ b/src/main/java/net/minecraft/network/PacketBuffer.java @@ -9,6 +9,8 @@ import java.nio.ByteOrder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import javax.annotation.Nullable; + import net.lax1dude.eaglercraft.v1_8.DecoderException; import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; import net.lax1dude.eaglercraft.v1_8.EncoderException; @@ -76,6 +78,79 @@ public class PacketBuffer extends ByteBuf { return 5; } + /** + * Writes an array of VarInts to the buffer, prefixed by the length of the array + * (as a VarInt). + */ + public PacketBuffer writeVarIntArray(int[] array) { + this.writeVarIntToBuffer(array.length); + + for (int i = 0; i < array.length; ++i) { + this.writeVarIntToBuffer(array[i]); + } + + return this; + } + + public int[] readVarIntArray() { + return this.func_189424_c(this.readableBytes()); + } + + public int[] func_189424_c(int p_189424_1_) { + int i = this.readVarIntFromBuffer(); + + if (i > p_189424_1_) { + throw new DecoderException("VarIntArray with size " + i + " is bigger than allowed " + p_189424_1_); + } else { + int[] aint = new int[i]; + + for (int j = 0; j < aint.length; ++j) { + aint[j] = this.readVarIntFromBuffer(); + } + + return aint; + } + } + + /** + * Writes an array of longs to the buffer, prefixed by the length of the array + * (as a VarInt). + */ + public PacketBuffer writeLongArray(long[] array) { + this.writeVarIntToBuffer(array.length); + + for (int i = 0; i < array.length; ++i) { + this.writeLong(array[i]); + } + + return this; + } + + /** + * Reads a length-prefixed array of longs from the buffer. + */ + public long[] readLongArray(@Nullable long[] array) { + return this.func_189423_a(array, this.readableBytes() / 8); + } + + public long[] func_189423_a(@Nullable long[] p_189423_1_, int p_189423_2_) { + int i = this.readVarIntFromBuffer(); + + if (p_189423_1_ == null || p_189423_1_.length != i) { + if (i > p_189423_2_) { + throw new DecoderException("LongArray with size " + i + " is bigger than allowed " + p_189423_2_); + } + + p_189423_1_ = new long[i]; + } + + for (int j = 0; j < p_189423_1_.length; ++j) { + p_189423_1_[j] = this.readLong(); + } + + return p_189423_1_; + } + public void writeByteArray(byte[] array) { this.writeVarIntToBuffer(array.length); this.writeBytes(array); diff --git a/src/main/java/net/minecraft/network/PlaceholderPacket.java b/src/main/java/net/minecraft/network/PlaceholderPacket.java new file mode 100644 index 0000000..7775c6b --- /dev/null +++ b/src/main/java/net/minecraft/network/PlaceholderPacket.java @@ -0,0 +1,17 @@ +package net.minecraft.network; + +import net.minecraft.network.play.INetHandlerPlayClient; + +public class PlaceholderPacket implements Packet { + public PlaceholderPacket() { + } + + public void readPacketData(PacketBuffer buf) { + } + + public void writePacketData(PacketBuffer buf) { + } + + public void processPacket(INetHandlerPlayClient handler) { + } +} diff --git a/src/main/java/net/minecraft/network/play/INetHandlerPlayClient.java b/src/main/java/net/minecraft/network/play/INetHandlerPlayClient.java index b0acc01..e88a5b9 100644 --- a/src/main/java/net/minecraft/network/play/INetHandlerPlayClient.java +++ b/src/main/java/net/minecraft/network/play/INetHandlerPlayClient.java @@ -36,7 +36,6 @@ import net.minecraft.network.play.server.S22PacketMultiBlockChange; import net.minecraft.network.play.server.S23PacketBlockChange; import net.minecraft.network.play.server.S24PacketBlockAction; import net.minecraft.network.play.server.S25PacketBlockBreakAnim; -import net.minecraft.network.play.server.S26PacketMapChunkBulk; import net.minecraft.network.play.server.S27PacketExplosion; import net.minecraft.network.play.server.S28PacketEffect; import net.minecraft.network.play.server.S29PacketSoundEffect; @@ -337,8 +336,6 @@ public interface INetHandlerPlayClient extends INetHandler { */ void handleChunkData(S21PacketChunkData var1); - void handleMapChunkBulk(S26PacketMapChunkBulk var1); - void handleEffect(S28PacketEffect var1); /** diff --git a/src/main/java/net/minecraft/network/play/server/S21PacketChunkData.java b/src/main/java/net/minecraft/network/play/server/S21PacketChunkData.java index 245af46..fcff0c6 100644 --- a/src/main/java/net/minecraft/network/play/server/S21PacketChunkData.java +++ b/src/main/java/net/minecraft/network/play/server/S21PacketChunkData.java @@ -2,13 +2,20 @@ package net.minecraft.network.play.server; import java.io.IOException; import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; import com.google.common.collect.Lists; import net.hoosiertransfer.Alfheim.ILightingEngineProvider; +import net.lax1dude.eaglercraft.v1_8.netty.ByteBuf; +import net.lax1dude.eaglercraft.v1_8.netty.Unpooled; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; import net.minecraft.network.play.INetHandlerPlayClient; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockPos; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; @@ -44,114 +51,136 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage; public class S21PacketChunkData implements Packet { private int chunkX; private int chunkZ; - private S21PacketChunkData.Extracted extractedData; - private boolean field_149279_g; + private int availableSections; + private byte[] buffer; + private List field_189557_e; + private boolean loadChunk; public S21PacketChunkData() { } - public S21PacketChunkData(Chunk chunkIn, boolean parFlag, int parInt1) { - this.chunkX = chunkIn.xPosition; - this.chunkZ = chunkIn.zPosition; - this.field_149279_g = parFlag; - chunkIn.alfheim$getLightingEngine().processLightUpdates(); - this.extractedData = func_179756_a(chunkIn, parFlag, !chunkIn.getWorld().provider.getHasNoSky(), parInt1); - } + public S21PacketChunkData(Chunk p_i47124_1_, boolean loaded, int p_i47124_2_) { + this.chunkX = p_i47124_1_.xPosition; + this.chunkZ = p_i47124_1_.zPosition; + this.loadChunk = loaded; + boolean flag = !p_i47124_1_.getWorld().provider.getHasNoSky(); + this.buffer = new byte[this.func_189556_a(p_i47124_1_, flag, p_i47124_2_)]; + this.availableSections = this.func_189555_a(new PacketBuffer(this.getWriteBuffer()), p_i47124_1_, flag, + p_i47124_2_); + this.field_189557_e = Lists.newArrayList(); - /** - * + - * Reads the raw packet data from the data stream. - */ - public void readPacketData(PacketBuffer parPacketBuffer) throws IOException { - this.chunkX = parPacketBuffer.readInt(); - this.chunkZ = parPacketBuffer.readInt(); - this.field_149279_g = parPacketBuffer.readBoolean(); - this.extractedData = new S21PacketChunkData.Extracted(); - this.extractedData.dataSize = parPacketBuffer.readShort(); - this.extractedData.data = parPacketBuffer.readByteArray(); - } + for (Entry entry : p_i47124_1_.getTileEntityMap().entrySet()) { + BlockPos blockpos = (BlockPos) entry.getKey(); + TileEntity tileentity = (TileEntity) entry.getValue(); + int i = blockpos.getY() >> 4; - /** - * + - * Writes the raw packet data to the data stream. - */ - public void writePacketData(PacketBuffer parPacketBuffer) throws IOException { - parPacketBuffer.writeInt(this.chunkX); - parPacketBuffer.writeInt(this.chunkZ); - parPacketBuffer.writeBoolean(this.field_149279_g); - parPacketBuffer.writeShort((short) (this.extractedData.dataSize & '\uffff')); - parPacketBuffer.writeByteArray(this.extractedData.data); - } - - /** - * + - * Passes this Packet on to the NetHandler for processing. - */ - public void processPacket(INetHandlerPlayClient inethandlerplayclient) { - inethandlerplayclient.handleChunkData(this); - } - - public byte[] func_149272_d() { - return this.extractedData.data; - } - - protected static int func_180737_a(int parInt1, boolean parFlag, boolean parFlag2) { - int i = parInt1 * 2 * 16 * 16 * 16; - int j = parInt1 * 16 * 16 * 16 / 2; - int k = parFlag ? parInt1 * 16 * 16 * 16 / 2 : 0; - int l = parFlag2 ? 256 : 0; - return i + j + k + l; - } - - public static S21PacketChunkData.Extracted func_179756_a(Chunk parChunk, boolean parFlag, boolean parFlag2, - int parInt1) { - ExtendedBlockStorage[] aextendedblockstorage = parChunk.getBlockStorageArray(); - S21PacketChunkData.Extracted s21packetchunkdata$extracted = new S21PacketChunkData.Extracted(); - ArrayList arraylist = Lists.newArrayList(); - - for (int i = 0; i < aextendedblockstorage.length; ++i) { - ExtendedBlockStorage extendedblockstorage = aextendedblockstorage[i]; - if (extendedblockstorage != null && (!parFlag || !extendedblockstorage.isEmpty()) - && (parInt1 & 1 << i) != 0) { - s21packetchunkdata$extracted.dataSize |= 1 << i; - arraylist.add(extendedblockstorage); + if (this.doChunkLoad() || (p_i47124_2_ & 1 << i) != 0) { + NBTTagCompound nbttagcompound = tileentity.func_189517_E_(); + this.field_189557_e.add(nbttagcompound); } } + } - s21packetchunkdata$extracted.data = new byte[func_180737_a( - Integer.bitCount(s21packetchunkdata$extracted.dataSize), parFlag2, parFlag)]; + public void readPacketData(PacketBuffer buf) throws IOException { + this.chunkX = buf.readInt(); + this.chunkZ = buf.readInt(); + this.loadChunk = buf.readBoolean(); + this.availableSections = buf.readVarIntFromBuffer(); + int i = buf.readVarIntFromBuffer(); + + if (i > 2097152) { + throw new RuntimeException("Chunk Packet trying to allocate too much memory on read."); + } else { + this.buffer = new byte[i]; + buf.readBytes(this.buffer); + int j = buf.readVarIntFromBuffer(); + this.field_189557_e = Lists.newArrayList(); + + for (int k = 0; k < j; ++k) { + this.field_189557_e.add(buf.readNBTTagCompoundFromBuffer()); + } + } + } + + public void writePacketData(PacketBuffer buf) throws IOException { + buf.writeInt(this.chunkX); + buf.writeInt(this.chunkZ); + buf.writeBoolean(this.loadChunk); + buf.writeVarIntToBuffer(this.availableSections); + buf.writeVarIntToBuffer(this.buffer.length); + buf.writeBytes(this.buffer); + buf.writeVarIntToBuffer(this.field_189557_e.size()); + + for (NBTTagCompound nbttagcompound : this.field_189557_e) { + buf.writeNBTTagCompoundToBuffer(nbttagcompound); + } + } + + public void processPacket(INetHandlerPlayClient handler) { + handler.handleChunkData(this); + } + + public PacketBuffer getReadBuffer() { + return new PacketBuffer(Unpooled.buffer(this.buffer.length).writeBytes(this.buffer)); + } + + private ByteBuf getWriteBuffer() { + ByteBuf bytebuf = Unpooled.wrappedBuffer(this.buffer); + bytebuf.writerIndex(0); + return bytebuf; + } + + public int func_189555_a(PacketBuffer p_189555_1_, Chunk p_189555_2_, boolean p_189555_3_, int p_189555_4_) { + int i = 0; + ExtendedBlockStorage[] aextendedblockstorage = p_189555_2_.getBlockStorageArray(); int j = 0; - int l = arraylist.size(); - for (int k = 0; k < l; ++k) { - char[] achar = arraylist.get(k).getData(); - for (int m = 0; m < achar.length; ++m) { - char c0 = achar[m]; - s21packetchunkdata$extracted.data[j++] = (byte) (c0 & 255); - s21packetchunkdata$extracted.data[j++] = (byte) (c0 >> 8 & 255); + for (int k = aextendedblockstorage.length; j < k; ++j) { + ExtendedBlockStorage extendedblockstorage = aextendedblockstorage[j]; + + if (extendedblockstorage != Chunk.NULL_BLOCK_STORAGE + && (!this.doChunkLoad() || !extendedblockstorage.isEmpty()) && (p_189555_4_ & 1 << j) != 0) { + i |= 1 << j; + extendedblockstorage.getData().write(p_189555_1_); + p_189555_1_.writeBytes(extendedblockstorage.getBlocklightArray().getData()); + + if (p_189555_3_) { + p_189555_1_.writeBytes(extendedblockstorage.getSkylightArray().getData()); + } } } - for (int k = 0; k < l; ++k) { - j = func_179757_a(arraylist.get(k).getBlocklightArray().getData(), s21packetchunkdata$extracted.data, j); + if (this.doChunkLoad()) { + p_189555_1_.writeBytes(p_189555_2_.getBiomeArray()); } - if (parFlag2) { - for (int k = 0; k < l; ++k) { - j = func_179757_a(arraylist.get(k).getSkylightArray().getData(), s21packetchunkdata$extracted.data, j); - } - } - - if (parFlag) { - func_179757_a(parChunk.getBiomeArray(), s21packetchunkdata$extracted.data, j); - } - - return s21packetchunkdata$extracted; + return i; } - private static int func_179757_a(byte[] parArrayOfByte, byte[] parArrayOfByte2, int parInt1) { - System.arraycopy(parArrayOfByte, 0, parArrayOfByte2, parInt1, parArrayOfByte.length); - return parInt1 + parArrayOfByte.length; + protected int func_189556_a(Chunk p_189556_1_, boolean p_189556_2_, int p_189556_3_) { + int i = 0; + ExtendedBlockStorage[] aextendedblockstorage = p_189556_1_.getBlockStorageArray(); + int j = 0; + + for (int k = aextendedblockstorage.length; j < k; ++j) { + ExtendedBlockStorage extendedblockstorage = aextendedblockstorage[j]; + + if (extendedblockstorage != Chunk.NULL_BLOCK_STORAGE + && (!this.doChunkLoad() || !extendedblockstorage.isEmpty()) && (p_189556_3_ & 1 << j) != 0) { + i = i + extendedblockstorage.getData().getSerializedSize(); + i = i + extendedblockstorage.getBlocklightArray().getData().length; + + if (p_189556_2_) { + i += extendedblockstorage.getSkylightArray().getData().length; + } + } + } + + if (this.doChunkLoad()) { + i += p_189556_1_.getBiomeArray().length; + } + + return i; } public int getChunkX() { @@ -163,15 +192,14 @@ public class S21PacketChunkData implements Packet { } public int getExtractedSize() { - return this.extractedData.dataSize; + return this.availableSections; } - public boolean func_149274_i() { - return this.field_149279_g; + public boolean doChunkLoad() { + return this.loadChunk; } - public static class Extracted { - public byte[] data; - public int dataSize; + public List func_189554_f() { + return this.field_189557_e; } } \ No newline at end of file diff --git a/src/main/java/net/minecraft/network/play/server/S26PacketMapChunkBulk.java b/src/main/java/net/minecraft/network/play/server/S26PacketMapChunkBulk.java deleted file mode 100644 index 6ae4e15..0000000 --- a/src/main/java/net/minecraft/network/play/server/S26PacketMapChunkBulk.java +++ /dev/null @@ -1,140 +0,0 @@ -package net.minecraft.network.play.server; - -import java.io.IOException; -import java.util.List; - -import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; -import net.minecraft.network.play.INetHandlerPlayClient; -import net.minecraft.world.chunk.Chunk; - -/** - * + - * This portion of EaglercraftX contains deobfuscated Minecraft 1.8 source code. - * - * Minecraft 1.8.8 bytecode is (c) 2015 Mojang AB. "Do not distribute!" - * Mod Coder Pack v9.18 deobfuscation configs are (c) Copyright by the MCP Team - * - * EaglercraftX 1.8 patch files (c) 2022-2024 lax1dude, hoosiertransfer, - * ayunami2000. All Rights Reserved. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ -public class S26PacketMapChunkBulk implements Packet { - private int[] xPositions; - private int[] zPositions; - private S21PacketChunkData.Extracted[] chunksData; - private boolean isOverworld; - - public S26PacketMapChunkBulk() { - } - - public S26PacketMapChunkBulk(List chunks) { - int i = chunks.size(); - this.xPositions = new int[i]; - this.zPositions = new int[i]; - this.chunksData = new S21PacketChunkData.Extracted[i]; - this.isOverworld = !((Chunk) chunks.get(0)).getWorld().provider.getHasNoSky(); - - for (int j = 0; j < i; ++j) { - Chunk chunk = (Chunk) chunks.get(j); - S21PacketChunkData.Extracted s21packetchunkdata$extracted = S21PacketChunkData.func_179756_a(chunk, true, - this.isOverworld, '\uffff'); - this.xPositions[j] = chunk.xPosition; - this.zPositions[j] = chunk.zPosition; - this.chunksData[j] = s21packetchunkdata$extracted; - } - - } - - /** - * + - * Reads the raw packet data from the data stream. - */ - public void readPacketData(PacketBuffer parPacketBuffer) throws IOException { - this.isOverworld = parPacketBuffer.readBoolean(); - int i = parPacketBuffer.readVarIntFromBuffer(); - this.xPositions = new int[i]; - this.zPositions = new int[i]; - this.chunksData = new S21PacketChunkData.Extracted[i]; - - for (int j = 0; j < i; ++j) { - this.xPositions[j] = parPacketBuffer.readInt(); - this.zPositions[j] = parPacketBuffer.readInt(); - this.chunksData[j] = new S21PacketChunkData.Extracted(); - this.chunksData[j].dataSize = parPacketBuffer.readShort() & '\uffff'; - this.chunksData[j].data = new byte[S21PacketChunkData - .func_180737_a(Integer.bitCount(this.chunksData[j].dataSize), this.isOverworld, true)]; - } - - for (int k = 0; k < i; ++k) { - parPacketBuffer.readBytes(this.chunksData[k].data); - } - - } - - /** - * + - * Writes the raw packet data to the data stream. - */ - public void writePacketData(PacketBuffer parPacketBuffer) throws IOException { - parPacketBuffer.writeBoolean(this.isOverworld); - parPacketBuffer.writeVarIntToBuffer(this.chunksData.length); - - for (int i = 0; i < this.xPositions.length; ++i) { - parPacketBuffer.writeInt(this.xPositions[i]); - parPacketBuffer.writeInt(this.zPositions[i]); - parPacketBuffer.writeShort((short) (this.chunksData[i].dataSize & '\uffff')); - } - - for (int j = 0; j < this.xPositions.length; ++j) { - parPacketBuffer.writeBytes(this.chunksData[j].data); - } - - } - - /** - * + - * Passes this Packet on to the NetHandler for processing. - */ - public void processPacket(INetHandlerPlayClient inethandlerplayclient) { - inethandlerplayclient.handleMapChunkBulk(this); - } - - public int getChunkX(int parInt1) { - return this.xPositions[parInt1]; - } - - public int getChunkZ(int parInt1) { - return this.zPositions[parInt1]; - } - - public int getChunkCount() { - return this.xPositions.length; - } - - public byte[] getChunkBytes(int parInt1) { - return this.chunksData[parInt1].data; - } - - public int getChunkSize(int parInt1) { - return this.chunksData[parInt1].dataSize; - } -} \ No newline at end of file diff --git a/src/main/java/net/minecraft/tileentity/TileEntity.java b/src/main/java/net/minecraft/tileentity/TileEntity.java index ce50696..b1f9ea0 100644 --- a/src/main/java/net/minecraft/tileentity/TileEntity.java +++ b/src/main/java/net/minecraft/tileentity/TileEntity.java @@ -148,6 +148,12 @@ public abstract class TileEntity { } } + public NBTTagCompound func_189517_E_() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + this.writeToNBT(nbttagcompound); + return nbttagcompound; + } + /** * + * Creates a new entity and loads its data from the specified diff --git a/src/main/java/net/minecraft/util/BitArray.java b/src/main/java/net/minecraft/util/BitArray.java new file mode 100644 index 0000000..2ef74b9 --- /dev/null +++ b/src/main/java/net/minecraft/util/BitArray.java @@ -0,0 +1,82 @@ +package net.minecraft.util; + +import org.apache.commons.lang3.Validate; + +public class BitArray { + /** The long array that is used to store the data for this BitArray. */ + private final long[] longArray; + + /** Number of bits a single entry takes up */ + private final int bitsPerEntry; + + /** + * The maximum value for a single entry. This also asks as a bitmask for a + * single entry. + * For instance, if bitsPerEntry were 5, this value would be 31 (ie, + * {@code 0b00011111}). + */ + private final long maxEntryValue; + + /** + * Number of entries in this array (not the length of the long array that + * internally backs this array) + */ + private final int arraySize; + + public BitArray(int bitsPerEntryIn, int arraySizeIn) { + Validate.inclusiveBetween(1L, 32L, (long) bitsPerEntryIn); + this.arraySize = arraySizeIn; + this.bitsPerEntry = bitsPerEntryIn; + this.maxEntryValue = (1L << bitsPerEntryIn) - 1L; + this.longArray = new long[MathHelper.roundUp(arraySizeIn * bitsPerEntryIn, 64) / 64]; + } + + /** + * Sets the entry at the given location to the given value + */ + public void setAt(int index, int value) { + Validate.inclusiveBetween(0L, (long) (this.arraySize - 1), (long) index); + Validate.inclusiveBetween(0L, this.maxEntryValue, (long) value); + int i = index * this.bitsPerEntry; + int j = i / 64; + int k = ((index + 1) * this.bitsPerEntry - 1) / 64; + int l = i % 64; + this.longArray[j] = this.longArray[j] & ~(this.maxEntryValue << l) | ((long) value & this.maxEntryValue) << l; + + if (j != k) { + int i1 = 64 - l; + int j1 = this.bitsPerEntry - i1; + this.longArray[k] = this.longArray[k] >>> j1 << j1 | ((long) value & this.maxEntryValue) >> i1; + } + } + + /** + * Gets the entry at the given index + */ + public int getAt(int index) { + Validate.inclusiveBetween(0L, (long) (this.arraySize - 1), (long) index); + int i = index * this.bitsPerEntry; + int j = i / 64; + int k = ((index + 1) * this.bitsPerEntry - 1) / 64; + int l = i % 64; + + if (j == k) { + return (int) (this.longArray[j] >>> l & this.maxEntryValue); + } else { + int i1 = 64 - l; + return (int) ((this.longArray[j] >>> l | this.longArray[k] << i1) & this.maxEntryValue); + } + } + + /** + * Gets the long array that is used to store the data in this BitArray. This is + * useful for sending packet data. + */ + public long[] getBackingLongArray() { + return this.longArray; + } + + public int size() { + return this.arraySize; + } +} diff --git a/src/main/java/net/minecraft/util/IntIdentityHashBiMap.java b/src/main/java/net/minecraft/util/IntIdentityHashBiMap.java new file mode 100644 index 0000000..fe79f72 --- /dev/null +++ b/src/main/java/net/minecraft/util/IntIdentityHashBiMap.java @@ -0,0 +1,159 @@ +package net.minecraft.util; + +import com.google.common.base.Predicates; +import com.google.common.collect.Iterators; +import java.util.Arrays; +import java.util.Iterator; +import javax.annotation.Nullable; +import net.minecraft.util.MathHelper; + +public class IntIdentityHashBiMap implements IObjectIntIterable, Iterable { + private static final Object EMPTY = null; + private K[] keys; + private int[] values; + private K[] byId; + private int nextFreeIndex; + private int mapSize; + + public IntIdentityHashBiMap(int initialCapacity) { + initialCapacity = (int) ((float) initialCapacity / 0.8F); + this.keys = (K[]) (new Object[initialCapacity]); + this.values = new int[initialCapacity]; + this.byId = (K[]) (new Object[initialCapacity]); + } + + public int getId(K p_186815_1_) { + return this.getValue(this.getIndex(p_186815_1_, this.hashObject(p_186815_1_))); + } + + @Nullable + public K get(int idIn) { + return (K) (idIn >= 0 && idIn < this.byId.length ? this.byId[idIn] : null); + } + + private int getValue(int p_186805_1_) { + return p_186805_1_ == -1 ? -1 : this.values[p_186805_1_]; + } + + /** + * Adds the given object while expanding this map + */ + public int add(K objectIn) { + int i = this.nextId(); + this.put(objectIn, i); + return i; + } + + private int nextId() { + while (this.nextFreeIndex < this.byId.length && this.byId[this.nextFreeIndex] != null) { + ++this.nextFreeIndex; + } + + return this.nextFreeIndex; + } + + /** + * Rehashes the map to the new capacity + */ + private void grow(int capacity) { + K[] ak = this.keys; + int[] aint = this.values; + this.keys = (K[]) (new Object[capacity]); + this.values = new int[capacity]; + this.byId = (K[]) (new Object[capacity]); + this.nextFreeIndex = 0; + this.mapSize = 0; + + for (int i = 0; i < ak.length; ++i) { + if (ak[i] != null) { + this.put(ak[i], aint[i]); + } + } + } + + /** + * Puts the provided object value with the integer key. + */ + public void put(K objectIn, int intKey) { + int i = Math.max(intKey, this.mapSize + 1); + + if ((float) i >= (float) this.keys.length * 0.8F) { + int j; + + for (j = this.keys.length << 1; j < intKey; j <<= 1) { + ; + } + + this.grow(j); + } + + int k = this.findEmpty(this.hashObject(objectIn)); + this.keys[k] = objectIn; + this.values[k] = intKey; + this.byId[intKey] = objectIn; + ++this.mapSize; + + if (intKey == this.nextFreeIndex) { + ++this.nextFreeIndex; + } + } + + private int hashObject(K obectIn) { + return (MathHelper.getHash(System.identityHashCode(obectIn)) & Integer.MAX_VALUE) % this.keys.length; + } + + private int getIndex(K objectIn, int p_186816_2_) { + for (int i = p_186816_2_; i < this.keys.length; ++i) { + if (this.keys[i] == objectIn) { + return i; + } + + if (this.keys[i] == EMPTY) { + return -1; + } + } + + for (int j = 0; j < p_186816_2_; ++j) { + if (this.keys[j] == objectIn) { + return j; + } + + if (this.keys[j] == EMPTY) { + return -1; + } + } + + return -1; + } + + private int findEmpty(int p_186806_1_) { + for (int i = p_186806_1_; i < this.keys.length; ++i) { + if (this.keys[i] == EMPTY) { + return i; + } + } + + for (int j = 0; j < p_186806_1_; ++j) { + if (this.keys[j] == EMPTY) { + return j; + } + } + + throw new RuntimeException("Overflowed :("); + } + + public Iterator iterator() { + return Iterators.filter(Iterators.forArray(this.byId), Predicates.notNull()); + } + + public void clear() { + Arrays.fill(this.keys, (Object) null); + Arrays.fill(this.byId, (Object) null); + this.nextFreeIndex = 0; + this.mapSize = 0; + } + + public int size() { + return this.mapSize; + } +} diff --git a/src/main/java/net/minecraft/util/MathHelper.java b/src/main/java/net/minecraft/util/MathHelper.java index 9c32ec4..9be3462 100644 --- a/src/main/java/net/minecraft/util/MathHelper.java +++ b/src/main/java/net/minecraft/util/MathHelper.java @@ -84,6 +84,37 @@ public class MathHelper { return y; } + public static int getHash(int p_188208_0_) { + p_188208_0_ = p_188208_0_ ^ p_188208_0_ >>> 16; + p_188208_0_ = p_188208_0_ * -2048144789; + p_188208_0_ = p_188208_0_ ^ p_188208_0_ >>> 13; + p_188208_0_ = p_188208_0_ * -1028477387; + p_188208_0_ = p_188208_0_ ^ p_188208_0_ >>> 16; + return p_188208_0_; + } + + /** + * Rounds the first parameter up to the next interval of the second parameter. + * + * For instance, {@code roundUp(1, 4)} returns 4; {@code roundUp(0, 4)} returns + * 0; and {@code roundUp(4, 4)} returns + * 4. + */ + public static int roundUp(int number, int interval) { + if (interval == 0) { + return 0; + } else if (number == 0) { + return interval; + } else { + if (number < 0) { + interval *= -1; + } + + int i = number % interval; + return i == 0 ? number : number + interval - i; + } + } + /** * + * Returns the greatest integer less than or equal to the float @@ -334,7 +365,7 @@ public class MathHelper { * If the input value is not a power-of-two, then subtract 1 * from the return value. */ - private static int calculateLogBaseTwoDeBruijn(int value) { + public static int calculateLogBaseTwoDeBruijn(int value) { value = isPowerOfTwo(value) ? value : roundUpToPowerOfTwo(value); return multiplyDeBruijnBitPosition[(int) ((long) value * 125613361L >> 27) & 31]; } diff --git a/src/main/java/net/minecraft/util/ObjectIntIdentityMap.java b/src/main/java/net/minecraft/util/ObjectIntIdentityMap.java index 567ac8b..219d3c0 100644 --- a/src/main/java/net/minecraft/util/ObjectIntIdentityMap.java +++ b/src/main/java/net/minecraft/util/ObjectIntIdentityMap.java @@ -1,51 +1,31 @@ package net.minecraft.util; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; - import com.google.common.base.Predicates; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import javax.annotation.Nullable; -/** - * + - * This portion of EaglercraftX contains deobfuscated Minecraft 1.8 source code. - * - * Minecraft 1.8.8 bytecode is (c) 2015 Mojang AB. "Do not distribute!" - * Mod Coder Pack v9.18 deobfuscation configs are (c) Copyright by the MCP Team - * - * EaglercraftX 1.8 patch files (c) 2022-2024 lax1dude, hoosiertransfer, - * ayunami2000. All Rights Reserved. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ public class ObjectIntIdentityMap implements IObjectIntIterable { - private final IdentityHashMap identityMap = new IdentityHashMap(512); - private final List objectList = Lists.newArrayList(); + private final IdentityHashMap identityMap; + private final List objectList; + + public ObjectIntIdentityMap() { + this(512); + } + + public ObjectIntIdentityMap(int expectedSize) { + this.objectList = Lists.newArrayListWithExpectedSize(expectedSize); + this.identityMap = new IdentityHashMap(expectedSize); + } public void put(T key, int value) { this.identityMap.put(key, Integer.valueOf(value)); while (this.objectList.size() <= value) { - this.objectList.add((T) null); + this.objectList.add(null); } this.objectList.set(value, key); @@ -56,6 +36,7 @@ public class ObjectIntIdentityMap implements IObjectIntIterable { return integer == null ? -1 : integer.intValue(); } + @Nullable public final T getByValue(int value) { return (T) (value >= 0 && value < this.objectList.size() ? this.objectList.get(value) : null); } @@ -63,4 +44,8 @@ public class ObjectIntIdentityMap implements IObjectIntIterable { public Iterator iterator() { return Iterators.filter(this.objectList.iterator(), Predicates.notNull()); } -} \ No newline at end of file + + public int size() { + return this.identityMap.size(); + } +} diff --git a/src/main/java/net/minecraft/world/chunk/BlockStateContainer.java b/src/main/java/net/minecraft/world/chunk/BlockStateContainer.java new file mode 100644 index 0000000..4355262 --- /dev/null +++ b/src/main/java/net/minecraft/world/chunk/BlockStateContainer.java @@ -0,0 +1,136 @@ +package net.minecraft.world.chunk; + +import javax.annotation.Nullable; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.BitArray; +import net.minecraft.util.MathHelper; + +public class BlockStateContainer implements IBlockStatePaletteResizer { + private static final IBlockStatePalette REGISTRY_BASED_PALETTE = new BlockStatePaletteRegistry(); + protected static final IBlockState AIR_BLOCK_STATE = Blocks.air.getDefaultState(); + protected BitArray storage; + protected IBlockStatePalette palette; + private int bits = 0; + + public BlockStateContainer() { + this.setBits(4); + } + + private static int getIndex(int x, int y, int z) { + return y << 8 | z << 4 | x; + } + + private void setBits(int bitsIn) { + if (bitsIn != this.bits) { + this.bits = bitsIn; + + if (this.bits <= 4) { + this.bits = 4; + this.palette = new BlockStatePaletteLinear(this.bits, this); + } else if (this.bits <= 8) { + this.palette = new BlockStatePaletteHashMap(this.bits, this); + } else { + this.palette = REGISTRY_BASED_PALETTE; + this.bits = MathHelper.calculateLogBaseTwoDeBruijn(Block.BLOCK_STATE_IDS.size()); + } + + this.palette.idFor(AIR_BLOCK_STATE); + this.storage = new BitArray(this.bits, 4096); + } + } + + public int onResize(int p_186008_1_, IBlockState state) { + BitArray bitarray = this.storage; + IBlockStatePalette iblockstatepalette = this.palette; + this.setBits(p_186008_1_); + + for (int i = 0; i < bitarray.size(); ++i) { + IBlockState iblockstate = iblockstatepalette.getBlockState(bitarray.getAt(i)); + + if (iblockstate != null) { + this.set(i, iblockstate); + } + } + + return this.palette.idFor(state); + } + + public void set(int x, int y, int z, IBlockState state) { + this.set(getIndex(x, y, z), state); + } + + protected void set(int index, IBlockState state) { + int i = this.palette.idFor(state); + this.storage.setAt(index, i); + } + + public IBlockState get(int x, int y, int z) { + return this.get(getIndex(x, y, z)); + } + + protected IBlockState get(int index) { + IBlockState iblockstate = this.palette.getBlockState(this.storage.getAt(index)); + return iblockstate == null ? AIR_BLOCK_STATE : iblockstate; + } + + public void read(PacketBuffer buf) { + int i = buf.readByte(); + + if (this.bits != i) { + this.setBits(i); + } + + this.palette.read(buf); + buf.readLongArray(this.storage.getBackingLongArray()); + } + + public void write(PacketBuffer buf) { + buf.writeByte(this.bits); + this.palette.write(buf); + buf.writeLongArray(this.storage.getBackingLongArray()); + } + + @Nullable + public NibbleArray getDataForNBT(byte[] p_186017_1_, NibbleArray p_186017_2_) { + NibbleArray nibblearray = null; + + for (int i = 0; i < 4096; ++i) { + int j = Block.BLOCK_STATE_IDS.get(this.get(i)); + int k = i & 15; + int l = i >> 8 & 15; + int i1 = i >> 4 & 15; + + if ((j >> 12 & 15) != 0) { + if (nibblearray == null) { + nibblearray = new NibbleArray(); + } + + nibblearray.set(k, l, i1, j >> 12 & 15); + } + + p_186017_1_[i] = (byte) (j >> 4 & 255); + p_186017_2_.set(k, l, i1, j & 15); + } + + return nibblearray; + } + + public void setDataFromNBT(byte[] p_186019_1_, NibbleArray p_186019_2_, @Nullable NibbleArray p_186019_3_) { + for (int i = 0; i < 4096; ++i) { + int j = i & 15; + int k = i >> 8 & 15; + int l = i >> 4 & 15; + int i1 = p_186019_3_ == null ? 0 : p_186019_3_.get(j, k, l); + int j1 = i1 << 12 | (p_186019_1_[i] & 255) << 4 | p_186019_2_.get(j, k, l); + this.set(i, (IBlockState) Block.BLOCK_STATE_IDS.getByValue(j1)); + } + } + + public int getSerializedSize() { + return 1 + this.palette.getSerializedState() + PacketBuffer.getVarIntSize(this.storage.size()) + + this.storage.getBackingLongArray().length * 8; + } +} diff --git a/src/main/java/net/minecraft/world/chunk/BlockStatePaletteHashMap.java b/src/main/java/net/minecraft/world/chunk/BlockStatePaletteHashMap.java new file mode 100644 index 0000000..ff6cf08 --- /dev/null +++ b/src/main/java/net/minecraft/world/chunk/BlockStatePaletteHashMap.java @@ -0,0 +1,70 @@ +package net.minecraft.world.chunk; + +import javax.annotation.Nullable; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.IntIdentityHashBiMap; + +public class BlockStatePaletteHashMap implements IBlockStatePalette { + private final IntIdentityHashBiMap statePaletteMap; + private final IBlockStatePaletteResizer paletteResizer; + private final int bits; + + public BlockStatePaletteHashMap(int bitsIn, IBlockStatePaletteResizer p_i47089_2_) { + this.bits = bitsIn; + this.paletteResizer = p_i47089_2_; + this.statePaletteMap = new IntIdentityHashBiMap(1 << bitsIn); + } + + public int idFor(IBlockState state) { + int i = this.statePaletteMap.getId(state); + + if (i == -1) { + i = this.statePaletteMap.add(state); + + if (i >= 1 << this.bits) { + i = this.paletteResizer.onResize(this.bits + 1, state); + } + } + + return i; + } + + @Nullable + + /** + * Gets the block state by the palette id. + */ + public IBlockState getBlockState(int indexKey) { + return (IBlockState) this.statePaletteMap.get(indexKey); + } + + public void read(PacketBuffer buf) { + this.statePaletteMap.clear(); + int i = buf.readVarIntFromBuffer(); + + for (int j = 0; j < i; ++j) { + this.statePaletteMap.add(Block.BLOCK_STATE_IDS.getByValue(buf.readVarIntFromBuffer())); + } + } + + public void write(PacketBuffer buf) { + int i = this.statePaletteMap.size(); + buf.writeVarIntToBuffer(i); + + for (int j = 0; j < i; ++j) { + buf.writeVarIntToBuffer(Block.BLOCK_STATE_IDS.get(this.statePaletteMap.get(j))); + } + } + + public int getSerializedState() { + int i = PacketBuffer.getVarIntSize(this.statePaletteMap.size()); + + for (int j = 0; j < this.statePaletteMap.size(); ++j) { + i += PacketBuffer.getVarIntSize(Block.BLOCK_STATE_IDS.get(this.statePaletteMap.get(j))); + } + + return i; + } +} diff --git a/src/main/java/net/minecraft/world/chunk/BlockStatePaletteLinear.java b/src/main/java/net/minecraft/world/chunk/BlockStatePaletteLinear.java new file mode 100644 index 0000000..6fcf2ea --- /dev/null +++ b/src/main/java/net/minecraft/world/chunk/BlockStatePaletteLinear.java @@ -0,0 +1,72 @@ +package net.minecraft.world.chunk; + +import javax.annotation.Nullable; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.network.PacketBuffer; + +public class BlockStatePaletteLinear implements IBlockStatePalette { + private final IBlockState[] states; + private final IBlockStatePaletteResizer resizeHandler; + private final int bits; + private int arraySize; + + public BlockStatePaletteLinear(int p_i47088_1_, IBlockStatePaletteResizer p_i47088_2_) { + this.states = new IBlockState[1 << p_i47088_1_]; + this.bits = p_i47088_1_; + this.resizeHandler = p_i47088_2_; + } + + public int idFor(IBlockState state) { + for (int i = 0; i < this.arraySize; ++i) { + if (this.states[i] == state) { + return i; + } + } + + int j = this.arraySize; + + if (j < this.states.length) { + this.states[j] = state; + ++this.arraySize; + return j; + } else { + return this.resizeHandler.onResize(this.bits + 1, state); + } + } + + @Nullable + + /** + * Gets the block state by the palette id. + */ + public IBlockState getBlockState(int indexKey) { + return indexKey >= 0 && indexKey < this.arraySize ? this.states[indexKey] : null; + } + + public void read(PacketBuffer buf) { + this.arraySize = buf.readVarIntFromBuffer(); + + for (int i = 0; i < this.arraySize; ++i) { + this.states[i] = (IBlockState) Block.BLOCK_STATE_IDS.getByValue(buf.readVarIntFromBuffer()); + } + } + + public void write(PacketBuffer buf) { + buf.writeVarIntToBuffer(this.arraySize); + + for (int i = 0; i < this.arraySize; ++i) { + buf.writeVarIntToBuffer(Block.BLOCK_STATE_IDS.get(this.states[i])); + } + } + + public int getSerializedState() { + int i = PacketBuffer.getVarIntSize(this.arraySize); + + for (int j = 0; j < this.arraySize; ++j) { + i += PacketBuffer.getVarIntSize(Block.BLOCK_STATE_IDS.get(this.states[j])); + } + + return i; + } +} diff --git a/src/main/java/net/minecraft/world/chunk/BlockStatePaletteRegistry.java b/src/main/java/net/minecraft/world/chunk/BlockStatePaletteRegistry.java new file mode 100644 index 0000000..54d9777 --- /dev/null +++ b/src/main/java/net/minecraft/world/chunk/BlockStatePaletteRegistry.java @@ -0,0 +1,33 @@ +package net.minecraft.world.chunk; + +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.network.PacketBuffer; + +public class BlockStatePaletteRegistry implements IBlockStatePalette { + public int idFor(IBlockState state) { + int i = Block.BLOCK_STATE_IDS.get(state); + return i == -1 ? 0 : i; + } + + /** + * Gets the block state by the palette id. + */ + public IBlockState getBlockState(int indexKey) { + IBlockState iblockstate = (IBlockState) Block.BLOCK_STATE_IDS.getByValue(indexKey); + return iblockstate == null ? Blocks.air.getDefaultState() : iblockstate; + } + + public void read(PacketBuffer buf) { + buf.readVarIntFromBuffer(); + } + + public void write(PacketBuffer buf) { + buf.writeVarIntToBuffer(0); + } + + public int getSerializedState() { + return PacketBuffer.getVarIntSize(0); + } +} diff --git a/src/main/java/net/minecraft/world/chunk/Chunk.java b/src/main/java/net/minecraft/world/chunk/Chunk.java index e6016ce..58a22ca 100644 --- a/src/main/java/net/minecraft/world/chunk/Chunk.java +++ b/src/main/java/net/minecraft/world/chunk/Chunk.java @@ -26,6 +26,7 @@ import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; import net.minecraft.entity.Entity; import net.minecraft.init.Blocks; +import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; @@ -1074,53 +1075,38 @@ public class Chunk { * + * Initialize this chunk with new binary data. */ - public void fillChunk(byte[] parArrayOfByte, int parInt1, boolean parFlag) { - int i = 0; + public void fillChunk(PacketBuffer buf, int p_186033_2_, boolean p_186033_3_) { boolean flag = !this.worldObj.provider.getHasNoSky(); + for (int i = 0; i < this.storageArrays.length; ++i) { + ExtendedBlockStorage extendedblockstorage = this.storageArrays[i]; + + if ((p_186033_2_ & 1 << i) == 0) { + if (p_186033_3_ && extendedblockstorage != NULL_BLOCK_STORAGE) { + this.storageArrays[i] = NULL_BLOCK_STORAGE; + } + } else { + if (extendedblockstorage == NULL_BLOCK_STORAGE) { + extendedblockstorage = new ExtendedBlockStorage(i << 4, flag); + this.storageArrays[i] = extendedblockstorage; + } + + extendedblockstorage.getData().read(buf); + buf.readBytes(extendedblockstorage.getBlocklightArray().getData()); + + if (flag) { + buf.readBytes(extendedblockstorage.getSkylightArray().getData()); + } + } + } + + if (p_186033_3_) { + buf.readBytes(this.blockBiomeArray); + } + for (int j = 0; j < this.storageArrays.length; ++j) { - if ((parInt1 & 1 << j) != 0) { - if (this.storageArrays[j] == null) { - this.storageArrays[j] = new ExtendedBlockStorage(j << 4, flag); - } - - char[] achar = this.storageArrays[j].getData(); - - for (int k = 0; k < achar.length; ++k) { - achar[k] = (char) ((parArrayOfByte[i + 1] & 255) << 8 | parArrayOfByte[i] & 255); - i += 2; - } - } else if (parFlag && this.storageArrays[j] != null) { - this.storageArrays[j] = null; - } - } - - for (int l = 0; l < this.storageArrays.length; ++l) { - if ((parInt1 & 1 << l) != 0 && this.storageArrays[l] != null) { - NibbleArray nibblearray = this.storageArrays[l].getBlocklightArray(); - System.arraycopy(parArrayOfByte, i, nibblearray.getData(), 0, nibblearray.getData().length); - i += nibblearray.getData().length; - } - } - - if (flag) { - for (int i1 = 0; i1 < this.storageArrays.length; ++i1) { - if ((parInt1 & 1 << i1) != 0 && this.storageArrays[i1] != null) { - NibbleArray nibblearray1 = this.storageArrays[i1].getSkylightArray(); - System.arraycopy(parArrayOfByte, i, nibblearray1.getData(), 0, nibblearray1.getData().length); - i += nibblearray1.getData().length; - } - } - } - - if (parFlag) { - System.arraycopy(parArrayOfByte, i, this.blockBiomeArray, 0, this.blockBiomeArray.length); - int k1 = i + this.blockBiomeArray.length; - } - - for (int j1 = 0; j1 < this.storageArrays.length; ++j1) { - if (this.storageArrays[j1] != null && (parInt1 & 1 << j1) != 0) { - this.storageArrays[j1].removeInvalidBlocks(); + if (this.storageArrays[j] != NULL_BLOCK_STORAGE && (p_186033_2_ & 1 << j) != 0) { + this.storageArrays[j].removeInvalidBlocks(); } } @@ -1131,7 +1117,6 @@ public class Chunk { for (TileEntity tileentity : this.chunkTileEntityMap.values()) { tileentity.updateContainingBlockInfo(); } - } public BiomeGenBase getBiome(BlockPos pos, WorldChunkManager chunkManager) { diff --git a/src/main/java/net/minecraft/world/chunk/IBlockStatePalette.java b/src/main/java/net/minecraft/world/chunk/IBlockStatePalette.java new file mode 100644 index 0000000..f644b08 --- /dev/null +++ b/src/main/java/net/minecraft/world/chunk/IBlockStatePalette.java @@ -0,0 +1,22 @@ +package net.minecraft.world.chunk; + +import javax.annotation.Nullable; +import net.minecraft.block.state.IBlockState; +import net.minecraft.network.PacketBuffer; + +public interface IBlockStatePalette { + int idFor(IBlockState state); + + @Nullable + + /** + * Gets the block state by the palette id. + */ + IBlockState getBlockState(int indexKey); + + void read(PacketBuffer buf); + + void write(PacketBuffer buf); + + int getSerializedState(); +} diff --git a/src/main/java/net/minecraft/world/chunk/IBlockStatePaletteResizer.java b/src/main/java/net/minecraft/world/chunk/IBlockStatePaletteResizer.java new file mode 100644 index 0000000..6f3a08f --- /dev/null +++ b/src/main/java/net/minecraft/world/chunk/IBlockStatePaletteResizer.java @@ -0,0 +1,7 @@ +package net.minecraft.world.chunk; + +import net.minecraft.block.state.IBlockState; + +interface IBlockStatePaletteResizer { + int onResize(int p_186008_1_, IBlockState state); +} diff --git a/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java b/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java index 0e70e8b..18d4dc0 100644 --- a/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java +++ b/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java @@ -88,9 +88,6 @@ public abstract class AnvilChunkLoader implements IChunkLoader { */ protected void writeChunkToNBT(Chunk chunkIn, World worldIn, NBTTagCompound parNBTTagCompound) { alfheim$writeNeighborLightChecksToNBT(chunkIn, parNBTTagCompound); - parNBTTagCompound.setBoolean("LightPopulated", chunkIn.alfheim$isLightInitialized()); - - parNBTTagCompound.setByte("V", (byte) 1); parNBTTagCompound.setInteger("xPos", chunkIn.xPosition); parNBTTagCompound.setInteger("zPos", chunkIn.zPosition); parNBTTagCompound.setLong("LastUpdate", worldIn.getTotalWorldTime()); @@ -103,37 +100,21 @@ public abstract class AnvilChunkLoader implements IChunkLoader { boolean flag = !worldIn.provider.getHasNoSky(); for (ExtendedBlockStorage extendedblockstorage : aextendedblockstorage) { - if (extendedblockstorage != null) { + if (extendedblockstorage != Chunk.NULL_BLOCK_STORAGE) { NBTTagCompound nbttagcompound = new NBTTagCompound(); nbttagcompound.setByte("Y", (byte) (extendedblockstorage.getYLocation() >> 4 & 255)); - byte[] abyte = new byte[extendedblockstorage.getData().length]; + byte[] abyte = new byte[4096]; NibbleArray nibblearray = new NibbleArray(); - NibbleArray nibblearray1 = null; - - for (int i = 0; i < extendedblockstorage.getData().length; ++i) { - char c0 = extendedblockstorage.getData()[i]; - int j = i & 15; - int k = i >> 8 & 15; - int l = i >> 4 & 15; - if (c0 >> 12 != 0) { - if (nibblearray1 == null) { - nibblearray1 = new NibbleArray(); - } - - nibblearray1.set(j, k, l, c0 >> 12); - } - - abyte[i] = (byte) (c0 >> 4 & 255); - nibblearray.set(j, k, l, c0 & 15); - } - + NibbleArray nibblearray1 = extendedblockstorage.getData().getDataForNBT(abyte, nibblearray); nbttagcompound.setByteArray("Blocks", abyte); nbttagcompound.setByteArray("Data", nibblearray.getData()); + if (nibblearray1 != null) { nbttagcompound.setByteArray("Add", nibblearray1.getData()); } nbttagcompound.setByteArray("BlockLight", extendedblockstorage.getBlocklightArray().getData()); + if (flag) { nbttagcompound.setByteArray("SkyLight", extendedblockstorage.getSkylightArray().getData()); } else { @@ -209,37 +190,28 @@ public abstract class AnvilChunkLoader implements IChunkLoader { chunk.setLightPopulated(parNBTTagCompound.getBoolean("LightPopulated")); chunk.setInhabitedTime(parNBTTagCompound.getLong("InhabitedTime")); NBTTagList nbttaglist = parNBTTagCompound.getTagList("Sections", 10); - byte b0 = 16; - ExtendedBlockStorage[] aextendedblockstorage = new ExtendedBlockStorage[b0]; + int k = 16; + ExtendedBlockStorage[] aextendedblockstorage = new ExtendedBlockStorage[k]; boolean flag = !worldIn.provider.getHasNoSky(); - for (int k = 0; k < nbttaglist.tagCount(); ++k) { - NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(k); - byte b1 = nbttagcompound.getByte("Y"); - ExtendedBlockStorage extendedblockstorage = new ExtendedBlockStorage(b1 << 4, flag); + for (int l = 0; l < nbttaglist.tagCount(); ++l) { + NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(l); + int i1 = nbttagcompound.getByte("Y"); + ExtendedBlockStorage extendedblockstorage = new ExtendedBlockStorage(i1 << 4, flag); byte[] abyte = nbttagcompound.getByteArray("Blocks"); NibbleArray nibblearray = new NibbleArray(nbttagcompound.getByteArray("Data")); NibbleArray nibblearray1 = nbttagcompound.hasKey("Add", 7) ? new NibbleArray(nbttagcompound.getByteArray("Add")) : null; - char[] achar = new char[abyte.length]; - - for (int l = 0; l < achar.length; ++l) { - int i1 = l & 15; - int j1 = l >> 8 & 15; - int k1 = l >> 4 & 15; - int l1 = nibblearray1 != null ? nibblearray1.get(i1, j1, k1) : 0; - achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.get(i1, j1, k1)); - } - - extendedblockstorage.setData(achar); + extendedblockstorage.getData().setDataFromNBT(abyte, nibblearray, nibblearray1); extendedblockstorage.setBlocklightArray(new NibbleArray(nbttagcompound.getByteArray("BlockLight"))); + if (flag) { extendedblockstorage.setSkylightArray(new NibbleArray(nbttagcompound.getByteArray("SkyLight"))); } extendedblockstorage.removeInvalidBlocks(); - aextendedblockstorage[b1] = extendedblockstorage; + aextendedblockstorage[i1] = extendedblockstorage; } chunk.setStorageArrays(aextendedblockstorage); diff --git a/src/main/java/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java b/src/main/java/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java index 406dac6..8bde1bd 100644 --- a/src/main/java/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java +++ b/src/main/java/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java @@ -3,6 +3,7 @@ package net.minecraft.world.chunk.storage; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; +import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.NibbleArray; /** @@ -38,13 +39,13 @@ public class ExtendedBlockStorage { private int yBase; private int blockRefCount; private int tickRefCount; - private char[] data; + private BlockStateContainer data; private NibbleArray blocklightArray; private NibbleArray skylightArray; public ExtendedBlockStorage(int y, boolean storeSkylight) { this.yBase = y; - this.data = new char[4096]; + this.data = new BlockStateContainer(); this.blocklightArray = new NibbleArray(); if (storeSkylight) { this.skylightArray = new NibbleArray(); @@ -53,8 +54,7 @@ public class ExtendedBlockStorage { } public IBlockState get(int x, int y, int z) { - IBlockState iblockstate = (IBlockState) Block.BLOCK_STATE_IDS.getByValue(this.data[y << 8 | z << 4 | x]); - return iblockstate != null ? iblockstate : Blocks.air.getDefaultState(); + return this.data.get(x, y, z); } public void set(int x, int y, int z, IBlockState state) { @@ -75,7 +75,7 @@ public class ExtendedBlockStorage { } } - this.data[y << 8 | z << 4 | x] = (char) Block.BLOCK_STATE_IDS.get(state); + this.data.set(x, y, z, state); } /** @@ -182,14 +182,10 @@ public class ExtendedBlockStorage { } - public char[] getData() { + public BlockStateContainer getData() { return this.data; } - public void setData(char[] dataArray) { - this.data = dataArray; - } - /** * + * Returns the NibbleArray instance containing Block-light data.