001 package net.minecraft.src; 002 003 import java.io.DataInputStream; 004 import java.io.DataOutputStream; 005 import java.io.EOFException; 006 import java.io.IOException; 007 import java.util.HashMap; 008 import java.util.HashSet; 009 import java.util.Map; 010 import java.util.Set; 011 012 public abstract class Packet 013 { 014 /** Maps packet id to packet class */ 015 public static IntHashMap packetIdToClassMap = new IntHashMap(); 016 017 /** Maps packet class to packet id */ 018 private static Map packetClassToIdMap = new HashMap(); 019 020 /** List of the client's packet IDs. */ 021 private static Set clientPacketIdList = new HashSet(); 022 023 /** List of the server's packet IDs. */ 024 private static Set serverPacketIdList = new HashSet(); 025 026 /** the system time in milliseconds when this packet was created. */ 027 public final long creationTimeMillis = System.currentTimeMillis(); 028 public static long receivedID; 029 public static long receivedSize; 030 031 /** Assumed to be sequential by the profiler. */ 032 public static long sentID; 033 public static long sentSize; 034 035 /** 036 * Only true for Packet51MapChunk, Packet52MultiBlockChange, Packet53BlockChange and Packet59ComplexEntity. Used to 037 * separate them into a different send queue. 038 */ 039 public boolean isChunkDataPacket = false; 040 041 /** 042 * Adds a two way mapping between the packet ID and packet class. 043 */ 044 static void addIdClassMapping(int par0, boolean par1, boolean par2, Class par3Class) 045 { 046 if (packetIdToClassMap.containsItem(par0)) 047 { 048 throw new IllegalArgumentException("Duplicate packet id:" + par0); 049 } 050 else if (packetClassToIdMap.containsKey(par3Class)) 051 { 052 throw new IllegalArgumentException("Duplicate packet class:" + par3Class); 053 } 054 else 055 { 056 packetIdToClassMap.addKey(par0, par3Class); 057 packetClassToIdMap.put(par3Class, Integer.valueOf(par0)); 058 059 if (par1) 060 { 061 clientPacketIdList.add(Integer.valueOf(par0)); 062 } 063 064 if (par2) 065 { 066 serverPacketIdList.add(Integer.valueOf(par0)); 067 } 068 } 069 } 070 071 /** 072 * Returns a new instance of the specified Packet class. 073 */ 074 public static Packet getNewPacket(int par0) 075 { 076 try 077 { 078 Class var1 = (Class)packetIdToClassMap.lookup(par0); 079 return var1 == null ? null : (Packet)var1.newInstance(); 080 } 081 catch (Exception var2) 082 { 083 var2.printStackTrace(); 084 System.out.println("Skipping packet with id " + par0); 085 return null; 086 } 087 } 088 089 /** 090 * Writes a byte array to the DataOutputStream 091 */ 092 public static void writeByteArray(DataOutputStream par0DataOutputStream, byte[] par1ArrayOfByte) throws IOException 093 { 094 par0DataOutputStream.writeShort(par1ArrayOfByte.length); 095 par0DataOutputStream.write(par1ArrayOfByte); 096 } 097 098 /** 099 * the first short in the stream indicates the number of bytes to read 100 */ 101 public static byte[] readBytesFromStream(DataInputStream par0DataInputStream) throws IOException 102 { 103 short var1 = par0DataInputStream.readShort(); 104 105 if (var1 < 0) 106 { 107 throw new IOException("Key was smaller than nothing! Weird key!"); 108 } 109 else 110 { 111 byte[] var2 = new byte[var1]; 112 par0DataInputStream.read(var2); 113 return var2; 114 } 115 } 116 117 /** 118 * Returns the ID of this packet. 119 */ 120 public final int getPacketId() 121 { 122 return ((Integer)packetClassToIdMap.get(this.getClass())).intValue(); 123 } 124 125 /** 126 * Read a packet, prefixed by its ID, from the data stream. 127 */ 128 public static Packet readPacket(DataInputStream par0DataInputStream, boolean par1) throws IOException 129 { 130 boolean var2 = false; 131 Packet var3 = null; 132 int var6; 133 134 try 135 { 136 var6 = par0DataInputStream.read(); 137 138 if (var6 == -1) 139 { 140 return null; 141 } 142 143 if (par1 && !serverPacketIdList.contains(Integer.valueOf(var6)) || !par1 && !clientPacketIdList.contains(Integer.valueOf(var6))) 144 { 145 throw new IOException("Bad packet id " + var6); 146 } 147 148 var3 = getNewPacket(var6); 149 150 if (var3 == null) 151 { 152 throw new IOException("Bad packet id " + var6); 153 } 154 155 var3.readPacketData(par0DataInputStream); 156 ++receivedID; 157 receivedSize += (long)var3.getPacketSize(); 158 } 159 catch (EOFException var5) 160 { 161 System.out.println("Reached end of stream"); 162 return null; 163 } 164 165 PacketCount.countPacket(var6, (long)var3.getPacketSize()); 166 ++receivedID; 167 receivedSize += (long)var3.getPacketSize(); 168 return var3; 169 } 170 171 /** 172 * Writes a packet, prefixed by its ID, to the data stream. 173 */ 174 public static void writePacket(Packet par0Packet, DataOutputStream par1DataOutputStream) throws IOException 175 { 176 par1DataOutputStream.write(par0Packet.getPacketId()); 177 par0Packet.writePacketData(par1DataOutputStream); 178 ++sentID; 179 sentSize += (long)par0Packet.getPacketSize(); 180 } 181 182 /** 183 * Writes a String to the DataOutputStream 184 */ 185 public static void writeString(String par0Str, DataOutputStream par1DataOutputStream) throws IOException 186 { 187 if (par0Str.length() > 32767) 188 { 189 throw new IOException("String too big"); 190 } 191 else 192 { 193 par1DataOutputStream.writeShort(par0Str.length()); 194 par1DataOutputStream.writeChars(par0Str); 195 } 196 } 197 198 /** 199 * Reads a string from a packet 200 */ 201 public static String readString(DataInputStream par0DataInputStream, int par1) throws IOException 202 { 203 short var2 = par0DataInputStream.readShort(); 204 205 if (var2 > par1) 206 { 207 throw new IOException("Received string length longer than maximum allowed (" + var2 + " > " + par1 + ")"); 208 } 209 else if (var2 < 0) 210 { 211 throw new IOException("Received string length is less than zero! Weird string!"); 212 } 213 else 214 { 215 StringBuilder var3 = new StringBuilder(); 216 217 for (int var4 = 0; var4 < var2; ++var4) 218 { 219 var3.append(par0DataInputStream.readChar()); 220 } 221 222 return var3.toString(); 223 } 224 } 225 226 /** 227 * Abstract. Reads the raw packet data from the data stream. 228 */ 229 public abstract void readPacketData(DataInputStream var1) throws IOException; 230 231 /** 232 * Abstract. Writes the raw packet data to the data stream. 233 */ 234 public abstract void writePacketData(DataOutputStream var1) throws IOException; 235 236 /** 237 * Passes this Packet on to the NetHandler for processing. 238 */ 239 public abstract void processPacket(NetHandler var1); 240 241 /** 242 * Abstract. Return the size of the packet (not counting the header). 243 */ 244 public abstract int getPacketSize(); 245 246 /** 247 * only false for the abstract Packet class, all real packets return true 248 */ 249 public boolean isRealPacket() 250 { 251 return false; 252 } 253 254 /** 255 * eg return packet30entity.entityId == entityId; WARNING : will throw if you compare a packet to a different packet 256 * class 257 */ 258 public boolean containsSameEntityIDAs(Packet par1Packet) 259 { 260 return false; 261 } 262 263 /** 264 * if this returns false, processPacket is deffered for processReadPackets to handle 265 */ 266 public boolean isWritePacket() 267 { 268 return false; 269 } 270 271 public String toString() 272 { 273 String var1 = this.getClass().getSimpleName(); 274 return var1; 275 } 276 277 /** 278 * Reads a ItemStack from the InputStream 279 */ 280 public static ItemStack readItemStack(DataInputStream par0DataInputStream) throws IOException 281 { 282 ItemStack var1 = null; 283 short var2 = par0DataInputStream.readShort(); 284 285 if (var2 >= 0) 286 { 287 byte var3 = par0DataInputStream.readByte(); 288 short var4 = par0DataInputStream.readShort(); 289 var1 = new ItemStack(var2, var3, var4); 290 var1.stackTagCompound = readNBTTagCompound(par0DataInputStream); 291 } 292 293 return var1; 294 } 295 296 /** 297 * Writes the ItemStack's ID (short), then size (byte), then damage. (short) 298 */ 299 public static void writeItemStack(ItemStack par0ItemStack, DataOutputStream par1DataOutputStream) throws IOException 300 { 301 if (par0ItemStack == null) 302 { 303 par1DataOutputStream.writeShort(-1); 304 } 305 else 306 { 307 par1DataOutputStream.writeShort(par0ItemStack.itemID); 308 par1DataOutputStream.writeByte(par0ItemStack.stackSize); 309 par1DataOutputStream.writeShort(par0ItemStack.getItemDamage()); 310 NBTTagCompound var2 = null; 311 312 if (par0ItemStack.getItem().isDamageable() || par0ItemStack.getItem().getShareTag()) 313 { 314 var2 = par0ItemStack.stackTagCompound; 315 } 316 317 writeNBTTagCompound(var2, par1DataOutputStream); 318 } 319 } 320 321 /** 322 * Reads a compressed NBTTagCompound from the InputStream 323 */ 324 public static NBTTagCompound readNBTTagCompound(DataInputStream par0DataInputStream) throws IOException 325 { 326 short var1 = par0DataInputStream.readShort(); 327 328 if (var1 < 0) 329 { 330 return null; 331 } 332 else 333 { 334 byte[] var2 = new byte[var1]; 335 par0DataInputStream.readFully(var2); 336 return CompressedStreamTools.decompress(var2); 337 } 338 } 339 340 /** 341 * Writes a compressed NBTTagCompound to the OutputStream 342 */ 343 protected static void writeNBTTagCompound(NBTTagCompound par0NBTTagCompound, DataOutputStream par1DataOutputStream) throws IOException 344 { 345 if (par0NBTTagCompound == null) 346 { 347 par1DataOutputStream.writeShort(-1); 348 } 349 else 350 { 351 byte[] var2 = CompressedStreamTools.compress(par0NBTTagCompound); 352 par1DataOutputStream.writeShort((short)var2.length); 353 par1DataOutputStream.write(var2); 354 } 355 } 356 357 static 358 { 359 addIdClassMapping(0, true, true, Packet0KeepAlive.class); 360 addIdClassMapping(1, true, true, Packet1Login.class); 361 addIdClassMapping(2, false, true, Packet2ClientProtocol.class); 362 addIdClassMapping(3, true, true, Packet3Chat.class); 363 addIdClassMapping(4, true, false, Packet4UpdateTime.class); 364 addIdClassMapping(5, true, false, Packet5PlayerInventory.class); 365 addIdClassMapping(6, true, false, Packet6SpawnPosition.class); 366 addIdClassMapping(7, false, true, Packet7UseEntity.class); 367 addIdClassMapping(8, true, false, Packet8UpdateHealth.class); 368 addIdClassMapping(9, true, true, Packet9Respawn.class); 369 addIdClassMapping(10, true, true, Packet10Flying.class); 370 addIdClassMapping(11, true, true, Packet11PlayerPosition.class); 371 addIdClassMapping(12, true, true, Packet12PlayerLook.class); 372 addIdClassMapping(13, true, true, Packet13PlayerLookMove.class); 373 addIdClassMapping(14, false, true, Packet14BlockDig.class); 374 addIdClassMapping(15, false, true, Packet15Place.class); 375 addIdClassMapping(16, false, true, Packet16BlockItemSwitch.class); 376 addIdClassMapping(17, true, false, Packet17Sleep.class); 377 addIdClassMapping(18, true, true, Packet18Animation.class); 378 addIdClassMapping(19, false, true, Packet19EntityAction.class); 379 addIdClassMapping(20, true, false, Packet20NamedEntitySpawn.class); 380 addIdClassMapping(21, true, false, Packet21PickupSpawn.class); 381 addIdClassMapping(22, true, false, Packet22Collect.class); 382 addIdClassMapping(23, true, false, Packet23VehicleSpawn.class); 383 addIdClassMapping(24, true, false, Packet24MobSpawn.class); 384 addIdClassMapping(25, true, false, Packet25EntityPainting.class); 385 addIdClassMapping(26, true, false, Packet26EntityExpOrb.class); 386 addIdClassMapping(28, true, false, Packet28EntityVelocity.class); 387 addIdClassMapping(29, true, false, Packet29DestroyEntity.class); 388 addIdClassMapping(30, true, false, Packet30Entity.class); 389 addIdClassMapping(31, true, false, Packet31RelEntityMove.class); 390 addIdClassMapping(32, true, false, Packet32EntityLook.class); 391 addIdClassMapping(33, true, false, Packet33RelEntityMoveLook.class); 392 addIdClassMapping(34, true, false, Packet34EntityTeleport.class); 393 addIdClassMapping(35, true, false, Packet35EntityHeadRotation.class); 394 addIdClassMapping(38, true, false, Packet38EntityStatus.class); 395 addIdClassMapping(39, true, false, Packet39AttachEntity.class); 396 addIdClassMapping(40, true, false, Packet40EntityMetadata.class); 397 addIdClassMapping(41, true, false, Packet41EntityEffect.class); 398 addIdClassMapping(42, true, false, Packet42RemoveEntityEffect.class); 399 addIdClassMapping(43, true, false, Packet43Experience.class); 400 addIdClassMapping(51, true, false, Packet51MapChunk.class); 401 addIdClassMapping(52, true, false, Packet52MultiBlockChange.class); 402 addIdClassMapping(53, true, false, Packet53BlockChange.class); 403 addIdClassMapping(54, true, false, Packet54PlayNoteBlock.class); 404 addIdClassMapping(55, true, false, Packet55BlockDestroy.class); 405 addIdClassMapping(56, true, false, Packet56MapChunks.class); 406 addIdClassMapping(60, true, false, Packet60Explosion.class); 407 addIdClassMapping(61, true, false, Packet61DoorChange.class); 408 addIdClassMapping(62, true, false, Packet62LevelSound.class); 409 addIdClassMapping(70, true, false, Packet70GameEvent.class); 410 addIdClassMapping(71, true, false, Packet71Weather.class); 411 addIdClassMapping(100, true, false, Packet100OpenWindow.class); 412 addIdClassMapping(101, true, true, Packet101CloseWindow.class); 413 addIdClassMapping(102, false, true, Packet102WindowClick.class); 414 addIdClassMapping(103, true, false, Packet103SetSlot.class); 415 addIdClassMapping(104, true, false, Packet104WindowItems.class); 416 addIdClassMapping(105, true, false, Packet105UpdateProgressbar.class); 417 addIdClassMapping(106, true, true, Packet106Transaction.class); 418 addIdClassMapping(107, true, true, Packet107CreativeSetSlot.class); 419 addIdClassMapping(108, false, true, Packet108EnchantItem.class); 420 addIdClassMapping(130, true, true, Packet130UpdateSign.class); 421 addIdClassMapping(131, true, true, Packet131MapData.class); 422 addIdClassMapping(132, true, false, Packet132TileEntityData.class); 423 addIdClassMapping(200, true, false, Packet200Statistic.class); 424 addIdClassMapping(201, true, false, Packet201PlayerInfo.class); 425 addIdClassMapping(202, true, true, Packet202PlayerAbilities.class); 426 addIdClassMapping(203, true, true, Packet203AutoComplete.class); 427 addIdClassMapping(204, false, true, Packet204ClientInfo.class); 428 addIdClassMapping(205, false, true, Packet205ClientCommand.class); 429 addIdClassMapping(250, true, true, Packet250CustomPayload.class); 430 addIdClassMapping(252, true, true, Packet252SharedKey.class); 431 addIdClassMapping(253, true, false, Packet253ServerAuthData.class); 432 addIdClassMapping(254, false, true, Packet254ServerPing.class); 433 addIdClassMapping(255, true, true, Packet255KickDisconnect.class); 434 } 435 }