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