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