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.List;
009    import java.util.zip.DataFormatException;
010    import java.util.zip.Deflater;
011    import java.util.zip.Inflater;
012    
013    public class Packet56MapChunks extends Packet
014    {
015        private int[] field_73589_c;
016        private int[] field_73586_d;
017        public int[] field_73590_a;
018        public int[] field_73588_b;
019        private byte[] field_73587_e;
020        private byte[][] field_73584_f;
021        private int field_73585_g;
022        private static byte[] field_73591_h = new byte[0];
023    
024        public Packet56MapChunks() {}
025    
026        public Packet56MapChunks(List par1List)
027        {
028            int var2 = par1List.size();
029            this.field_73589_c = new int[var2];
030            this.field_73586_d = new int[var2];
031            this.field_73590_a = new int[var2];
032            this.field_73588_b = new int[var2];
033            this.field_73584_f = new byte[var2][];
034            int var3 = 0;
035    
036            for (int var4 = 0; var4 < var2; ++var4)
037            {
038                Chunk var5 = (Chunk)par1List.get(var4);
039                Packet51MapChunkData var6 = Packet51MapChunk.func_73594_a(var5, true, 65535);
040    
041                if (field_73591_h.length < var3 + var6.field_74582_a.length)
042                {
043                    byte[] var7 = new byte[var3 + var6.field_74582_a.length];
044                    System.arraycopy(field_73591_h, 0, var7, 0, field_73591_h.length);
045                    field_73591_h = var7;
046                }
047    
048                System.arraycopy(var6.field_74582_a, 0, field_73591_h, var3, var6.field_74582_a.length);
049                var3 += var6.field_74582_a.length;
050                this.field_73589_c[var4] = var5.xPosition;
051                this.field_73586_d[var4] = var5.zPosition;
052                this.field_73590_a[var4] = var6.field_74580_b;
053                this.field_73588_b[var4] = var6.field_74581_c;
054                this.field_73584_f[var4] = var6.field_74582_a;
055            }
056    
057            Deflater var11 = new Deflater(-1);
058    
059            try
060            {
061                var11.setInput(field_73591_h, 0, var3);
062                var11.finish();
063                this.field_73587_e = new byte[var3];
064                this.field_73585_g = var11.deflate(this.field_73587_e);
065            }
066            finally
067            {
068                var11.end();
069            }
070        }
071    
072        /**
073         * Abstract. Reads the raw packet data from the data stream.
074         */
075        public void readPacketData(DataInputStream par1DataInputStream) throws IOException
076        {
077            short var2 = par1DataInputStream.readShort();
078            this.field_73585_g = par1DataInputStream.readInt();
079            this.field_73589_c = new int[var2];
080            this.field_73586_d = new int[var2];
081            this.field_73590_a = new int[var2];
082            this.field_73588_b = new int[var2];
083            this.field_73584_f = new byte[var2][];
084    
085            if (field_73591_h.length < this.field_73585_g)
086            {
087                field_73591_h = new byte[this.field_73585_g];
088            }
089    
090            par1DataInputStream.readFully(field_73591_h, 0, this.field_73585_g);
091            byte[] var3 = new byte[196864 * var2];
092            Inflater var4 = new Inflater();
093            var4.setInput(field_73591_h, 0, this.field_73585_g);
094    
095            try
096            {
097                var4.inflate(var3);
098            }
099            catch (DataFormatException var11)
100            {
101                throw new IOException("Bad compressed data format");
102            }
103            finally
104            {
105                var4.end();
106            }
107    
108            int var5 = 0;
109    
110            for (int var6 = 0; var6 < var2; ++var6)
111            {
112                this.field_73589_c[var6] = par1DataInputStream.readInt();
113                this.field_73586_d[var6] = par1DataInputStream.readInt();
114                this.field_73590_a[var6] = par1DataInputStream.readShort();
115                this.field_73588_b[var6] = par1DataInputStream.readShort();
116                int var7 = 0;
117                int var8;
118    
119                for (var8 = 0; var8 < 16; ++var8)
120                {
121                    var7 += this.field_73590_a[var6] >> var8 & 1;
122                }
123    
124                int msb = 0; //BugFix: MC does not read the MSB array from the packet properly, causing issues for servers that use blocks > 256
125                for (int x = 0; x < 16; x++)
126                {
127                    msb += (field_73588_b[var6] >> x) & 1;
128                }
129    
130                var8 = 2048 * 5 * var7 + (2048 * msb) + 256;
131                this.field_73584_f[var6] = new byte[var8];
132                System.arraycopy(var3, var5, this.field_73584_f[var6], 0, var8);
133                var5 += var8;
134            }
135        }
136    
137        /**
138         * Abstract. Writes the raw packet data to the data stream.
139         */
140        public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException
141        {
142            par1DataOutputStream.writeShort(this.field_73589_c.length);
143            par1DataOutputStream.writeInt(this.field_73585_g);
144            par1DataOutputStream.write(this.field_73587_e, 0, this.field_73585_g);
145    
146            for (int var2 = 0; var2 < this.field_73589_c.length; ++var2)
147            {
148                par1DataOutputStream.writeInt(this.field_73589_c[var2]);
149                par1DataOutputStream.writeInt(this.field_73586_d[var2]);
150                par1DataOutputStream.writeShort((short)(this.field_73590_a[var2] & 65535));
151                par1DataOutputStream.writeShort((short)(this.field_73588_b[var2] & 65535));
152            }
153        }
154    
155        /**
156         * Passes this Packet on to the NetHandler for processing.
157         */
158        public void processPacket(NetHandler par1NetHandler)
159        {
160            par1NetHandler.handleMapChunks(this);
161        }
162    
163        /**
164         * Abstract. Return the size of the packet (not counting the header).
165         */
166        public int getPacketSize()
167        {
168            return 6 + this.field_73585_g + 12 * this.func_73581_d();
169        }
170    
171        @SideOnly(Side.CLIENT)
172        public int func_73582_a(int par1)
173        {
174            return this.field_73589_c[par1];
175        }
176    
177        @SideOnly(Side.CLIENT)
178        public int func_73580_b(int par1)
179        {
180            return this.field_73586_d[par1];
181        }
182    
183        public int func_73581_d()
184        {
185            return this.field_73589_c.length;
186        }
187    
188        @SideOnly(Side.CLIENT)
189        public byte[] func_73583_c(int par1)
190        {
191            return this.field_73584_f[par1];
192        }
193    }