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.zip.DataFormatException; 009 import java.util.zip.Deflater; 010 import java.util.zip.Inflater; 011 012 public class Packet51MapChunk extends Packet 013 { 014 /** The x-position of the transmitted chunk, in chunk coordinates. */ 015 public int xCh; 016 017 /** The z-position of the transmitted chunk, in chunk coordinates. */ 018 public int zCh; 019 020 /** 021 * The y-position of the lowest chunk Section in the transmitted chunk, in chunk coordinates. 022 */ 023 public int yChMin; 024 025 /** 026 * The y-position of the highest chunk Section in the transmitted chunk, in chunk coordinates. 027 */ 028 public int yChMax; 029 030 /** The transmitted chunk data, decompressed. */ 031 private byte[] chunkData; 032 private byte[] field_73596_g; 033 034 /** 035 * Whether to initialize the Chunk before applying the effect of the Packet51MapChunk. 036 */ 037 public boolean includeInitialize; 038 039 /** The length of the compressed chunk data byte array. */ 040 private int tempLength; 041 042 /** A temporary storage for the compressed chunk data byte array. */ 043 private static byte[] temp = new byte[196864]; 044 045 public Packet51MapChunk() 046 { 047 this.isChunkDataPacket = true; 048 } 049 050 public Packet51MapChunk(Chunk par1Chunk, boolean par2, int par3) 051 { 052 this.isChunkDataPacket = true; 053 this.xCh = par1Chunk.xPosition; 054 this.zCh = par1Chunk.zPosition; 055 this.includeInitialize = par2; 056 Packet51MapChunkData var4 = func_73594_a(par1Chunk, par2, par3); 057 Deflater var5 = new Deflater(-1); 058 this.yChMax = var4.field_74581_c; 059 this.yChMin = var4.field_74580_b; 060 061 try 062 { 063 this.field_73596_g = var4.field_74582_a; 064 var5.setInput(var4.field_74582_a, 0, var4.field_74582_a.length); 065 var5.finish(); 066 this.chunkData = new byte[var4.field_74582_a.length]; 067 this.tempLength = var5.deflate(this.chunkData); 068 } 069 finally 070 { 071 var5.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 this.xCh = par1DataInputStream.readInt(); 081 this.zCh = par1DataInputStream.readInt(); 082 this.includeInitialize = par1DataInputStream.readBoolean(); 083 this.yChMin = par1DataInputStream.readShort(); 084 this.yChMax = par1DataInputStream.readShort(); 085 this.tempLength = par1DataInputStream.readInt(); 086 087 if (temp.length < this.tempLength) 088 { 089 temp = new byte[this.tempLength]; 090 } 091 092 par1DataInputStream.readFully(temp, 0, this.tempLength); 093 int var2 = 0; 094 int var3; 095 096 for (var3 = 0; var3 < 16; ++var3) 097 { 098 var2 += this.yChMin >> var3 & 1; 099 } 100 101 var3 = 12288 * var2; 102 103 int msb = 0; //BugFix: MC does not read the MSB array from the packet properly, causing issues for servers that use blocks > 256 104 for (int x = 0; x < 16; x++) 105 { 106 msb += (yChMax >> x) & 1; 107 } 108 var3 += (2048 * msb); 109 110 if (this.includeInitialize) 111 { 112 var3 += 256; 113 } 114 115 this.field_73596_g = new byte[var3]; 116 Inflater var4 = new Inflater(); 117 var4.setInput(temp, 0, this.tempLength); 118 119 try 120 { 121 var4.inflate(this.field_73596_g); 122 } 123 catch (DataFormatException var9) 124 { 125 throw new IOException("Bad compressed data format"); 126 } 127 finally 128 { 129 var4.end(); 130 } 131 } 132 133 /** 134 * Abstract. Writes the raw packet data to the data stream. 135 */ 136 public void writePacketData(DataOutputStream par1DataOutputStream) throws IOException 137 { 138 par1DataOutputStream.writeInt(this.xCh); 139 par1DataOutputStream.writeInt(this.zCh); 140 par1DataOutputStream.writeBoolean(this.includeInitialize); 141 par1DataOutputStream.writeShort((short)(this.yChMin & 65535)); 142 par1DataOutputStream.writeShort((short)(this.yChMax & 65535)); 143 par1DataOutputStream.writeInt(this.tempLength); 144 par1DataOutputStream.write(this.chunkData, 0, this.tempLength); 145 } 146 147 /** 148 * Passes this Packet on to the NetHandler for processing. 149 */ 150 public void processPacket(NetHandler par1NetHandler) 151 { 152 par1NetHandler.handleMapChunk(this); 153 } 154 155 /** 156 * Abstract. Return the size of the packet (not counting the header). 157 */ 158 public int getPacketSize() 159 { 160 return 17 + this.tempLength; 161 } 162 163 public static Packet51MapChunkData func_73594_a(Chunk par0Chunk, boolean par1, int par2) 164 { 165 int var3 = 0; 166 ExtendedBlockStorage[] var4 = par0Chunk.getBlockStorageArray(); 167 int var5 = 0; 168 Packet51MapChunkData var6 = new Packet51MapChunkData(); 169 byte[] var7 = temp; 170 171 if (par1) 172 { 173 par0Chunk.deferRender = true; 174 } 175 176 int var8; 177 178 for (var8 = 0; var8 < var4.length; ++var8) 179 { 180 if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) 181 { 182 var6.field_74580_b |= 1 << var8; 183 184 if (var4[var8].getBlockMSBArray() != null) 185 { 186 var6.field_74581_c |= 1 << var8; 187 ++var5; 188 } 189 } 190 } 191 192 for (var8 = 0; var8 < var4.length; ++var8) 193 { 194 if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) 195 { 196 byte[] var9 = var4[var8].getBlockLSBArray(); 197 System.arraycopy(var9, 0, var7, var3, var9.length); 198 var3 += var9.length; 199 } 200 } 201 202 NibbleArray var10; 203 204 for (var8 = 0; var8 < var4.length; ++var8) 205 { 206 if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) 207 { 208 var10 = var4[var8].getMetadataArray(); 209 System.arraycopy(var10.data, 0, var7, var3, var10.data.length); 210 var3 += var10.data.length; 211 } 212 } 213 214 for (var8 = 0; var8 < var4.length; ++var8) 215 { 216 if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) 217 { 218 var10 = var4[var8].getBlocklightArray(); 219 System.arraycopy(var10.data, 0, var7, var3, var10.data.length); 220 var3 += var10.data.length; 221 } 222 } 223 224 for (var8 = 0; var8 < var4.length; ++var8) 225 { 226 if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && (par2 & 1 << var8) != 0) 227 { 228 var10 = var4[var8].getSkylightArray(); 229 System.arraycopy(var10.data, 0, var7, var3, var10.data.length); 230 var3 += var10.data.length; 231 } 232 } 233 234 if (var5 > 0) 235 { 236 for (var8 = 0; var8 < var4.length; ++var8) 237 { 238 if (var4[var8] != null && (!par1 || !var4[var8].isEmpty()) && var4[var8].getBlockMSBArray() != null && (par2 & 1 << var8) != 0) 239 { 240 var10 = var4[var8].getBlockMSBArray(); 241 System.arraycopy(var10.data, 0, var7, var3, var10.data.length); 242 var3 += var10.data.length; 243 } 244 } 245 } 246 247 if (par1) 248 { 249 byte[] var11 = par0Chunk.getBiomeArray(); 250 System.arraycopy(var11, 0, var7, var3, var11.length); 251 var3 += var11.length; 252 } 253 254 var6.field_74582_a = new byte[var3]; 255 System.arraycopy(var7, 0, var6.field_74582_a, 0, var3); 256 return var6; 257 } 258 259 @SideOnly(Side.CLIENT) 260 public byte[] func_73593_d() 261 { 262 return this.field_73596_g; 263 } 264 }