001 package net.minecraft.src; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.DataOutputStream; 005 import java.io.IOException; 006 import java.util.ArrayList; 007 import java.util.Iterator; 008 import java.util.LinkedList; 009 import java.util.List; 010 import net.minecraft.server.MinecraftServer; 011 012 public class EntityPlayerMP extends EntityPlayer implements ICrafting 013 { 014 private StringTranslate translator = new StringTranslate("en_US"); 015 016 /** set by the NetServerHandler or the ServerConfigurationManager */ 017 public NetServerHandler serverForThisPlayer; 018 019 /** Reference to the MinecraftServer object. */ 020 public MinecraftServer mcServer; 021 022 /** The ItemInWorldManager belonging to this player */ 023 public ItemInWorldManager theItemInWorldManager; 024 025 /** player X position as seen by PlayerManager */ 026 public double managedPosX; 027 028 /** player Z position as seen by PlayerManager */ 029 public double managedPosZ; 030 public final List chunksToLoad = new LinkedList(); 031 032 /** entities added to this list will be packet29'd to the player */ 033 public final List destroyedItemsNetCache = new LinkedList(); 034 035 /** set to getHealth */ 036 private int lastHealth = -99999999; 037 038 /** set to foodStats.GetFoodLevel */ 039 private int lastFoodLevel = -99999999; 040 041 /** set to foodStats.getSaturationLevel() == 0.0F each tick */ 042 private boolean wasHungry = true; 043 044 /** Amount of experience the client was last set to */ 045 private int lastExperience = -99999999; 046 047 /** de-increments onUpdate, attackEntityFrom is ignored if this >0 */ 048 private int initialInvulnerability = 60; 049 050 /** must be between 3>x>15 (strictly between) */ 051 private int renderDistance = 0; 052 private int chatVisibility = 0; 053 private boolean chatColours = true; 054 055 /** 056 * 0 is the held item, 1-4 is armor ; used to detect changes in getCurrentItemOrArmor 057 */ 058 private ItemStack[] lastActiveItems = new ItemStack[] {null, null, null, null, null}; 059 060 /** 061 * The currently in use window ID. Incremented every time a window is opened. 062 */ 063 public int currentWindowId = 0; 064 065 /** 066 * poor mans concurency flag, lets hope the jvm doesn't re-order the setting of this flag wrt the inventory change 067 * on the next line 068 */ 069 public boolean playerInventoryBeingManipulated; 070 public int ping; 071 072 /** set to true when the player is leaving the End after success. */ 073 public boolean playerHasConqueredTheEnd = false; 074 075 public EntityPlayerMP(MinecraftServer par1MinecraftServer, World par2World, String par3Str, ItemInWorldManager par4ItemInWorldManager) 076 { 077 super(par2World); 078 par4ItemInWorldManager.thisPlayerMP = this; 079 this.theItemInWorldManager = par4ItemInWorldManager; 080 this.renderDistance = par1MinecraftServer.getConfigurationManager().getViewDistance(); 081 ChunkCoordinates var5 = par2World.getSpawnPoint(); 082 int var6 = var5.posX; 083 int var7 = var5.posZ; 084 int var8 = var5.posY; 085 086 if (!par2World.provider.hasNoSky && par2World.getWorldInfo().getGameType() != EnumGameType.ADVENTURE) 087 { 088 var6 += this.rand.nextInt(20) - 10; 089 var8 = par2World.getTopSolidOrLiquidBlock(var6, var7); 090 var7 += this.rand.nextInt(20) - 10; 091 } 092 093 this.setLocationAndAngles((double)var6 + 0.5D, (double)var8, (double)var7 + 0.5D, 0.0F, 0.0F); 094 this.mcServer = par1MinecraftServer; 095 this.stepHeight = 0.0F; 096 this.username = par3Str; 097 this.yOffset = 0.0F; 098 } 099 100 /** 101 * (abstract) Protected helper method to read subclass entity data from NBT. 102 */ 103 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 104 { 105 super.readEntityFromNBT(par1NBTTagCompound); 106 107 if (par1NBTTagCompound.hasKey("playerGameType")) 108 { 109 this.theItemInWorldManager.setGameType(EnumGameType.getByID(par1NBTTagCompound.getInteger("playerGameType"))); 110 } 111 } 112 113 /** 114 * (abstract) Protected helper method to write subclass entity data to NBT. 115 */ 116 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 117 { 118 super.writeEntityToNBT(par1NBTTagCompound); 119 par1NBTTagCompound.setInteger("playerGameType", this.theItemInWorldManager.getGameType().getID()); 120 } 121 122 /** 123 * Decrease the player level, used to pay levels for enchantments on items at enchanted table. 124 */ 125 public void removeExperience(int par1) 126 { 127 super.removeExperience(par1); 128 this.lastExperience = -1; 129 } 130 131 public void addSelfToInternalCraftingInventory() 132 { 133 this.craftingInventory.addCraftingToCrafters(this); 134 } 135 136 public ItemStack[] getLastActiveItems() 137 { 138 return this.lastActiveItems; 139 } 140 141 /** 142 * sets the players height back to normal after doing things like sleeping and dieing 143 */ 144 protected void resetHeight() 145 { 146 this.yOffset = 0.0F; 147 } 148 149 public float getEyeHeight() 150 { 151 return 1.62F; 152 } 153 154 /** 155 * Called to update the entity's position/logic. 156 */ 157 public void onUpdate() 158 { 159 this.theItemInWorldManager.updateBlockRemoving(); 160 --this.initialInvulnerability; 161 this.craftingInventory.updateCraftingResults(); 162 int var1; 163 164 for (var1 = 0; var1 < 5; ++var1) 165 { 166 ItemStack var2 = this.getCurrentItemOrArmor(var1); 167 168 if (var2 != this.lastActiveItems[var1]) 169 { 170 this.getServerForPlayer().getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, new Packet5PlayerInventory(this.entityId, var1, var2)); 171 this.lastActiveItems[var1] = var2; 172 } 173 } 174 175 if (!this.chunksToLoad.isEmpty()) 176 { 177 ArrayList var6 = new ArrayList(); 178 Iterator var7 = this.chunksToLoad.iterator(); 179 ArrayList var3 = new ArrayList(); 180 181 while (var7.hasNext() && var6.size() < 5) 182 { 183 ChunkCoordIntPair var4 = (ChunkCoordIntPair)var7.next(); 184 var7.remove(); 185 186 if (var4 != null && this.worldObj.blockExists(var4.chunkXPos << 4, 0, var4.chunkZPos << 4)) 187 { 188 var6.add(this.worldObj.getChunkFromChunkCoords(var4.chunkXPos, var4.chunkZPos)); 189 var3.addAll(((WorldServer)this.worldObj).getAllTileEntityInBox(var4.chunkXPos * 16, 0, var4.chunkZPos * 16, var4.chunkXPos * 16 + 16, 256, var4.chunkZPos * 16 + 16)); 190 } 191 } 192 193 if (!var6.isEmpty()) 194 { 195 this.serverForThisPlayer.sendPacketToPlayer(new Packet56MapChunks(var6)); 196 Iterator var10 = var3.iterator(); 197 198 while (var10.hasNext()) 199 { 200 TileEntity var5 = (TileEntity)var10.next(); 201 this.sendTileEntityToPlayer(var5); 202 } 203 } 204 } 205 206 if (!this.destroyedItemsNetCache.isEmpty()) 207 { 208 var1 = Math.min(this.destroyedItemsNetCache.size(), 127); 209 int[] var8 = new int[var1]; 210 Iterator var9 = this.destroyedItemsNetCache.iterator(); 211 int var11 = 0; 212 213 while (var9.hasNext() && var11 < var1) 214 { 215 var8[var11++] = ((Integer)var9.next()).intValue(); 216 var9.remove(); 217 } 218 219 this.serverForThisPlayer.sendPacketToPlayer(new Packet29DestroyEntity(var8)); 220 } 221 } 222 223 public void onUpdateEntity() 224 { 225 super.onUpdate(); 226 227 for (int var1 = 0; var1 < this.inventory.getSizeInventory(); ++var1) 228 { 229 ItemStack var2 = this.inventory.getStackInSlot(var1); 230 231 if (var2 != null && Item.itemsList[var2.itemID].isMap() && this.serverForThisPlayer.packetSize() <= 2) 232 { 233 Packet var3 = ((ItemMapBase)Item.itemsList[var2.itemID]).createMapDataPacket(var2, this.worldObj, this); 234 235 if (var3 != null) 236 { 237 this.serverForThisPlayer.sendPacketToPlayer(var3); 238 } 239 } 240 } 241 242 if (this.inPortal) 243 { 244 if (this.mcServer.getAllowNether()) 245 { 246 if (this.craftingInventory != this.inventorySlots) 247 { 248 this.closeScreen(); 249 } 250 251 if (this.ridingEntity != null) 252 { 253 this.mountEntity(this.ridingEntity); 254 } 255 else 256 { 257 this.timeInPortal += 0.0125F; 258 259 if (this.timeInPortal >= 1.0F) 260 { 261 this.timeInPortal = 1.0F; 262 this.timeUntilPortal = 10; 263 boolean var4 = false; 264 byte var5; 265 266 if (this.dimension == -1) 267 { 268 var5 = 0; 269 } 270 else 271 { 272 var5 = -1; 273 } 274 275 this.mcServer.getConfigurationManager().transferPlayerToDimension(this, var5); 276 this.lastExperience = -1; 277 this.lastHealth = -1; 278 this.lastFoodLevel = -1; 279 this.triggerAchievement(AchievementList.portal); 280 } 281 } 282 283 this.inPortal = false; 284 } 285 } 286 else 287 { 288 if (this.timeInPortal > 0.0F) 289 { 290 this.timeInPortal -= 0.05F; 291 } 292 293 if (this.timeInPortal < 0.0F) 294 { 295 this.timeInPortal = 0.0F; 296 } 297 } 298 299 if (this.timeUntilPortal > 0) 300 { 301 --this.timeUntilPortal; 302 } 303 304 if (this.getHealth() != this.lastHealth || this.lastFoodLevel != this.foodStats.getFoodLevel() || this.foodStats.getSaturationLevel() == 0.0F != this.wasHungry) 305 { 306 this.serverForThisPlayer.sendPacketToPlayer(new Packet8UpdateHealth(this.getHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel())); 307 this.lastHealth = this.getHealth(); 308 this.lastFoodLevel = this.foodStats.getFoodLevel(); 309 this.wasHungry = this.foodStats.getSaturationLevel() == 0.0F; 310 } 311 312 if (this.experienceTotal != this.lastExperience) 313 { 314 this.lastExperience = this.experienceTotal; 315 this.serverForThisPlayer.sendPacketToPlayer(new Packet43Experience(this.experience, this.experienceTotal, this.experienceLevel)); 316 } 317 } 318 319 /** 320 * 0 = item, 1-n is armor 321 */ 322 public ItemStack getCurrentItemOrArmor(int par1) 323 { 324 return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1]; 325 } 326 327 /** 328 * Called when the mob's health reaches 0. 329 */ 330 public void onDeath(DamageSource par1DamageSource) 331 { 332 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(par1DamageSource.getDeathMessage(this))); 333 this.inventory.dropAllItems(); 334 } 335 336 /** 337 * Called when the entity is attacked. 338 */ 339 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 340 { 341 if (this.initialInvulnerability > 0) 342 { 343 return false; 344 } 345 else 346 { 347 if (!this.mcServer.isPVPEnabled() && par1DamageSource instanceof EntityDamageSource) 348 { 349 Entity var3 = par1DamageSource.getEntity(); 350 351 if (var3 instanceof EntityPlayer) 352 { 353 return false; 354 } 355 356 if (var3 instanceof EntityArrow) 357 { 358 EntityArrow var4 = (EntityArrow)var3; 359 360 if (var4.shootingEntity instanceof EntityPlayer) 361 { 362 return false; 363 } 364 } 365 } 366 367 return super.attackEntityFrom(par1DamageSource, par2); 368 } 369 } 370 371 /** 372 * returns if pvp is enabled or not 373 */ 374 protected boolean isPVPEnabled() 375 { 376 return this.mcServer.isPVPEnabled(); 377 } 378 379 public void travelToTheEnd(int par1) 380 { 381 if (this.dimension == 1 && par1 == 1) 382 { 383 this.triggerAchievement(AchievementList.theEnd2); 384 this.worldObj.setEntityDead(this); 385 this.playerHasConqueredTheEnd = true; 386 this.serverForThisPlayer.sendPacketToPlayer(new Packet70GameEvent(4, 0)); 387 } 388 else 389 { 390 this.triggerAchievement(AchievementList.theEnd); 391 ChunkCoordinates var2 = this.mcServer.worldServerForDimension(par1).getEntrancePortalLocation(); 392 393 if (var2 != null) 394 { 395 this.serverForThisPlayer.setPlayerLocation((double)var2.posX, (double)var2.posY, (double)var2.posZ, 0.0F, 0.0F); 396 } 397 398 this.mcServer.getConfigurationManager().transferPlayerToDimension(this, 1); 399 this.lastExperience = -1; 400 this.lastHealth = -1; 401 this.lastFoodLevel = -1; 402 } 403 } 404 405 /** 406 * called from onUpdate for all tileEntity in specific chunks 407 */ 408 private void sendTileEntityToPlayer(TileEntity par1TileEntity) 409 { 410 if (par1TileEntity != null) 411 { 412 Packet var2 = par1TileEntity.getAuxillaryInfoPacket(); 413 414 if (var2 != null) 415 { 416 this.serverForThisPlayer.sendPacketToPlayer(var2); 417 } 418 } 419 } 420 421 /** 422 * Called whenever an item is picked up from walking over it. Args: pickedUpEntity, stackSize 423 */ 424 public void onItemPickup(Entity par1Entity, int par2) 425 { 426 if (!par1Entity.isDead) 427 { 428 EntityTracker var3 = this.getServerForPlayer().getEntityTracker(); 429 430 if (par1Entity instanceof EntityItem) 431 { 432 var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); 433 } 434 435 if (par1Entity instanceof EntityArrow) 436 { 437 var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); 438 } 439 440 if (par1Entity instanceof EntityXPOrb) 441 { 442 var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); 443 } 444 } 445 446 super.onItemPickup(par1Entity, par2); 447 this.craftingInventory.updateCraftingResults(); 448 } 449 450 /** 451 * Swings the item the player is holding. 452 */ 453 public void swingItem() 454 { 455 if (!this.isSwinging) 456 { 457 this.swingProgressInt = -1; 458 this.isSwinging = true; 459 this.getServerForPlayer().getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, new Packet18Animation(this, 1)); 460 } 461 } 462 463 /** 464 * Attempts to have the player sleep in a bed at the specified location. 465 */ 466 public EnumStatus sleepInBedAt(int par1, int par2, int par3) 467 { 468 EnumStatus var4 = super.sleepInBedAt(par1, par2, par3); 469 470 if (var4 == EnumStatus.OK) 471 { 472 Packet17Sleep var5 = new Packet17Sleep(this, 0, par1, par2, par3); 473 this.getServerForPlayer().getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, var5); 474 this.serverForThisPlayer.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); 475 this.serverForThisPlayer.sendPacketToPlayer(var5); 476 } 477 478 return var4; 479 } 480 481 /** 482 * Wake up the player if they're sleeping. 483 */ 484 public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) 485 { 486 if (this.isPlayerSleeping()) 487 { 488 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(this, 3)); 489 } 490 491 super.wakeUpPlayer(par1, par2, par3); 492 493 if (this.serverForThisPlayer != null) 494 { 495 this.serverForThisPlayer.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); 496 } 497 } 498 499 /** 500 * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. 501 */ 502 public void mountEntity(Entity par1Entity) 503 { 504 super.mountEntity(par1Entity); 505 this.serverForThisPlayer.sendPacketToPlayer(new Packet39AttachEntity(this, this.ridingEntity)); 506 this.serverForThisPlayer.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); 507 } 508 509 /** 510 * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance 511 * and deal fall damage if landing on the ground. Args: distanceFallenThisTick, onGround 512 */ 513 protected void updateFallState(double par1, boolean par3) {} 514 515 /** 516 * likeUpdateFallState, but called from updateFlyingState, rather than moveEntity 517 */ 518 public void updateFlyingState(double par1, boolean par3) 519 { 520 super.updateFallState(par1, par3); 521 } 522 523 public void incrementWindowID() 524 { 525 this.currentWindowId = this.currentWindowId % 100 + 1; 526 } 527 528 /** 529 * Displays the crafting GUI for a workbench. 530 */ 531 public void displayGUIWorkbench(int par1, int par2, int par3) 532 { 533 this.incrementWindowID(); 534 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 1, "Crafting", 9)); 535 this.craftingInventory = new ContainerWorkbench(this.inventory, this.worldObj, par1, par2, par3); 536 this.craftingInventory.windowId = this.currentWindowId; 537 this.craftingInventory.addCraftingToCrafters(this); 538 } 539 540 public void displayGUIEnchantment(int par1, int par2, int par3) 541 { 542 this.incrementWindowID(); 543 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 4, "Enchanting", 9)); 544 this.craftingInventory = new ContainerEnchantment(this.inventory, this.worldObj, par1, par2, par3); 545 this.craftingInventory.windowId = this.currentWindowId; 546 this.craftingInventory.addCraftingToCrafters(this); 547 } 548 549 /** 550 * Displays the GUI for interacting with a chest inventory. Args: chestInventory 551 */ 552 public void displayGUIChest(IInventory par1IInventory) 553 { 554 if (this.craftingInventory != this.inventorySlots) 555 { 556 this.closeScreen(); 557 } 558 559 this.incrementWindowID(); 560 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 0, par1IInventory.getInvName(), par1IInventory.getSizeInventory())); 561 this.craftingInventory = new ContainerChest(this.inventory, par1IInventory); 562 this.craftingInventory.windowId = this.currentWindowId; 563 this.craftingInventory.addCraftingToCrafters(this); 564 } 565 566 /** 567 * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace 568 */ 569 public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) 570 { 571 this.incrementWindowID(); 572 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 2, par1TileEntityFurnace.getInvName(), par1TileEntityFurnace.getSizeInventory())); 573 this.craftingInventory = new ContainerFurnace(this.inventory, par1TileEntityFurnace); 574 this.craftingInventory.windowId = this.currentWindowId; 575 this.craftingInventory.addCraftingToCrafters(this); 576 } 577 578 /** 579 * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser 580 */ 581 public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) 582 { 583 this.incrementWindowID(); 584 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 3, par1TileEntityDispenser.getInvName(), par1TileEntityDispenser.getSizeInventory())); 585 this.craftingInventory = new ContainerDispenser(this.inventory, par1TileEntityDispenser); 586 this.craftingInventory.windowId = this.currentWindowId; 587 this.craftingInventory.addCraftingToCrafters(this); 588 } 589 590 /** 591 * Displays the GUI for interacting with a brewing stand. 592 */ 593 public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) 594 { 595 this.incrementWindowID(); 596 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 5, par1TileEntityBrewingStand.getInvName(), par1TileEntityBrewingStand.getSizeInventory())); 597 this.craftingInventory = new ContainerBrewingStand(this.inventory, par1TileEntityBrewingStand); 598 this.craftingInventory.windowId = this.currentWindowId; 599 this.craftingInventory.addCraftingToCrafters(this); 600 } 601 602 public void displayGUIMerchant(IMerchant par1IMerchant) 603 { 604 this.incrementWindowID(); 605 this.craftingInventory = new ContainerMerchant(this.inventory, par1IMerchant, this.worldObj); 606 this.craftingInventory.windowId = this.currentWindowId; 607 this.craftingInventory.addCraftingToCrafters(this); 608 InventoryMerchant var2 = ((ContainerMerchant)this.craftingInventory).getMerchantInventory(); 609 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 6, var2.getInvName(), var2.getSizeInventory())); 610 MerchantRecipeList var3 = par1IMerchant.getRecipes(this); 611 612 if (var3 != null) 613 { 614 try 615 { 616 ByteArrayOutputStream var4 = new ByteArrayOutputStream(); 617 DataOutputStream var5 = new DataOutputStream(var4); 618 var5.writeInt(this.currentWindowId); 619 var3.writeRecipiesToStream(var5); 620 this.serverForThisPlayer.sendPacketToPlayer(new Packet250CustomPayload("MC|TrList", var4.toByteArray())); 621 } 622 catch (IOException var6) 623 { 624 var6.printStackTrace(); 625 } 626 } 627 } 628 629 /** 630 * inform the player of a change in a single slot 631 */ 632 public void updateCraftingInventorySlot(Container par1Container, int par2, ItemStack par3ItemStack) 633 { 634 if (!(par1Container.getSlot(par2) instanceof SlotCrafting)) 635 { 636 if (!this.playerInventoryBeingManipulated) 637 { 638 this.serverForThisPlayer.sendPacketToPlayer(new Packet103SetSlot(par1Container.windowId, par2, par3ItemStack)); 639 } 640 } 641 } 642 643 public void sendContainerToPlayer(Container par1Container) 644 { 645 this.sendContainerAndContentsToPlayer(par1Container, par1Container.getInventory()); 646 } 647 648 public void sendContainerAndContentsToPlayer(Container par1Container, List par2List) 649 { 650 this.serverForThisPlayer.sendPacketToPlayer(new Packet104WindowItems(par1Container.windowId, par2List)); 651 this.serverForThisPlayer.sendPacketToPlayer(new Packet103SetSlot(-1, -1, this.inventory.getItemStack())); 652 } 653 654 /** 655 * send information about the crafting inventory to the client(currently only for furnace times) 656 */ 657 public void updateCraftingInventoryInfo(Container par1Container, int par2, int par3) 658 { 659 this.serverForThisPlayer.sendPacketToPlayer(new Packet105UpdateProgressbar(par1Container.windowId, par2, par3)); 660 } 661 662 /** 663 * sets current screen to null (used on escape buttons of GUIs) 664 */ 665 public void closeScreen() 666 { 667 this.serverForThisPlayer.sendPacketToPlayer(new Packet101CloseWindow(this.craftingInventory.windowId)); 668 this.closeInventory(); 669 } 670 671 public void sendInventoryToPlayer() 672 { 673 if (!this.playerInventoryBeingManipulated) 674 { 675 this.serverForThisPlayer.sendPacketToPlayer(new Packet103SetSlot(-1, -1, this.inventory.getItemStack())); 676 } 677 } 678 679 public void closeInventory() 680 { 681 this.craftingInventory.onCraftGuiClosed(this); 682 this.craftingInventory = this.inventorySlots; 683 } 684 685 /** 686 * Adds a value to a statistic field. 687 */ 688 public void addStat(StatBase par1StatBase, int par2) 689 { 690 if (par1StatBase != null) 691 { 692 if (!par1StatBase.isIndependent) 693 { 694 while (par2 > 100) 695 { 696 this.serverForThisPlayer.sendPacketToPlayer(new Packet200Statistic(par1StatBase.statId, 100)); 697 par2 -= 100; 698 } 699 700 this.serverForThisPlayer.sendPacketToPlayer(new Packet200Statistic(par1StatBase.statId, par2)); 701 } 702 } 703 } 704 705 public void mountEntityAndWakeUp() 706 { 707 if (this.ridingEntity != null) 708 { 709 this.mountEntity(this.ridingEntity); 710 } 711 712 if (this.riddenByEntity != null) 713 { 714 this.riddenByEntity.mountEntity(this); 715 } 716 717 if (this.sleeping) 718 { 719 this.wakeUpPlayer(true, false, false); 720 } 721 } 722 723 /** 724 * this function is called when a players inventory is sent to him, lastHealth is updated on any dimension 725 * transitions, then reset. 726 */ 727 public void setPlayerHealthUpdated() 728 { 729 this.lastHealth = -99999999; 730 } 731 732 /** 733 * Add a chat message to the player 734 */ 735 public void addChatMessage(String par1Str) 736 { 737 StringTranslate var2 = StringTranslate.getInstance(); 738 String var3 = var2.translateKey(par1Str); 739 this.serverForThisPlayer.sendPacketToPlayer(new Packet3Chat(var3)); 740 } 741 742 /** 743 * Used for when item use count runs out, ie: eating completed 744 */ 745 protected void onItemUseFinish() 746 { 747 this.serverForThisPlayer.sendPacketToPlayer(new Packet38EntityStatus(this.entityId, (byte)9)); 748 super.onItemUseFinish(); 749 } 750 751 /** 752 * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration 753 */ 754 public void setItemInUse(ItemStack par1ItemStack, int par2) 755 { 756 super.setItemInUse(par1ItemStack, par2); 757 758 if (par1ItemStack != null && par1ItemStack.getItem() != null && par1ItemStack.getItem().getItemUseAction(par1ItemStack) == EnumAction.eat) 759 { 760 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(this, 5)); 761 } 762 } 763 764 protected void onNewPotionEffect(PotionEffect par1PotionEffect) 765 { 766 super.onNewPotionEffect(par1PotionEffect); 767 this.serverForThisPlayer.sendPacketToPlayer(new Packet41EntityEffect(this.entityId, par1PotionEffect)); 768 } 769 770 protected void onChangedPotionEffect(PotionEffect par1PotionEffect) 771 { 772 super.onChangedPotionEffect(par1PotionEffect); 773 this.serverForThisPlayer.sendPacketToPlayer(new Packet41EntityEffect(this.entityId, par1PotionEffect)); 774 } 775 776 protected void onFinishedPotionEffect(PotionEffect par1PotionEffect) 777 { 778 super.onFinishedPotionEffect(par1PotionEffect); 779 this.serverForThisPlayer.sendPacketToPlayer(new Packet42RemoveEntityEffect(this.entityId, par1PotionEffect)); 780 } 781 782 /** 783 * Move the entity to the coordinates informed, but keep yaw/pitch values. 784 */ 785 public void setPositionAndUpdate(double par1, double par3, double par5) 786 { 787 this.serverForThisPlayer.setPlayerLocation(par1, par3, par5, this.rotationYaw, this.rotationPitch); 788 } 789 790 /** 791 * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically 792 */ 793 public void onCriticalHit(Entity par1Entity) 794 { 795 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(par1Entity, 6)); 796 } 797 798 public void onEnchantmentCritical(Entity par1Entity) 799 { 800 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(par1Entity, 7)); 801 } 802 803 /** 804 * Sends the player's abilities to the server (if there is one). 805 */ 806 public void sendPlayerAbilities() 807 { 808 if (this.serverForThisPlayer != null) 809 { 810 this.serverForThisPlayer.sendPacketToPlayer(new Packet202PlayerAbilities(this.capabilities)); 811 } 812 } 813 814 public WorldServer getServerForPlayer() 815 { 816 return (WorldServer)this.worldObj; 817 } 818 819 public void sendGameTypeToPlayer(EnumGameType par1EnumGameType) 820 { 821 this.theItemInWorldManager.setGameType(par1EnumGameType); 822 this.serverForThisPlayer.sendPacketToPlayer(new Packet70GameEvent(3, par1EnumGameType.getID())); 823 } 824 825 public void sendChatToPlayer(String par1Str) 826 { 827 this.serverForThisPlayer.sendPacketToPlayer(new Packet3Chat(par1Str)); 828 } 829 830 /** 831 * Returns true if the command sender is allowed to use the given command. 832 */ 833 public boolean canCommandSenderUseCommand(String par1Str) 834 { 835 return "seed".equals(par1Str) && !this.mcServer.isDedicatedServer() ? true : (!"tell".equals(par1Str) && !"help".equals(par1Str) && !"me".equals(par1Str) ? this.mcServer.getConfigurationManager().areCommandsAllowed(this.username) : true); 836 } 837 838 public String func_71114_r() 839 { 840 String var1 = this.serverForThisPlayer.theNetworkManager.getSocketAddress().toString(); 841 var1 = var1.substring(var1.indexOf("/") + 1); 842 var1 = var1.substring(0, var1.indexOf(":")); 843 return var1; 844 } 845 846 public void updateClientInfo(Packet204ClientInfo par1Packet204ClientInfo) 847 { 848 if (this.translator.getLanguageList().containsKey(par1Packet204ClientInfo.getLanguage())) 849 { 850 this.translator.setLanguage(par1Packet204ClientInfo.getLanguage()); 851 } 852 853 int var2 = 256 >> par1Packet204ClientInfo.getRenderDistance(); 854 855 if (var2 > 3 && var2 < 15) 856 { 857 this.renderDistance = var2; 858 } 859 860 this.chatVisibility = par1Packet204ClientInfo.getChatVisibility(); 861 this.chatColours = par1Packet204ClientInfo.getChatColours(); 862 863 if (this.mcServer.isSinglePlayer() && this.mcServer.getServerOwner().equals(this.username)) 864 { 865 this.mcServer.setDifficultyForAllDimensions(par1Packet204ClientInfo.getDifficulty()); 866 } 867 } 868 869 public StringTranslate getTranslator() 870 { 871 return this.translator; 872 } 873 874 public int getChatVisibility() 875 { 876 return this.chatVisibility; 877 } 878 879 /** 880 * on recieving this message the client (if permission is given) will download the requested textures 881 */ 882 public void requestTexturePackLoad(String par1Str, int par2) 883 { 884 String var3 = par1Str + "\u0000" + par2; 885 this.serverForThisPlayer.sendPacketToPlayer(new Packet250CustomPayload("MC|TPack", var3.getBytes())); 886 } 887 }