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