    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.io.DataInputStream;
    006    import java.io.DataOutputStream;
    007    import java.io.IOException;
    008    import java.util.zip.DataFormatException;
    009    import java.util.zip.Deflater;
    010    import java.util.zip.Inflater;
    011
    012    public class Packet51MapChunk extends Packet
    013    {
    014        /** The x-position of the transmitted chunk, in chunk coordinates. */
    015        public int xCh;
    016
    017        /** The z-position of the transmitted chunk, in chunk coordinates. */
    018        public int zCh;
    019
    020        /**
    021         * The y-position of the lowest chunk Section in the transmitted chunk, in chunk coordinates.
    022         */
    023        public int yChMin;
    024
    025        /**
    026         * The y-position of the highest chunk Section in the transmitted chunk, in chunk coordinates.
    027         */
    028        public int yChMax;
    029
    030        /** The transmitted chunk data, decompressed. */
    031        private byte[] chunkData;
    032        private byte[] field_73596_g;
    033
    034        /**
    035         * Whether to initialize the Chunk before applying the effect of the Packet51MapChunk.
    036         */
    037        public boolean includeInitialize;
    038
    039        /** The length of the compressed chunk data byte array. */
    040        private int tempLength;
    041
    042        /** A temporary storage for the compressed chunk data byte array. */
    043        private static byte[] temp = new byte[196864];
    044
    045        public Packet51MapChunk()
    046        {
    047            this.isChunkDataPacket = true;
    048        }
    049
    050        public Packet51MapChunk(Chunk par1Chunk, boolean par2, int par3)
    051        {
    052            this.isChunkDataPacket = true;
    053            this.xCh = par1Chunk.xPosition;
    054            this.zCh = par1Chunk.zPosition;
    055            this.includeInitialize = par2;
    056            Packet51MapChunkData var4 = getMapChunkData(par1Chunk, par2, par3);
    057            Deflater var5 = new Deflater(-1);
    058            this.yChMax = var4.field_74581_c;
    059            this.yChMin = var4.field_74580_b;
    060
    061            try
    062            {
    063                this.field_73596_g = var4.field_74582_a;
    064                var5.setInput(var4.field_74582_a, 0, var4.field_74582_a.length);
    065                var5.finish();
    066                this.chunkData = new byte[var4.field_74582_a.length];
    067                this.tempLength = var5.deflate(this.chunkData);
    068            }
    069            finally
    070            {
    071                var5.end();
    072            }
    073        }
    074
    075        /**
    076         * Abstract. Reads the raw packet data from the data stream.
    077         */
    078        public void readPacketData(DataInputStream par1DataInputStream) throws IOException
    079        {
    080            this.xCh = par1DataInputStream.readInt();
    081            this.zCh = par1DataInputStream.readInt();
    082            this.includeInitialize = par1DataInputStream.readBoolean();
    083            this.yChMin = par1DataInputStream.readShort();
    084            this.yChMax = par1DataInputStream.readShort();
    085            this.tempLength = par1DataInputStream.readInt();
    086
    087            if (temp.length < this.tempLength)
    088            {
    089                temp = new byte[this.tempLength];
    090            }
    091
    092            par1DataInputStream.readFully(temp, 0, this.tempLength);
    093            int var2 = 0;
    094            int var3;
    095
    096            for (var3 = 0; var3 < 16; ++var3)
    097            {
    098                var2 += this.yChMin >> var3 & 1;
    099            }
    100
    101            var3 = 12288 * var2;
    102
    103            int msb = 0; //BugFix: MC does not read the MSB array from the packet properly, causing issues for servers that use blocks > 256
    104            for (int x = 0; x < 16; x++)
    105            {
    106                msb += (yChMax >> x) & 1;
    107            }
    108            var3 += (2048 * msb);
    109
    110            if (this.includeInitialize)
    111            {
    112                var3 += 256;
    113            }
    114
    115            this.field_73596_g = new byte[var3];
    116            Inflater var4 = new Inflater();
    117            var4.setInput(temp, 0, this.tempLength);
    118
    119            try
    120            {
    121                var4.inflate(this.field_73596_g);
    122            }
    123            catch (DataFormatException var9)
    124            {
    125                throw new IOException("Bad compressed data format");
    126            }
    127            finally
    128            {
    129                var4.end();
    130            }
    131        }
    132
    133        /**
    134         * Abstract. Writes the raw packet data to the data stream.
    135         */
    136        public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
    137        {
    138            par1DataOutputStream.writeInt(this.xCh);
    139            par1DataOutputStream.writeInt(this.zCh);
    140            par1DataOutputStream.writeBoolean(this.includeInitialize);
    141            par1DataOutputStream.writeShort((short)(this.yChMin & 65535));
    142            par1DataOutputStream.writeShort((short)(this.yChMax & 65535));
    143            par1DataOutputStream.writeInt(this.tempLength);
    144            par1DataOutputStream.write(this.chunkData, 0, this.tempLength);
    145        }
    146
    147        /**
    148         * Passes this Packet on to the NetHandler for processing.
    149         */
    150        public void processPacket(NetHandler par1NetHandler)
    151        {
    152            par1NetHandler.handleMapChunk(this);
    153        }
    154
    155        /**
    156         * Abstract. Return the size of the packet (not counting the header).
    157         */
    158        public int getPacketSize()
    159        {
    160            return 17 + this.tempLength;
    161        }
    162
    163        public static Packet51MapChunkData getMapChunkData(Chunk par0Chunk, boolean par1, int par2)
    164        {
    165            int var3 = 0;
    166            ExtendedBlockStorage[] var4 = par0Chunk.getBlockStorageArray();
    167            int var5 = 0;
    168            Packet51MapChunkData var6 = new Packet51MapChunkData();
    169            byte[] var7 = temp;
    170
    171            if (par1)
    172            {
    173                par0Chunk.deferRender = true;
    174            }
    175
    176            int var8;
    177
    178            for (var8 = 0; var8 < var4.length; ++var8)
    179            {
    180                if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0)
    181                {
    182                    var6.field_74580_b |= 1 << var8;
    183
    184                    if (var4[var8].getBlockMSBArray() != null)
    185                    {
    186                        var6.field_74581_c |= 1 << var8;
    187                        ++var5;
    188                    }
    189                }
    190            }
    191
    192            for (var8 = 0; var8 < var4.length; ++var8)
    193            {
    194                if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0)
    195                {
    196                    byte[] var9 = var4[var8].getBlockLSBArray();
    197                    System.arraycopy(var9, 0, var7, var3, var9.length);
    198                    var3 += var9.length;
    199                }
    200            }
    201
    202            NibbleArray var10;
    203
    204            for (var8 = 0; var8 < var4.length; ++var8)
    205            {
    206                if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0)
    207                {
    208                    var10 = var4[var8].getMetadataArray();
    209                    System.arraycopy(var10.data, 0, var7, var3, var10.data.length);
    210                    var3 += var10.data.length;
    211                }
    212            }
    213
    214            for (var8 = 0; var8 < var4.length; ++var8)
    215            {
    216                if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0)
    217                {
    218                    var10 = var4[var8].getBlocklightArray();
    219                    System.arraycopy(var10.data, 0, var7, var3, var10.data.length);
    220                    var3 += var10.data.length;
    221                }
    222            }
    223
    224            for (var8 = 0; var8 < var4.length; ++var8)
    225            {
    226                if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0)
    227                {
    228                    var10 = var4[var8].getSkylightArray();
    229                    System.arraycopy(var10.data, 0, var7, var3, var10.data.length);
    230                    var3 += var10.data.length;
    231                }
    232            }
    233
    234            if (var5 > 0)
    235            {
    236                for (var8 = 0; var8 < var4.length; ++var8)
    237                {
    238                    if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && var4[var8].getBlockMSBArray() != null && (par2 & 1 << var8) != 0)
    239                    {
    240                        var10 = var4[var8].getBlockMSBArray();
    241                        System.arraycopy(var10.data, 0, var7, var3, var10.data.length);
    242                        var3 += var10.data.length;
    243                    }
    244                }
    245            }
    246
    247            if (par1)
    248            {
    249                byte[] var11 = par0Chunk.getBiomeArray();
    250                System.arraycopy(var11, 0, var7, var3, var11.length);
    251                var3 += var11.length;
    252            }
    253
    254            var6.field_74582_a = new byte[var3];
    255            System.arraycopy(var7, 0, var6.field_74582_a, 0, var3);
    256            return var6;
    257        }
    258
    259        @SideOnly(Side.CLIENT)
    260        public byte[] func_73593_d()
    261        {
    262            return this.field_73596_g;
    263        }
    264    }