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 NetworkManager 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 par1MinecraftServer, NetworkManager par2NetworkManager, EntityPlayerMP par3EntityPlayerMP) 064 { 065 this.mcServer = par1MinecraftServer; 066 this.netManager = par2NetworkManager; 067 par2NetworkManager.setNetHandler(this); 068 this.playerEntity = par3EntityPlayerMP; 069 par3EntityPlayerMP.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.actionsAllowed = var2.provider.dimensionId != 0 || 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 <= mcServer.spawnProtectionSize && !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 var2.actionsAllowed = false; 489 } 490 } 491 492 public void handlePlace(Packet15Place par1Packet15Place) 493 { 494 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 495 ItemStack var3 = this.playerEntity.inventory.getCurrentItem(); 496 boolean var4 = false; 497 int var5 = par1Packet15Place.getXPosition(); 498 int var6 = par1Packet15Place.getYPosition(); 499 int var7 = par1Packet15Place.getZPosition(); 500 int var8 = par1Packet15Place.getDirection(); 501 boolean var9 = var2.actionsAllowed = var2.provider.dimensionId != 0 || this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username) || this.mcServer.isSinglePlayer(); 502 503 if (par1Packet15Place.getDirection() == 255) 504 { 505 if (var3 == null) 506 { 507 return; 508 } 509 510 PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(playerEntity, PlayerInteractEvent.Action.RIGHT_CLICK_AIR, 0, 0, 0, -1); 511 if (event.useItem != Event.Result.DENY) 512 { 513 this.playerEntity.theItemInWorldManager.tryUseItem(this.playerEntity, var2, var3); 514 } 515 } 516 else if (par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit() - 1 && (par1Packet15Place.getDirection() == 1 || par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit())) 517 { 518 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet3Chat("\u00a77Height limit for building is " + this.mcServer.getBuildLimit())); 519 var4 = true; 520 } 521 else 522 { 523 ChunkCoordinates var10 = var2.getSpawnPoint(); 524 int var11 = MathHelper.abs_int(var5 - var10.posX); 525 int var12 = MathHelper.abs_int(var7 - var10.posZ); 526 527 if (var11 > var12) 528 { 529 var12 = var11; 530 } 531 532 double dist = playerEntity.theItemInWorldManager.getBlockReachDistance() + 1; 533 dist *= dist; 534 if (this.hasMoved && this.playerEntity.getDistanceSq((double)var5 + 0.5D, (double)var6 + 0.5D, (double)var7 + 0.5D) < dist && (var12 > mcServer.spawnProtectionSize || var9)) 535 { 536 this.playerEntity.theItemInWorldManager.activateBlockOrUseItem(this.playerEntity, var2, var3, var5, var6, var7, var8, par1Packet15Place.getXOffset(), par1Packet15Place.getYOffset(), par1Packet15Place.getZOffset()); 537 } 538 539 var4 = true; 540 } 541 542 if (var4) 543 { 544 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 545 546 if (var8 == 0) 547 { 548 --var6; 549 } 550 551 if (var8 == 1) 552 { 553 ++var6; 554 } 555 556 if (var8 == 2) 557 { 558 --var7; 559 } 560 561 if (var8 == 3) 562 { 563 ++var7; 564 } 565 566 if (var8 == 4) 567 { 568 --var5; 569 } 570 571 if (var8 == 5) 572 { 573 ++var5; 574 } 575 576 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2)); 577 } 578 579 var3 = this.playerEntity.inventory.getCurrentItem(); 580 581 if (var3 != null && var3.stackSize == 0) 582 { 583 this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = null; 584 var3 = null; 585 } 586 587 if (var3 == null || var3.getMaxItemUseDuration() == 0) 588 { 589 this.playerEntity.playerInventoryBeingManipulated = true; 590 this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = ItemStack.copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem]); 591 Slot var13 = this.playerEntity.craftingInventory.getSlotFromInventory(this.playerEntity.inventory, this.playerEntity.inventory.currentItem); 592 this.playerEntity.craftingInventory.updateCraftingResults(); 593 this.playerEntity.playerInventoryBeingManipulated = false; 594 595 if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), par1Packet15Place.getItemStack())) 596 { 597 this.sendPacketToPlayer(new Packet103SetSlot(this.playerEntity.craftingInventory.windowId, var13.slotNumber, this.playerEntity.inventory.getCurrentItem())); 598 } 599 } 600 601 var2.actionsAllowed = false; 602 } 603 604 public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj) 605 { 606 logger.info(this.playerEntity.username + " lost connection: " + par1Str); 607 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat("\u00a7e" + this.playerEntity.username + " left the game.")); 608 this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity); 609 this.connectionClosed = true; 610 611 if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner())) 612 { 613 logger.info("Stopping singleplayer server as player logged out"); 614 this.mcServer.initiateShutdown(); 615 } 616 } 617 618 /** 619 * Default handler called for packets that don't have their own handlers in NetClientHandler; currentlly does 620 * nothing. 621 */ 622 public void unexpectedPacket(Packet par1Packet) 623 { 624 logger.warning(this.getClass() + " wasn\'t prepared to deal with a " + par1Packet.getClass()); 625 this.kickPlayerFromServer("Protocol error, unexpected packet"); 626 } 627 628 /** 629 * addToSendQueue. if it is a chat packet, check before sending it 630 */ 631 public void sendPacketToPlayer(Packet par1Packet) 632 { 633 if (par1Packet instanceof Packet3Chat) 634 { 635 Packet3Chat var2 = (Packet3Chat)par1Packet; 636 int var3 = this.playerEntity.getChatVisibility(); 637 638 if (var3 == 2) 639 { 640 return; 641 } 642 643 if (var3 == 1 && !var2.func_73475_d()) 644 { 645 return; 646 } 647 } 648 649 this.netManager.addToSendQueue(par1Packet); 650 } 651 652 public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch) 653 { 654 if (par1Packet16BlockItemSwitch.id >= 0 && par1Packet16BlockItemSwitch.id < InventoryPlayer.func_70451_h()) 655 { 656 this.playerEntity.inventory.currentItem = par1Packet16BlockItemSwitch.id; 657 } 658 else 659 { 660 logger.warning(this.playerEntity.username + " tried to set an invalid carried item"); 661 } 662 } 663 664 public void handleChat(Packet3Chat par1Packet3Chat) 665 { 666 par1Packet3Chat = FMLNetworkHandler.handleChatMessage(this, par1Packet3Chat); 667 if (this.playerEntity.getChatVisibility() == 2) 668 { 669 this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message.")); 670 } 671 else 672 { 673 String var2 = par1Packet3Chat.message; 674 675 if (var2.length() > 100) 676 { 677 this.kickPlayerFromServer("Chat message too long"); 678 } 679 else 680 { 681 var2 = var2.trim(); 682 683 for (int var3 = 0; var3 < var2.length(); ++var3) 684 { 685 if (!ChatAllowedCharacters.isAllowedCharacter(var2.charAt(var3))) 686 { 687 this.kickPlayerFromServer("Illegal characters in chat"); 688 return; 689 } 690 } 691 692 if (var2.startsWith("/")) 693 { 694 this.handleSlashCommand(var2); 695 } 696 else 697 { 698 if (this.playerEntity.getChatVisibility() == 1) 699 { 700 this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message.")); 701 return; 702 } 703 704 var2 = "<" + this.playerEntity.username + "> " + var2; 705 logger.info(var2); 706 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(var2, false)); 707 } 708 709 this.chatSpamThresholdCount += 20; 710 711 if (this.chatSpamThresholdCount > 200 && !this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username)) 712 { 713 this.kickPlayerFromServer("disconnect.spam"); 714 } 715 } 716 } 717 } 718 719 /** 720 * Processes a / command 721 */ 722 private void handleSlashCommand(String par1Str) 723 { 724 this.mcServer.getCommandManager().executeCommand(this.playerEntity, par1Str); 725 } 726 727 public void handleAnimation(Packet18Animation par1Packet18Animation) 728 { 729 if (par1Packet18Animation.animate == 1) 730 { 731 this.playerEntity.swingItem(); 732 } 733 } 734 735 /** 736 * runs registerPacket on the given Packet19EntityAction 737 */ 738 public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction) 739 { 740 if (par1Packet19EntityAction.state == 1) 741 { 742 this.playerEntity.setSneaking(true); 743 } 744 else if (par1Packet19EntityAction.state == 2) 745 { 746 this.playerEntity.setSneaking(false); 747 } 748 else if (par1Packet19EntityAction.state == 4) 749 { 750 this.playerEntity.setSprinting(true); 751 } 752 else if (par1Packet19EntityAction.state == 5) 753 { 754 this.playerEntity.setSprinting(false); 755 } 756 else if (par1Packet19EntityAction.state == 3) 757 { 758 this.playerEntity.wakeUpPlayer(false, true, true); 759 this.hasMoved = false; 760 } 761 } 762 763 public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect) 764 { 765 this.netManager.networkShutdown("disconnect.quitting", new Object[0]); 766 } 767 768 /** 769 * returns 0 for memoryMapped connections 770 */ 771 public int packetSize() 772 { 773 return this.netManager.packetSize(); 774 } 775 776 public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity) 777 { 778 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 779 Entity var3 = var2.getEntityByID(par1Packet7UseEntity.targetEntity); 780 781 if (var3 != null) 782 { 783 boolean var4 = this.playerEntity.canEntityBeSeen(var3); 784 double var5 = 36.0D; 785 786 if (!var4) 787 { 788 var5 = 9.0D; 789 } 790 791 if (this.playerEntity.getDistanceSqToEntity(var3) < var5) 792 { 793 if (par1Packet7UseEntity.isLeftClick == 0) 794 { 795 this.playerEntity.interactWith(var3); 796 } 797 else if (par1Packet7UseEntity.isLeftClick == 1) 798 { 799 this.playerEntity.attackTargetEntityWithCurrentItem(var3); 800 } 801 } 802 } 803 } 804 805 public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand) 806 { 807 if (par1Packet205ClientCommand.forceRespawn == 1) 808 { 809 if (this.playerEntity.playerConqueredTheEnd) 810 { 811 this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true); 812 } 813 else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled()) 814 { 815 if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner())) 816 { 817 this.playerEntity.playerNetServerHandler.kickPlayerFromServer("You have died. Game over, man, it\'s game over!"); 818 this.mcServer.deleteWorldAndStopServer(); 819 } 820 else 821 { 822 BanEntry var2 = new BanEntry(this.playerEntity.username); 823 var2.setBanReason("Death in Hardcore"); 824 this.mcServer.getConfigurationManager().getBannedPlayers().put(var2); 825 this.playerEntity.playerNetServerHandler.kickPlayerFromServer("You have died. Game over, man, it\'s game over!"); 826 } 827 } 828 else 829 { 830 if (this.playerEntity.getHealth() > 0) 831 { 832 return; 833 } 834 835 this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, playerEntity.dimension, false); 836 } 837 } 838 } 839 840 /** 841 * packet.processPacket is only called if this returns true 842 */ 843 public boolean canProcessPackets() 844 { 845 return true; 846 } 847 848 /** 849 * respawns the player 850 */ 851 public void handleRespawn(Packet9Respawn par1Packet9Respawn) {} 852 853 public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow) 854 { 855 this.playerEntity.closeInventory(); 856 } 857 858 public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick) 859 { 860 if (this.playerEntity.craftingInventory.windowId == par1Packet102WindowClick.window_Id && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity)) 861 { 862 ItemStack var2 = this.playerEntity.craftingInventory.slotClick(par1Packet102WindowClick.inventorySlot, par1Packet102WindowClick.mouseClick, par1Packet102WindowClick.holdingShift, this.playerEntity); 863 864 if (ItemStack.areItemStacksEqual(par1Packet102WindowClick.itemStack, var2)) 865 { 866 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, true)); 867 this.playerEntity.playerInventoryBeingManipulated = true; 868 this.playerEntity.craftingInventory.updateCraftingResults(); 869 this.playerEntity.sendInventoryToPlayer(); 870 this.playerEntity.playerInventoryBeingManipulated = false; 871 } 872 else 873 { 874 this.field_72586_s.addKey(this.playerEntity.craftingInventory.windowId, Short.valueOf(par1Packet102WindowClick.action)); 875 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, false)); 876 this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, false); 877 ArrayList var3 = new ArrayList(); 878 879 for (int var4 = 0; var4 < this.playerEntity.craftingInventory.inventorySlots.size(); ++var4) 880 { 881 var3.add(((Slot)this.playerEntity.craftingInventory.inventorySlots.get(var4)).getStack()); 882 } 883 884 this.playerEntity.sendContainerAndContentsToPlayer(this.playerEntity.craftingInventory, var3); 885 } 886 } 887 } 888 889 public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem) 890 { 891 if (this.playerEntity.craftingInventory.windowId == par1Packet108EnchantItem.windowId && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity)) 892 { 893 this.playerEntity.craftingInventory.enchantItem(this.playerEntity, par1Packet108EnchantItem.enchantment); 894 this.playerEntity.craftingInventory.updateCraftingResults(); 895 } 896 } 897 898 /** 899 * Handle a creative slot packet. 900 */ 901 public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot) 902 { 903 if (this.playerEntity.theItemInWorldManager.isCreative()) 904 { 905 boolean var2 = par1Packet107CreativeSetSlot.slot < 0; 906 ItemStack var3 = par1Packet107CreativeSetSlot.itemStack; 907 boolean var4 = par1Packet107CreativeSetSlot.slot >= 1 && par1Packet107CreativeSetSlot.slot < 36 + InventoryPlayer.func_70451_h(); 908 boolean var5 = var3 == null || var3.itemID < Item.itemsList.length && var3.itemID >= 0 && Item.itemsList[var3.itemID] != null; 909 boolean var6 = var3 == null || var3.getItemDamage() >= 0 && var3.getItemDamage() >= 0 && var3.stackSize <= 64 && var3.stackSize > 0; 910 911 if (var4 && var5 && var6) 912 { 913 if (var3 == null) 914 { 915 this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, (ItemStack)null); 916 } 917 else 918 { 919 this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, var3); 920 } 921 922 this.playerEntity.inventorySlots.setPlayerIsPresent(this.playerEntity, true); 923 } 924 else if (var2 && var5 && var6 && this.creativeItemCreationSpamThresholdTally < 200) 925 { 926 this.creativeItemCreationSpamThresholdTally += 20; 927 EntityItem var7 = this.playerEntity.dropPlayerItem(var3); 928 929 if (var7 != null) 930 { 931 var7.func_70288_d(); 932 } 933 } 934 } 935 } 936 937 public void handleTransaction(Packet106Transaction par1Packet106Transaction) 938 { 939 Short var2 = (Short)this.field_72586_s.lookup(this.playerEntity.craftingInventory.windowId); 940 941 if (var2 != null && par1Packet106Transaction.shortWindowId == var2.shortValue() && this.playerEntity.craftingInventory.windowId == par1Packet106Transaction.windowId && !this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity)) 942 { 943 this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, true); 944 } 945 } 946 947 /** 948 * Updates Client side signs 949 */ 950 public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign) 951 { 952 WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension); 953 954 if (var2.blockExists(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition)) 955 { 956 TileEntity var3 = var2.getBlockTileEntity(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition); 957 958 if (var3 instanceof TileEntitySign) 959 { 960 TileEntitySign var4 = (TileEntitySign)var3; 961 962 if (!var4.isEditable()) 963 { 964 this.mcServer.logWarning("Player " + this.playerEntity.username + " just tried to change non-editable sign"); 965 return; 966 } 967 } 968 969 int var6; 970 int var8; 971 972 for (var8 = 0; var8 < 4; ++var8) 973 { 974 boolean var5 = true; 975 976 if (par1Packet130UpdateSign.signLines[var8].length() > 15) 977 { 978 var5 = false; 979 } 980 else 981 { 982 for (var6 = 0; var6 < par1Packet130UpdateSign.signLines[var8].length(); ++var6) 983 { 984 if (ChatAllowedCharacters.allowedCharacters.indexOf(par1Packet130UpdateSign.signLines[var8].charAt(var6)) < 0) 985 { 986 var5 = false; 987 } 988 } 989 } 990 991 if (!var5) 992 { 993 par1Packet130UpdateSign.signLines[var8] = "!?"; 994 } 995 } 996 997 if (var3 instanceof TileEntitySign) 998 { 999 var8 = par1Packet130UpdateSign.xPosition; 1000 int var9 = par1Packet130UpdateSign.yPosition; 1001 var6 = par1Packet130UpdateSign.zPosition; 1002 TileEntitySign var7 = (TileEntitySign)var3; 1003 System.arraycopy(par1Packet130UpdateSign.signLines, 0, var7.signText, 0, 4); 1004 var7.onInventoryChanged(); 1005 var2.markBlockNeedsUpdate(var8, var9, var6); 1006 } 1007 } 1008 } 1009 1010 /** 1011 * Handle a keep alive packet. 1012 */ 1013 public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive) 1014 { 1015 if (par1Packet0KeepAlive.randomId == this.keepAliveRandomID) 1016 { 1017 int var2 = (int)(System.nanoTime() / 1000000L - this.keepAliveTimeSent); 1018 this.playerEntity.ping = (this.playerEntity.ping * 3 + var2) / 4; 1019 } 1020 } 1021 1022 /** 1023 * determine if it is a server handler 1024 */ 1025 public boolean isServerHandler() 1026 { 1027 return true; 1028 } 1029 1030 /** 1031 * Handle a player abilities packet. 1032 */ 1033 public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities) 1034 { 1035 this.playerEntity.capabilities.isFlying = par1Packet202PlayerAbilities.getFlying() && this.playerEntity.capabilities.allowFlying; 1036 } 1037 1038 public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete) 1039 { 1040 StringBuilder var2 = new StringBuilder(); 1041 String var4; 1042 1043 for (Iterator var3 = this.mcServer.getPossibleCompletions(this.playerEntity, par1Packet203AutoComplete.getText()).iterator(); var3.hasNext(); var2.append(var4)) 1044 { 1045 var4 = (String)var3.next(); 1046 1047 if (var2.length() > 0) 1048 { 1049 var2.append("\u0000"); 1050 } 1051 } 1052 1053 this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet203AutoComplete(var2.toString())); 1054 } 1055 1056 public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo) 1057 { 1058 this.playerEntity.updateClientInfo(par1Packet204ClientInfo); 1059 } 1060 1061 public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload) 1062 { 1063 FMLNetworkHandler.handlePacket250Packet(par1Packet250CustomPayload, netManager, this); 1064 } 1065 1066 public void handleVanilla250Packet(Packet250CustomPayload par1Packet250CustomPayload) 1067 { 1068 DataInputStream var2; 1069 ItemStack var3; 1070 ItemStack var4; 1071 1072 if ("MC|BEdit".equals(par1Packet250CustomPayload.channel)) 1073 { 1074 try 1075 { 1076 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1077 var3 = Packet.readItemStack(var2); 1078 1079 if (!ItemWritableBook.validBookTagPages(var3.getTagCompound())) 1080 { 1081 throw new IOException("Invalid book tag!"); 1082 } 1083 1084 var4 = this.playerEntity.inventory.getCurrentItem(); 1085 1086 if (var3 != null && var3.itemID == Item.writableBook.shiftedIndex && var3.itemID == var4.itemID) 1087 { 1088 var4.setTagCompound(var3.getTagCompound()); 1089 } 1090 } 1091 catch (Exception var7) 1092 { 1093 var7.printStackTrace(); 1094 } 1095 } 1096 else if ("MC|BSign".equals(par1Packet250CustomPayload.channel)) 1097 { 1098 try 1099 { 1100 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1101 var3 = Packet.readItemStack(var2); 1102 1103 if (!ItemEditableBook.validBookTagContents(var3.getTagCompound())) 1104 { 1105 throw new IOException("Invalid book tag!"); 1106 } 1107 1108 var4 = this.playerEntity.inventory.getCurrentItem(); 1109 1110 if (var3 != null && var3.itemID == Item.writtenBook.shiftedIndex && var4.itemID == Item.writableBook.shiftedIndex) 1111 { 1112 var4.setTagCompound(var3.getTagCompound()); 1113 var4.itemID = Item.writtenBook.shiftedIndex; 1114 } 1115 } 1116 catch (Exception var6) 1117 { 1118 var6.printStackTrace(); 1119 } 1120 } 1121 else if ("MC|TrSel".equals(par1Packet250CustomPayload.channel)) 1122 { 1123 try 1124 { 1125 var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data)); 1126 int var8 = var2.readInt(); 1127 Container var9 = this.playerEntity.craftingInventory; 1128 1129 if (var9 instanceof ContainerMerchant) 1130 { 1131 ((ContainerMerchant)var9).setCurrentRecipeIndex(var8); 1132 } 1133 } 1134 catch (Exception var5) 1135 { 1136 var5.printStackTrace(); 1137 } 1138 } 1139 } 1140 1141 @Override 1142 1143 /** 1144 * Contains logic for handling packets containing arbitrary unique item data. Currently this is only for maps. 1145 */ 1146 public void handleMapData(Packet131MapData par1Packet131MapData) 1147 { 1148 FMLNetworkHandler.handlePacket131Packet(this, par1Packet131MapData); 1149 } 1150 1151 // modloader compat -- yuk! 1152 @Override 1153 public EntityPlayerMP getPlayer() 1154 { 1155 return playerEntity; 1156 } 1157 }