001 package net.minecraft.src; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.DataInputStream; 005 import java.io.IOException; 006 import java.util.ArrayList; 007 import java.util.Iterator; 008 import java.util.Random; 009 import java.util.logging.Logger; 010 011 import cpw.mods.fml.common.network.FMLNetworkHandler; 012 import net.minecraft.server.MinecraftServer; 013 import net.minecraftforge.event.Event; 014 import net.minecraftforge.event.ForgeEventFactory; 015 import net.minecraftforge.event.entity.player.PlayerInteractEvent; 016 import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; 017 018 public class NetServerHandler extends NetHandler 019 { 020 /** The logging system. */ 021 public static Logger logger = Logger.getLogger("Minecraft"); 022 023 /** The underlying network manager for this server handler. */ 024 public INetworkManager netManager; 025 026 /** This is set to true whenever a player disconnects from the server. */ 027 public boolean connectionClosed = false; 028 029 /** Reference to the MinecraftServer object. */ 030 private MinecraftServer mcServer; 031 032 /** Reference to the EntityPlayerMP object. */ 033 private EntityPlayerMP playerEntity; 034 035 /** incremented each tick */ 036 private int currentTicks; 037 038 /** 039 * player is kicked if they float for over 80 ticks without flying enabled 040 */ 041 public int ticksForFloatKick; 042 private boolean field_72584_h; 043 private int keepAliveRandomID; 044 private long keepAliveTimeSent; 045 private static Random randomGenerator = new Random(); 046 private long ticksOfLastKeepAlive; 047 private int chatSpamThresholdCount = 0; 048 private int creativeItemCreationSpamThresholdTally = 0; 049 050 /** The last known x position for this connection. */ 051 private double lastPosX; 052 053 /** The last known y position for this connection. */ 054 private double lastPosY; 055 056 /** The last known z position for this connection. */ 057 private double lastPosZ; 058 059 /** is true when the player has moved since his last movement packet */ 060 private boolean hasMoved = true; 061 private IntHashMap field_72586_s = new IntHashMap(); 062 063 public NetServerHandler(MinecraftServer par1, INetworkManager par2, EntityPlayerMP par3) 064 { 065 this.mcServer = par1; 066 this.netManager = par2; 067 par2.setNetHandler(this); 068 this.playerEntity = par3; 069 par3.playerNetServerHandler = this; 070 } 071 072 /** 073 * run once each game tick 074 */ 075 public void networkTick() 076 { 077 this.field_72584_h = false; 078 ++this.currentTicks; 079 this.mcServer.theProfiler.startSection("packetflow"); 080 this.netManager.processReadPackets(); 081 this.mcServer.theProfiler.endStartSection("keepAlive"); 082 083 if ((long)this.currentTicks - this.ticksOfLastKeepAlive > 20L) 084 { 085 this.ticksOfLastKeepAlive = (long)this.currentTicks; 086 this.keepAliveTimeSent = System.nanoTime() / 1000000L; 087 this.keepAliveRandomID = randomGenerator.nextInt(); 088 this.sendPacketToPlayer(new Packet0KeepAlive(this.keepAliveRandomID)); 089 } 090 091 if (this.chatSpamThresholdCount > 0) 092 { 093 --this.chatSpamThresholdCount; 094 } 095 096 if (this.creativeItemCreationSpamThresholdTally > 0) 097 { 098 --this.creativeItemCreationSpamThresholdTally; 099 } 100 101 this.mcServer.theProfiler.endStartSection("playerTick"); 102 103 if (!this.field_72584_h && !this.playerEntity.playerConqueredTheEnd) 104 { 105 this.playerEntity.onUpdateEntity(); 106 107 if (this.playerEntity.ridingEntity == null) 108 { 109 this.playerEntity.setLocationAndAngles(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); 110 } 111 } 112 113 this.mcServer.theProfiler.endSection(); 114 } 115 116 public void kickPlayerFromServer(String par1Str) 117 { 118 if (!this.connectionClosed) 119 { 120 this.playerEntity.mountEntityAndWakeUp(); 121 this.sendPacketToPlayer(new Packet255KickDisconnect(par1Str)); 122 this.netManager.serverShutdown(); 123 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat("\u00a7e" + this.playerEntity.username + " left the game.")); 124 this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity); 125 this.connectionClosed = true; 126 } 127 } 128 129 public void handleFlying(Packet10Flying par1Packet10Flying) 130 { 131 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 132 this.field_72584_h = true; 133 134 if (!this.playerEntity.playerConqueredTheEnd) 135 { 136 double var3; 137 138 if (!this.hasMoved) 139 { 140 var3 = par1Packet10Flying.yPosition - this.lastPosY; 141 142 if (par1Packet10Flying.xPosition == this.lastPosX && var3 * var3 < 0.01D && par1Packet10Flying.zPosition == this.lastPosZ) 143 { 144 this.hasMoved = true; 145 } 146 } 147 148 if (this.hasMoved) 149 { 150 double var5; 151 double var7; 152 double var9; 153 double var13; 154 155 if (this.playerEntity.ridingEntity != null) 156 { 157 float var34 = this.playerEntity.rotationYaw; 158 float var4 = this.playerEntity.rotationPitch; 159 this.playerEntity.ridingEntity.updateRiderPosition(); 160 var5 = this.playerEntity.posX; 161 var7 = this.playerEntity.posY; 162 var9 = this.playerEntity.posZ; 163 double var35 = 0.0D; 164 var13 = 0.0D; 165 166 if (par1Packet10Flying.rotating) 167 { 168 var34 = par1Packet10Flying.yaw; 169 var4 = par1Packet10Flying.pitch; 170 } 171 172 if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D) 173 { 174 if (Math.abs(par1Packet10Flying.xPosition) > 1.0D || Math.abs(par1Packet10Flying.zPosition) > 1.0D) 175 { 176 System.err.println(this.playerEntity.username + " was caught trying to crash the server with an invalid position."); 177 this.kickPlayerFromServer("Nope!"); 178 return; 179 } 180 181 var35 = par1Packet10Flying.xPosition; 182 var13 = par1Packet10Flying.zPosition; 183 } 184 185 this.playerEntity.onGround = par1Packet10Flying.onGround; 186 this.playerEntity.onUpdateEntity(); 187 this.playerEntity.moveEntity(var35, 0.0D, var13); 188 this.playerEntity.setPositionAndRotation(var5, var7, var9, var34, var4); 189 this.playerEntity.motionX = var35; 190 this.playerEntity.motionZ = var13; 191 192 if (this.playerEntity.ridingEntity != null) 193 { 194 var2.uncheckedUpdateEntity(this.playerEntity.ridingEntity, true); 195 } 196 197 if (this.playerEntity.ridingEntity != null) 198 { 199 this.playerEntity.ridingEntity.updateRiderPosition(); 200 } 201 202 if (!this.hasMoved) //Fixes teleportation kick while riding entities 203 { 204 return; 205 } 206 207 this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); 208 this.lastPosX = this.playerEntity.posX; 209 this.lastPosY = this.playerEntity.posY; 210 this.lastPosZ = this.playerEntity.posZ; 211 var2.updateEntity(this.playerEntity); 212 return; 213 } 214 215 if (this.playerEntity.isPlayerSleeping()) 216 { 217 this.playerEntity.onUpdateEntity(); 218 this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); 219 var2.updateEntity(this.playerEntity); 220 return; 221 } 222 223 var3 = this.playerEntity.posY; 224 this.lastPosX = this.playerEntity.posX; 225 this.lastPosY = this.playerEntity.posY; 226 this.lastPosZ = this.playerEntity.posZ; 227 var5 = this.playerEntity.posX; 228 var7 = this.playerEntity.posY; 229 var9 = this.playerEntity.posZ; 230 float var11 = this.playerEntity.rotationYaw; 231 float var12 = this.playerEntity.rotationPitch; 232 233 if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D) 234 { 235 par1Packet10Flying.moving = false; 236 } 237 238 if (par1Packet10Flying.moving) 239 { 240 var5 = par1Packet10Flying.xPosition; 241 var7 = par1Packet10Flying.yPosition; 242 var9 = par1Packet10Flying.zPosition; 243 var13 = par1Packet10Flying.stance - par1Packet10Flying.yPosition; 244 245 if (!this.playerEntity.isPlayerSleeping() && (var13 > 1.65D || var13 < 0.1D)) 246 { 247 this.kickPlayerFromServer("Illegal stance"); 248 logger.warning(this.playerEntity.username + " had an illegal stance: " + var13); 249 return; 250 } 251 252 if (Math.abs(par1Packet10Flying.xPosition) > 3.2E7D || Math.abs(par1Packet10Flying.zPosition) > 3.2E7D) 253 { 254 this.kickPlayerFromServer("Illegal position"); 255 return; 256 } 257 } 258 259 if (par1Packet10Flying.rotating) 260 { 261 var11 = par1Packet10Flying.yaw; 262 var12 = par1Packet10Flying.pitch; 263 } 264 265 this.playerEntity.onUpdateEntity(); 266 this.playerEntity.ySize = 0.0F; 267 this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, var11, var12); 268 269 if (!this.hasMoved) 270 { 271 return; 272 } 273 274 var13 = var5 - this.playerEntity.posX; 275 double var15 = var7 - this.playerEntity.posY; 276 double var17 = var9 - this.playerEntity.posZ; 277 double var19 = Math.min(Math.abs(var13), Math.abs(this.playerEntity.motionX)); 278 double var21 = Math.min(Math.abs(var15), Math.abs(this.playerEntity.motionY)); 279 double var23 = Math.min(Math.abs(var17), Math.abs(this.playerEntity.motionZ)); 280 double var25 = var19 * var19 + var21 * var21 + var23 * var23; 281 282 if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.username))) 283 { 284 logger.warning(this.playerEntity.username + " moved too quickly! " + var13 + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")"); 285 this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); 286 return; 287 } 288 289 float var27 = 0.0625F; 290 boolean var28 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract((double)var27, (double)var27, (double)var27)).isEmpty(); 291 292 if (this.playerEntity.onGround && !par1Packet10Flying.onGround && var15 > 0.0D) 293 { 294 this.playerEntity.addExhaustion(0.2F); 295 } 296 297 if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving 298 { 299 return; 300 } 301 302 this.playerEntity.moveEntity(var13, var15, var17); 303 this.playerEntity.onGround = par1Packet10Flying.onGround; 304 this.playerEntity.addMovementStat(var13, var15, var17); 305 double var29 = var15; 306 var13 = var5 - this.playerEntity.posX; 307 var15 = var7 - this.playerEntity.posY; 308 309 if (var15 > -0.5D || var15 < 0.5D) 310 { 311 var15 = 0.0D; 312 } 313 314 var17 = var9 - this.playerEntity.posZ; 315 var25 = var13 * var13 + var15 * var15 + var17 * var17; 316 boolean var31 = false; 317 318 if (var25 > 0.0625D && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.theItemInWorldManager.isCreative()) 319 { 320 var31 = true; 321 logger.warning(this.playerEntity.username + " moved wrongly!"); 322 } 323 324 if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving 325 { 326 return; 327 } 328 329 this.playerEntity.setPositionAndRotation(var5, var7, var9, var11, var12); 330 boolean var32 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract((double)var27, (double)var27, (double)var27)).isEmpty(); 331 332 if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.noClip) 333 { 334 this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, var11, var12); 335 return; 336 } 337 338 AxisAlignedBB var33 = this.playerEntity.boundingBox.copy().expand((double)var27, (double)var27, (double)var27).addCoord(0.0D, -0.55D, 0.0D); 339 340 if (!this.mcServer.isFlightAllowed() && !this.playerEntity.theItemInWorldManager.isCreative() && !var2.isAABBNonEmpty(var33) && !this.playerEntity.capabilities.allowFlying) 341 { 342 if (var29 >= -0.03125D) 343 { 344 ++this.ticksForFloatKick; 345 346 if (this.ticksForFloatKick > 80) 347 { 348 logger.warning(this.playerEntity.username + " was kicked for floating too long!"); 349 this.kickPlayerFromServer("Flying is not enabled on this server"); 350 return; 351 } 352 } 353 } 354 else 355 { 356 this.ticksForFloatKick = 0; 357 } 358 359 if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving 360 { 361 return; 362 } 363 364 this.playerEntity.onGround = par1Packet10Flying.onGround; 365 this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); 366 this.playerEntity.updateFlyingState(this.playerEntity.posY - var3, par1Packet10Flying.onGround); 367 } 368 } 369 } 370 371 /** 372 * Moves the player to the specified destination and rotation 373 */ 374 public void setPlayerLocation(double par1, double par3, double par5, float par7, float par8) 375 { 376 this.hasMoved = false; 377 this.lastPosX = par1; 378 this.lastPosY = par3; 379 this.lastPosZ = par5; 380 this.playerEntity.setPositionAndRotation(par1, par3, par5, par7, par8); 381 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet13PlayerLookMove(par1, par3 + 1.6200000047683716D, par3, par5, par7, par8, false)); 382 } 383 384 public void handleBlockDig(Packet14BlockDig par1Packet14BlockDig) 385 { 386 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 387 388 if (par1Packet14BlockDig.status == 4) 389 { 390 this.playerEntity.dropOneItem(); 391 } 392 else if (par1Packet14BlockDig.status == 5) 393 { 394 this.playerEntity.stopUsingItem(); 395 } 396 else 397 { 398 boolean var3 = var2.provider.dimensionId != 0 || this.mcServer.getConfigurationManager().getOps().isEmpty() || this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username) || this.mcServer.isSinglePlayer(); 399 boolean var4 = false; 400 401 if (par1Packet14BlockDig.status == 0) 402 { 403 var4 = true; 404 } 405 406 if (par1Packet14BlockDig.status == 2) 407 { 408 var4 = true; 409 } 410 411 int var5 = par1Packet14BlockDig.xPosition; 412 int var6 = par1Packet14BlockDig.yPosition; 413 int var7 = par1Packet14BlockDig.zPosition; 414 415 if (var4) 416 { 417 double var8 = this.playerEntity.posX - ((double)var5 + 0.5D); 418 double var10 = this.playerEntity.posY - ((double)var6 + 0.5D) + 1.5D; 419 double var12 = this.playerEntity.posZ - ((double)var7 + 0.5D); 420 double var14 = var8 * var8 + var10 * var10 + var12 * var12; 421 422 double dist = playerEntity.theItemInWorldManager.getBlockReachDistance() + 1; 423 dist *= dist; 424 425 if (var14 > dist) 426 { 427 return; 428 } 429 430 if (var6 >= this.mcServer.getBuildLimit()) 431 { 432 return; 433 } 434 } 435 436 ChunkCoordinates var19 = var2.getSpawnPoint(); 437 int var9 = MathHelper.abs_int(var5 - var19.posX); 438 int var20 = MathHelper.abs_int(var7 - var19.posZ); 439 440 if (var9 > var20) 441 { 442 var20 = var9; 443 } 444 445 if (par1Packet14BlockDig.status == 0) 446 { 447 if (var20 <= this.mcServer.func_82357_ak() && !var3) 448 { 449 ForgeEventFactory.onPlayerInteract(playerEntity, Action.LEFT_CLICK_BLOCK, var5, var6, var7, 0); 450 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 451 } 452 else 453 { 454 this.playerEntity.theItemInWorldManager.onBlockClicked(var5, var6, var7, par1Packet14BlockDig.face); 455 } 456 } 457 else if (par1Packet14BlockDig.status == 2) 458 { 459 this.playerEntity.theItemInWorldManager.uncheckedTryHarvestBlock(var5, var6, var7); 460 461 if (var2.getBlockId(var5, var6, var7) != 0) 462 { 463 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 464 } 465 } 466 else if (par1Packet14BlockDig.status == 1) 467 { 468 this.playerEntity.theItemInWorldManager.destroyBlockInWorldPartially(var5, var6, var7); 469 470 if (var2.getBlockId(var5, var6, var7) != 0) 471 { 472 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 473 } 474 } 475 else if (par1Packet14BlockDig.status == 3) 476 { 477 double var11 = this.playerEntity.posX - ((double)var5 + 0.5D); 478 double var13 = this.playerEntity.posY - ((double)var6 + 0.5D); 479 double var15 = this.playerEntity.posZ - ((double)var7 + 0.5D); 480 double var17 = var11 * var11 + var13 * var13 + var15 * var15; 481 482 if (var17 < 256.0D) 483 { 484 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 485 } 486 } 487 } 488 } 489 490 public void handlePlace(Packet15Place par1Packet15Place) 491 { 492 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 493 ItemStack var3 = this.playerEntity.inventory.getCurrentItem(); 494 boolean var4 = false; 495 int var5 = par1Packet15Place.getXPosition(); 496 int var6 = par1Packet15Place.getYPosition(); 497 int var7 = par1Packet15Place.getZPosition(); 498 int var8 = par1Packet15Place.getDirection(); 499 boolean var9 = var2.provider.dimensionId != 0 || this.mcServer.getConfigurationManager().getOps().isEmpty() || this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username) || this.mcServer.isSinglePlayer(); 500 501 if (par1Packet15Place.getDirection() == 255) 502 { 503 if (var3 == null) 504 { 505 return; 506 } 507 508 PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(playerEntity, PlayerInteractEvent.Action.RIGHT_CLICK_AIR, 0, 0, 0, -1); 509 if (event.useItem != Event.Result.DENY) 510 { 511 this.playerEntity.theItemInWorldManager.tryUseItem(this.playerEntity, var2, var3); 512 } 513 } 514 else if (par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit() - 1 && (par1Packet15Place.getDirection() == 1 || par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit())) 515 { 516 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet3Chat("\u00a77Height limit for building is " + this.mcServer.getBuildLimit())); 517 var4 = true; 518 } 519 else 520 { 521 ChunkCoordinates var10 = var2.getSpawnPoint(); 522 int var11 = MathHelper.abs_int(var5 - var10.posX); 523 int var12 = MathHelper.abs_int(var7 - var10.posZ); 524 525 if (var11 > var12) 526 { 527 var12 = var11; 528 } 529 530 double dist = playerEntity.theItemInWorldManager.getBlockReachDistance() + 1; 531 dist *= dist; 532 if (this.hasMoved && this.playerEntity.getDistanceSq((double)var5 + 0.5D, (double)var6 + 0.5D, (double)var7 + 0.5D) < dist && (var12 > this.mcServer.func_82357_ak() || var9)) 533 { 534 this.playerEntity.theItemInWorldManager.activateBlockOrUseItem(this.playerEntity, var2, var3, var5, var6, var7, var8, par1Packet15Place.getXOffset(), par1Packet15Place.getYOffset(), par1Packet15Place.getZOffset()); 535 } 536 537 var4 = true; 538 } 539 540 if (var4) 541 { 542 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 543 544 if (var8 == 0) 545 { 546 --var6; 547 } 548 549 if (var8 == 1) 550 { 551 ++var6; 552 } 553 554 if (var8 == 2) 555 { 556 --var7; 557 } 558 559 if (var8 == 3) 560 { 561 ++var7; 562 } 563 564 if (var8 == 4) 565 { 566 --var5; 567 } 568 569 if (var8 == 5) 570 { 571 ++var5; 572 } 573 574 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 575 } 576 577 var3 = this.playerEntity.inventory.getCurrentItem(); 578 579 if (var3 != null && var3.stackSize == 0) 580 { 581 this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = null; 582 var3 = null; 583 } 584 585 if (var3 == null || var3.getMaxItemUseDuration() == 0) 586 { 587 this.playerEntity.playerInventoryBeingManipulated = true; 588 this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = ItemStack.copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem]); 589 Slot var13 = this.playerEntity.craftingInventory.getSlotFromInventory(this.playerEntity.inventory, this.playerEntity.inventory.currentItem); 590 this.playerEntity.craftingInventory.updateCraftingResults(); 591 this.playerEntity.playerInventoryBeingManipulated = false; 592 593 if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), par1Packet15Place.getItemStack())) 594 { 595 this.sendPacketToPlayer(new Packet103SetSlot(this.playerEntity.craftingInventory.windowId, var13.slotNumber, this.playerEntity.inventory.getCurrentItem())); 596 } 597 } 598 } 599 600 public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) 601 { 602 logger.info(this.playerEntity.username + " lost connection: " + par1Str); 603 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat("\u00a7e" + this.playerEntity.username + " left the game.")); 604 this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity); 605 this.connectionClosed = true; 606 607 if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner())) 608 { 609 logger.info("Stopping singleplayer server as player logged out"); 610 this.mcServer.initiateShutdown(); 611 } 612 } 613 614 /** 615 * Default handler called for packets that don't have their own handlers in NetClientHandler; currentlly does 616 * nothing. 617 */ 618 public void unexpectedPacket(Packet par1Packet) 619 { 620 logger.warning(this.getClass() + " wasn\'t prepared to deal with a " + par1Packet.getClass()); 621 this.kickPlayerFromServer("Protocol error, unexpected packet"); 622 } 623 624 /** 625 * addToSendQueue. if it is a chat packet, check before sending it 626 */ 627 public void sendPacketToPlayer(Packet par1Packet) 628 { 629 if (par1Packet instanceof Packet3Chat) 630 { 631 Packet3Chat var2 = (Packet3Chat)par1Packet; 632 int var3 = this.playerEntity.getChatVisibility(); 633 634 if (var3 == 2) 635 { 636 return; 637 } 638 639 if (var3 == 1 && !var2.func_73475_d()) 640 { 641 return; 642 } 643 } 644 645 this.netManager.addToSendQueue(par1Packet); 646 } 647 648 public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch) 649 { 650 if (par1Packet16BlockItemSwitch.id >= 0 && par1Packet16BlockItemSwitch.id < InventoryPlayer.func_70451_h()) 651 { 652 this.playerEntity.inventory.currentItem = par1Packet16BlockItemSwitch.id; 653 } 654 else 655 { 656 logger.warning(this.playerEntity.username + " tried to set an invalid carried item"); 657 } 658 } 659 660 public void handleChat(Packet3Chat par1Packet3Chat) 661 { 662 par1Packet3Chat = FMLNetworkHandler.handleChatMessage(this, par1Packet3Chat); 663 if (this.playerEntity.getChatVisibility() == 2) 664 { 665 this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message.")); 666 } 667 else 668 { 669 String var2 = par1Packet3Chat.message; 670 671 if (var2.length() > 100) 672 { 673 this.kickPlayerFromServer("Chat message too long"); 674 } 675 else 676 { 677 var2 = var2.trim(); 678 679 for (int var3 = 0; var3 < var2.length(); ++var3) 680 { 681 if (!ChatAllowedCharacters.isAllowedCharacter(var2.charAt(var3))) 682 { 683 this.kickPlayerFromServer("Illegal characters in chat"); 684 return; 685 } 686 } 687 688 if (var2.startsWith("/")) 689 { 690 this.handleSlashCommand(var2); 691 } 692 else 693 { 694 if (this.playerEntity.getChatVisibility() == 1) 695 { 696 this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message.")); 697 return; 698 } 699 700 var2 = "<" + this.playerEntity.username + "> " + var2; 701 logger.info(var2); 702 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(var2, false)); 703 } 704 705 this.chatSpamThresholdCount += 20; 706 707 if (this.chatSpamThresholdCount > 200 && !this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username)) 708 { 709 this.kickPlayerFromServer("disconnect.spam"); 710 } 711 } 712 } 713 } 714 715 /** 716 * Processes a / command 717 */ 718 private void handleSlashCommand(String par1Str) 719 { 720 this.mcServer.getCommandManager().executeCommand(this.playerEntity, par1Str); 721 } 722 723 public void handleAnimation(Packet18Animation par1Packet18Animation) 724 { 725 if (par1Packet18Animation.animate == 1) 726 { 727 this.playerEntity.swingItem(); 728 } 729 } 730 731 /** 732 * runs registerPacket on the given Packet19EntityAction 733 */ 734 public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction) 735 { 736 if (par1Packet19EntityAction.state == 1) 737 { 738 this.playerEntity.setSneaking(true); 739 } 740 else if (par1Packet19EntityAction.state == 2) 741 { 742 this.playerEntity.setSneaking(false); 743 } 744 else if (par1Packet19EntityAction.state == 4) 745 { 746 this.playerEntity.setSprinting(true); 747 } 748 else if (par1Packet19EntityAction.state == 5) 749 { 750 this.playerEntity.setSprinting(false); 751 } 752 else if (par1Packet19EntityAction.state == 3) 753 { 754 this.playerEntity.wakeUpPlayer(false, true, true); 755 this.hasMoved = false; 756 } 757 } 758 759 public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect) 760 { 761 this.netManager.networkShutdown("disconnect.quitting", new Object[0]); 762 } 763 764 /** 765 * returns 0 for memoryMapped connections 766 */ 767 public int packetSize() 768 { 769 return this.netManager.packetSize(); 770 } 771 772 public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity) 773 { 774 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 775 Entity var3 = var2.getEntityByID(par1Packet7UseEntity.targetEntity); 776 777 if (var3 != null) 778 { 779 boolean var4 = this.playerEntity.canEntityBeSeen(var3); 780 double var5 = 36.0D; 781 782 if (!var4) 783 { 784 var5 = 9.0D; 785 } 786 787 if (this.playerEntity.getDistanceSqToEntity(var3) < var5) 788 { 789 if (par1Packet7UseEntity.isLeftClick == 0) 790 { 791 this.playerEntity.interactWith(var3); 792 } 793 else if (par1Packet7UseEntity.isLeftClick == 1) 794 { 795 this.playerEntity.attackTargetEntityWithCurrentItem(var3); 796 } 797 } 798 } 799 } 800 801 public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) 802 { 803 if (par1Packet205ClientCommand.forceRespawn == 1) 804 { 805 if (this.playerEntity.playerConqueredTheEnd) 806 { 807 this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true); 808 } 809 else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled()) 810 { 811 if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner())) 812 { 813 this.playerEntity.playerNetServerHandler.kickPlayerFromServer("You have died. Game over, man, it\'s game over!"); 814 this.mcServer.deleteWorldAndStopServer(); 815 } 816 else 817 { 818 BanEntry var2 = new BanEntry(this.playerEntity.username); 819 var2.setBanReason("Death in Hardcore"); 820 this.mcServer.getConfigurationManager().getBannedPlayers().put(var2); 821 this.playerEntity.playerNetServerHandler.kickPlayerFromServer("You have died. Game over, man, it\'s game over!"); 822 } 823 } 824 else 825 { 826 if (this.playerEntity.getHealth() > 0) 827 { 828 return; 829 } 830 831 this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, playerEntity.dimension, false); 832 } 833 } 834 } 835 836 /** 837 * packet.processPacket is only called if this returns true 838 */ 839 public boolean canProcessPackets() 840 { 841 return true; 842 } 843 844 /** 845 * respawns the player 846 */ 847 public void handleRespawn(Packet9Respawn par1Packet9Respawn) {} 848 849 public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow) 850 { 851 this.playerEntity.closeInventory(); 852 } 853 854 public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick) 855 { 856 if (this.playerEntity.craftingInventory.windowId == par1Packet102WindowClick.window_Id && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity)) 857 { 858 ItemStack var2 = this.playerEntity.craftingInventory.slotClick(par1Packet102WindowClick.inventorySlot, par1Packet102WindowClick.mouseClick, par1Packet102WindowClick.holdingShift, this.playerEntity); 859 860 if (ItemStack.areItemStacksEqual(par1Packet102WindowClick.itemStack, var2)) 861 { 862 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, true)); 863 this.playerEntity.playerInventoryBeingManipulated = true; 864 this.playerEntity.craftingInventory.updateCraftingResults(); 865 this.playerEntity.sendInventoryToPlayer(); 866 this.playerEntity.playerInventoryBeingManipulated = false; 867 } 868 else 869 { 870 this.field_72586_s.addKey(this.playerEntity.craftingInventory.windowId, Short.valueOf(par1Packet102WindowClick.action)); 871 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, false)); 872 this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, false); 873 ArrayList var3 = new ArrayList(); 874 875 for (int var4 = 0; var4 < this.playerEntity.craftingInventory.inventorySlots.size(); ++var4) 876 { 877 var3.add(((Slot)this.playerEntity.craftingInventory.inventorySlots.get(var4)).getStack()); 878 } 879 880 this.playerEntity.sendContainerAndContentsToPlayer(this.playerEntity.craftingInventory, var3); 881 } 882 } 883 } 884 885 public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem) 886 { 887 if (this.playerEntity.craftingInventory.windowId == par1Packet108EnchantItem.windowId && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity)) 888 { 889 this.playerEntity.craftingInventory.enchantItem(this.playerEntity, par1Packet108EnchantItem.enchantment); 890 this.playerEntity.craftingInventory.updateCraftingResults(); 891 } 892 } 893 894 /** 895 * Handle a creative slot packet. 896 */ 897 public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot) 898 { 899 if (this.playerEntity.theItemInWorldManager.isCreative()) 900 { 901 boolean var2 = par1Packet107CreativeSetSlot.slot < 0; 902 ItemStack var3 = par1Packet107CreativeSetSlot.itemStack; 903 boolean var4 = par1Packet107CreativeSetSlot.slot >= 1 && par1Packet107CreativeSetSlot.slot < 36 + InventoryPlayer.func_70451_h(); 904 boolean var5 = var3 == null || var3.itemID < Item.itemsList.length && var3.itemID >= 0 && Item.itemsList[var3.itemID] != null; 905 boolean var6 = var3 == null || var3.getItemDamage() >= 0 && var3.getItemDamage() >= 0 && var3.stackSize <= 64 && var3.stackSize > 0; 906 907 if (var4 && var5 && var6) 908 { 909 if (var3 == null) 910 { 911 this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, (ItemStack)null); 912 } 913 else 914 { 915 this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, var3); 916 } 917 918 this.playerEntity.inventorySlots.setPlayerIsPresent(this.playerEntity, true); 919 } 920 else if (var2 && var5 && var6 && this.creativeItemCreationSpamThresholdTally < 200) 921 { 922 this.creativeItemCreationSpamThresholdTally += 20; 923 EntityItem var7 = this.playerEntity.dropPlayerItem(var3); 924 925 if (var7 != null) 926 { 927 var7.func_70288_d(); 928 } 929 } 930 } 931 } 932 933 public void handleTransaction(Packet106Transaction par1Packet106Transaction) 934 { 935 Short var2 = (Short)this.field_72586_s.lookup(this.playerEntity.craftingInventory.windowId); 936 937 if (var2 != null && par1Packet106Transaction.shortWindowId == var2.shortValue() && this.playerEntity.craftingInventory.windowId == par1Packet106Transaction.windowId && !this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity)) 938 { 939 this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, true); 940 } 941 } 942 943 /** 944 * Updates Client side signs 945 */ 946 public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign) 947 { 948 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 949 950 if (var2.blockExists(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition)) 951 { 952 TileEntity var3 = var2.getBlockTileEntity(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition); 953 954 if (var3 instanceof TileEntitySign) 955 { 956 TileEntitySign var4 = (TileEntitySign)var3; 957 958 if (!var4.isEditable()) 959 { 960 this.mcServer.logWarning("Player " + this.playerEntity.username + " just tried to change non-editable sign"); 961 return; 962 } 963 } 964 965 int var6; 966 int var8; 967 968 for (var8 = 0; var8 < 4; ++var8) 969 { 970 boolean var5 = true; 971 972 if (par1Packet130UpdateSign.signLines[var8].length() > 15) 973 { 974 var5 = false; 975 } 976 else 977 { 978 for (var6 = 0; var6 < par1Packet130UpdateSign.signLines[var8].length(); ++var6) 979 { 980 if (ChatAllowedCharacters.allowedCharacters.indexOf(par1Packet130UpdateSign.signLines[var8].charAt(var6)) < 0) 981 { 982 var5 = false; 983 } 984 } 985 } 986 987 if (!var5) 988 { 989 par1Packet130UpdateSign.signLines[var8] = "!?"; 990 } 991 } 992 993 if (var3 instanceof TileEntitySign) 994 { 995 var8 = par1Packet130UpdateSign.xPosition; 996 int var9 = par1Packet130UpdateSign.yPosition; 997 var6 = par1Packet130UpdateSign.zPosition; 998 TileEntitySign var7 = (TileEntitySign)var3; 999 System.arraycopy(par1Packet130UpdateSign.signLines, 0, var7.signText, 0, 4); 1000 var7.onInventoryChanged(); 1001 var2.markBlockNeedsUpdate(var8, var9, var6); 1002 } 1003 } 1004 } 1005 1006 /** 1007 * Handle a keep alive packet. 1008 */ 1009 public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive) 1010 { 1011 if (par1Packet0KeepAlive.randomId == this.keepAliveRandomID) 1012 { 1013 int var2 = (int)(System.nanoTime() / 1000000L - this.keepAliveTimeSent); 1014 this.playerEntity.ping = (this.playerEntity.ping * 3 + var2) / 4; 1015 } 1016 } 1017 1018 /** 1019 * determine if it is a server handler 1020 */ 1021 public boolean isServerHandler() 1022 { 1023 return true; 1024 } 1025 1026 /** 1027 * Handle a player abilities packet. 1028 */ 1029 public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities) 1030 { 1031 this.playerEntity.capabilities.isFlying = par1Packet202PlayerAbilities.getFlying() && this.playerEntity.capabilities.allowFlying; 1032 } 1033 1034 public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete) 1035 { 1036 StringBuilder var2 = new StringBuilder(); 1037 String var4; 1038 1039 for (Iterator var3 = this.mcServer.getPossibleCompletions(this.playerEntity, par1Packet203AutoComplete.getText()).iterator(); var3.hasNext(); var2.append(var4)) 1040 { 1041 var4 = (String)var3.next(); 1042 1043 if (var2.length() > 0) 1044 { 1045 var2.append("\u0000"); 1046 } 1047 } 1048 1049 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet203AutoComplete(var2.toString())); 1050 } 1051 1052 public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo) 1053 { 1054 this.playerEntity.updateClientInfo(par1Packet204ClientInfo); 1055 } 1056 1057 public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload) 1058 { 1059 FMLNetworkHandler.handlePacket250Packet(par1Packet250CustomPayload, netManager, this); 1060 } 1061 1062 public void handleVanilla250Packet(Packet250CustomPayload par1Packet250CustomPayload) 1063 { 1064 DataInputStream var2; 1065 ItemStack var3; 1066 ItemStack var4; 1067 1068 if ("MC|BEdit".equals(par1Packet250CustomPayload.channel)) 1069 { 1070 try 1071 { 1072 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1073 var3 = Packet.readItemStack(var2); 1074 1075 if (!ItemWritableBook.validBookTagPages(var3.getTagCompound())) 1076 { 1077 throw new IOException("Invalid book tag!"); 1078 } 1079 1080 var4 = this.playerEntity.inventory.getCurrentItem(); 1081 1082 if (var3 != null && var3.itemID == Item.writableBook.shiftedIndex && var3.itemID == var4.itemID) 1083 { 1084 var4.setTagCompound(var3.getTagCompound()); 1085 } 1086 } 1087 catch (Exception var12) 1088 { 1089 var12.printStackTrace(); 1090 } 1091 } 1092 else if ("MC|BSign".equals(par1Packet250CustomPayload.channel)) 1093 { 1094 try 1095 { 1096 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1097 var3 = Packet.readItemStack(var2); 1098 1099 if (!ItemEditableBook.validBookTagContents(var3.getTagCompound())) 1100 { 1101 throw new IOException("Invalid book tag!"); 1102 } 1103 1104 var4 = this.playerEntity.inventory.getCurrentItem(); 1105 1106 if (var3 != null && var3.itemID == Item.writtenBook.shiftedIndex && var4.itemID == Item.writableBook.shiftedIndex) 1107 { 1108 var4.setTagCompound(var3.getTagCompound()); 1109 var4.itemID = Item.writtenBook.shiftedIndex; 1110 } 1111 } 1112 catch (Exception var11) 1113 { 1114 var11.printStackTrace(); 1115 } 1116 } 1117 else 1118 { 1119 int var14; 1120 1121 if ("MC|TrSel".equals(par1Packet250CustomPayload.channel)) 1122 { 1123 try 1124 { 1125 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1126 var14 = var2.readInt(); 1127 Container var15 = this.playerEntity.craftingInventory; 1128 1129 if (var15 instanceof ContainerMerchant) 1130 { 1131 ((ContainerMerchant)var15).setCurrentRecipeIndex(var14); 1132 } 1133 } 1134 catch (Exception var10) 1135 { 1136 var10.printStackTrace(); 1137 } 1138 } 1139 else 1140 { 1141 int var18; 1142 1143 if ("MC|AdvCdm".equals(par1Packet250CustomPayload.channel)) 1144 { 1145 if (!this.mcServer.func_82356_Z()) 1146 { 1147 this.playerEntity.sendChatToPlayer(this.playerEntity.translateString("advMode.notEnabled", new Object[0])); 1148 } 1149 else if (this.playerEntity.canCommandSenderUseCommand(2, "") && this.playerEntity.capabilities.isCreativeMode) 1150 { 1151 try 1152 { 1153 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1154 var14 = var2.readInt(); 1155 var18 = var2.readInt(); 1156 int var5 = var2.readInt(); 1157 String var6 = Packet.readString(var2, 256); 1158 TileEntity var7 = this.playerEntity.worldObj.getBlockTileEntity(var14, var18, var5); 1159 1160 if (var7 != null && var7 instanceof TileEntityCommandBlock) 1161 { 1162 ((TileEntityCommandBlock)var7).func_82352_b(var6); 1163 this.playerEntity.worldObj.markBlockNeedsUpdate(var14, var18, var5); 1164 this.playerEntity.sendChatToPlayer("Command set: " + var6); 1165 } 1166 } 1167 catch (Exception var9) 1168 { 1169 var9.printStackTrace(); 1170 } 1171 } 1172 else 1173 { 1174 this.playerEntity.sendChatToPlayer(this.playerEntity.translateString("advMode.notAllowed", new Object[0])); 1175 } 1176 } 1177 else if ("MC|Beacon".equals(par1Packet250CustomPayload.channel)) 1178 { 1179 if (this.playerEntity.craftingInventory instanceof ContainerBeacon) 1180 { 1181 try 1182 { 1183 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1184 var14 = var2.readInt(); 1185 var18 = var2.readInt(); 1186 ContainerBeacon var17 = (ContainerBeacon)this.playerEntity.craftingInventory; 1187 Slot var19 = var17.getSlot(0); 1188 1189 if (var19.getHasStack()) 1190 { 1191 var19.decrStackSize(1); 1192 TileEntityBeacon var20 = var17.func_82863_d(); 1193 var20.func_82128_d(var14); 1194 var20.func_82127_e(var18); 1195 var20.onInventoryChanged(); 1196 } 1197 } 1198 catch (Exception var8) 1199 { 1200 var8.printStackTrace(); 1201 } 1202 } 1203 } 1204 else if ("MC|ItemName".equals(par1Packet250CustomPayload.channel) && this.playerEntity.craftingInventory instanceof ContainerRepair) 1205 { 1206 ContainerRepair var13 = (ContainerRepair)this.playerEntity.craftingInventory; 1207 1208 if (par1Packet250CustomPayload.data != null && par1Packet250CustomPayload.data.length >= 1) 1209 { 1210 String var16 = ChatAllowedCharacters.filerAllowedCharacters(new String(par1Packet250CustomPayload.data)); 1211 1212 if (var16.length() <= 30) 1213 { 1214 var13.func_82850_a(var16); 1215 } 1216 } 1217 else 1218 { 1219 var13.func_82850_a(""); 1220 } 1221 } 1222 } 1223 } 1224 } 1225 1226 @Override 1227 1228 /** 1229 * Contains logic for handling packets containing arbitrary unique item data. Currently this is only for maps. 1230 */ 1231 public void handleMapData(Packet131MapData par1Packet131MapData) 1232 { 1233 FMLNetworkHandler.handlePacket131Packet(this, par1Packet131MapData); 1234 } 1235 1236 // modloader compat -- yuk! 1237 @Override 1238 public EntityPlayerMP getPlayer() 1239 { 1240 return playerEntity; 1241 } 1242 }