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