    001    package net.minecraft.network.packet;
    002
    003    import cpw.mods.fml.relauncher.Side;
    004    import cpw.mods.fml.relauncher.SideOnly;
    005    import java.io.DataInputStream;
    006    import java.io.DataOutputStream;
    007    import java.io.IOException;
    008    import java.util.List;
    009    import java.util.concurrent.Semaphore;
    010    import java.util.zip.DataFormatException;
    011    import java.util.zip.Deflater;
    012    import java.util.zip.Inflater;
    013    import net.minecraft.world.chunk.Chunk;
    014
    015    public class Packet56MapChunks extends Packet
    016    {
    017        private int[] field_73589_c;
    018        private int[] field_73586_d;
    019        public int[] field_73590_a;
    020        public int[] field_73588_b;
    021        private byte[] field_73587_e;
    022        private byte[][] field_73584_f;
    023        private int field_73585_g;
    024        private boolean field_92024_h;
    025        private static byte[] field_73591_h = new byte[0];
    026        private int maxLen = 0;
    027
    028        private Semaphore deflateGate;
    029
    030        public Packet56MapChunks() {}
    031
    032        public Packet56MapChunks(List par1List)
    033        {
    034            int var2 = par1List.size();
    035            this.field_73589_c = new int[var2];
    036            this.field_73586_d = new int[var2];
    037            this.field_73590_a = new int[var2];
    038            this.field_73588_b = new int[var2];
    039            this.field_73584_f = new byte[var2][];
    040            this.field_92024_h = !par1List.isEmpty() && !((Chunk)par1List.get(0)).worldObj.provider.hasNoSky;
    041            int var3 = 0;
    042
    043            for (int var4 = 0; var4 < var2; ++var4)
    044            {
    045                Chunk var5 = (Chunk)par1List.get(var4);
    046                Packet51MapChunkData var6 = Packet51MapChunk.getMapChunkData(var5, true, 65535);
    047                var3 += var6.field_74582_a.length;
    048                this.field_73589_c[var4] = var5.xPosition;
    049                this.field_73586_d[var4] = var5.zPosition;
    050                this.field_73590_a[var4] = var6.field_74580_b;
    051                this.field_73588_b[var4] = var6.field_74581_c;
    052                this.field_73584_f[var4] = var6.field_74582_a;
    053                deflateGate = new Semaphore(1);
    054            }
    055
    056            maxLen = var3;
    057        }
    058
    059        private void deflate()
    060        {
    061            byte[] data = new byte[maxLen];
    062            int offset = 0;
    063            for (int x = 0; x < field_73584_f.length; x++)
    064            {
    065                System.arraycopy(field_73584_f[x], 0, data, offset, field_73584_f[x].length);
    066                offset += field_73584_f[x].length;
    067            }
    068
    069            Deflater var11 = new Deflater(-1);
    070
    071            try
    072            {
    073                var11.setInput(data, 0, maxLen);
    074                var11.finish();
    075                byte[] deflated = new byte[maxLen];
    076                this.field_73585_g = var11.deflate(deflated);
    077                this.field_73587_e = deflated;
    078            }
    079            finally
    080            {
    081                var11.end();
    082            }
    083        }
    084
    085        /**
    086         * Abstract. Reads the raw packet data from the data stream.
    087         */
    088        public void readPacketData(DataInputStream par1DataInputStream) throws IOException
    089        {
    090            short var2 = par1DataInputStream.readShort();
    091            this.field_73585_g = par1DataInputStream.readInt();
    092            this.field_92024_h = par1DataInputStream.readBoolean();
    093            this.field_73589_c = new int[var2];
    094            this.field_73586_d = new int[var2];
    095            this.field_73590_a = new int[var2];
    096            this.field_73588_b = new int[var2];
    097            this.field_73584_f = new byte[var2][];
    098
    099            if (field_73591_h.length < this.field_73585_g)
    100            {
    101                field_73591_h = new byte[this.field_73585_g];
    102            }
    103
    104            par1DataInputStream.readFully(field_73591_h, 0, this.field_73585_g);
    105            byte[] var3 = new byte[196864 * var2];
    106            Inflater var4 = new Inflater();
    107            var4.setInput(field_73591_h, 0, this.field_73585_g);
    108
    109            try
    110            {
    111                var4.inflate(var3);
    112            }
    113            catch (DataFormatException var12)
    114            {
    115                throw new IOException("Bad compressed data format");
    116            }
    117            finally
    118            {
    119                var4.end();
    120            }
    121
    122            int var5 = 0;
    123
    124            for (int var6 = 0; var6 < var2; ++var6)
    125            {
    126                this.field_73589_c[var6] = par1DataInputStream.readInt();
    127                this.field_73586_d[var6] = par1DataInputStream.readInt();
    128                this.field_73590_a[var6] = par1DataInputStream.readShort();
    129                this.field_73588_b[var6] = par1DataInputStream.readShort();
    130                int var7 = 0;
    131                int var8 = 0;
    132                int var9;
    133
    134                for (var9 = 0; var9 < 16; ++var9)
    135                {
    136                    var7 += this.field_73590_a[var6] >> var9 & 1;
    137                    var8 += this.field_73588_b[var6] >> var9 & 1;
    138                }
    139
    140                var9 = 2048 * 4 * var7 + 256;
    141                var9 += 2048 * var8;
    142
    143                if (this.field_92024_h)
    144                {
    145                    var9 += 2048 * var7;
    146                }
    147
    148                this.field_73584_f[var6] = new byte[var9];
    149                System.arraycopy(var3, var5, this.field_73584_f[var6], 0, var9);
    150                var5 += var9;
    151            }
    152        }
    153
    154        /**
    155         * Abstract. Writes the raw packet data to the data stream.
    156         */
    157        public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
    158        {
    159            if (field_73587_e == null)
    160            {
    161                deflateGate.acquireUninterruptibly();
    162                if (field_73587_e == null)
    163                {
    164                    deflate();
    165                }
    166                deflateGate.release();
    167            }
    168
    169            par1DataOutputStream.writeShort(this.field_73589_c.length);
    170            par1DataOutputStream.writeInt(this.field_73585_g);
    171            par1DataOutputStream.writeBoolean(this.field_92024_h);
    172            par1DataOutputStream.write(this.field_73587_e, 0, this.field_73585_g);
    173
    174            for (int var2 = 0; var2 < this.field_73589_c.length; ++var2)
    175            {
    176                par1DataOutputStream.writeInt(this.field_73589_c[var2]);
    177                par1DataOutputStream.writeInt(this.field_73586_d[var2]);
    178                par1DataOutputStream.writeShort((short)(this.field_73590_a[var2] & 65535));
    179                par1DataOutputStream.writeShort((short)(this.field_73588_b[var2] & 65535));
    180            }
    181        }
    182
    183        /**
    184         * Passes this Packet on to the NetHandler for processing.
    185         */
    186        public void processPacket(NetHandler par1NetHandler)
    187        {
    188            par1NetHandler.handleMapChunks(this);
    189        }
    190
    191        /**
    192         * Abstract. Return the size of the packet (not counting the header).
    193         */
    194        public int getPacketSize()
    195        {
    196            return 6 + this.field_73585_g + 12 * this.func_73581_d();
    197        }
    198
    199        @SideOnly(Side.CLIENT)
    200        public int func_73582_a(int par1)
    201        {
    202            return this.field_73589_c[par1];
    203        }
    204
    205        @SideOnly(Side.CLIENT)
    206        public int func_73580_b(int par1)
    207        {
    208            return this.field_73586_d[par1];
    209        }
    210
    211        public int func_73581_d()
    212        {
    213            return this.field_73589_c.length;
    214        }
    215
    216        @SideOnly(Side.CLIENT)
    217        public byte[] func_73583_c(int par1)
    218        {
    219            return this.field_73584_f[par1];
    220        }
    221    }