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