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