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