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