Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 680 lines 26 kB view raw
1package net.minecraft.server; 2 3import java.util.ArrayList; 4import java.util.HashMap; 5import java.util.HashSet; 6import java.util.Iterator; 7import java.util.LinkedList; 8import java.util.List; 9import java.util.Set; 10import java.util.UUID; 11 12import org.bukkit.Bukkit; 13import org.bukkit.craftbukkit.ChunkCompressionThread; 14import org.bukkit.craftbukkit.CraftWorld; 15import org.bukkit.craftbukkit.inventory.CraftItemStack; 16import org.bukkit.entity.Player; 17import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; 18import org.bukkit.event.inventory.ChestOpenedEvent; 19 20import com.legacyminecraft.poseidon.PoseidonConfig; 21import com.legacyminecraft.poseidon.event.PlayerDeathEvent; 22import com.projectposeidon.api.PoseidonUUID; 23 24import me.devcody.uberbukkit.math.Vec3i; 25import uk.betacraft.uberbukkit.UberbukkitConfig; 26import uk.betacraft.uberbukkit.alpha.inventory.ProcessPacket5; 27import uk.betacraft.uberbukkit.packet.Packet62Sound; 28import uk.betacraft.uberbukkit.protocol.Protocol; 29 30// CraftBukkit start 31 32public class EntityPlayer extends EntityHuman implements ICrafting { 33 34 public NetServerHandler netServerHandler; 35 public MinecraftServer b; 36 public ItemInWorldManager itemInWorldManager; 37 public double d; 38 public double e; 39 public List chunkCoordIntPairQueue = new LinkedList(); 40 public Set playerChunkCoordIntPairs = new HashSet(); 41 public final List removeQueue = new LinkedList(); // poseidon 42 private int bL = -99999999; 43 private int bM = 60; 44 private ItemStack[] bN = new ItemStack[] { null, null, null, null, null }; 45 private int bO = 0; 46 public boolean h; 47 // uberbukkit 48 public Protocol protocol; 49 public ProcessPacket5 packet5; 50 public boolean isInWorkbench = false; // uberbukkit pvn < 7 51 52 public EntityPlayer(MinecraftServer minecraftserver, World world, String s, ItemInWorldManager iteminworldmanager, int pvn) { 53 super(world); 54 this.packet5 = new ProcessPacket5(this); // uberbukkit 55 this.protocol = Protocol.getProtocolClass(pvn); // uberbukkit 56 iteminworldmanager.player = this; 57 this.itemInWorldManager = iteminworldmanager; 58 ChunkCoordinates chunkcoordinates = world.getSpawn(); 59 int i = chunkcoordinates.x; 60 int j = chunkcoordinates.z; 61 int k = chunkcoordinates.y; 62 63 if (!world.worldProvider.e) { 64 k = world.f(i, j); //Project Poseidon: This finds a solid block, this needs to be left outside of the setting 65 if ((boolean) PoseidonConfig.getInstance().getProperty("world-settings.randomize-spawn")) { //Project Poseidon: Moved randomizing X and Y axis into a config option 66 i += this.random.nextInt(20) - 10; 67 j += this.random.nextInt(20) - 10; 68 } 69 } 70 71 this.setPositionRotation((double) i + 0.5D, (double) k, (double) j + 0.5D, 0.0F, 0.0F); 72 this.b = minecraftserver; 73 this.bs = 0.0F; 74 this.name = s; 75 this.height = 0.0F; 76 77 // CraftBukkit start 78 this.displayName = this.name; 79 this.playerUUID = PoseidonUUID.getPlayerGracefulUUID(this.name); //Project Poseidon 80 } 81 82 public String displayName; 83 public UUID playerUUID; //Project Poseidon 84 public org.bukkit.Location compassTarget; 85 // CraftBukkit end 86 87 public void spawnIn(World world) { 88 super.spawnIn(world); 89 // CraftBukkit - world fallback code, either respawn location or global spawn 90 if (world == null) { 91 this.dead = false; 92 ChunkCoordinates position = null; 93 if (this.spawnWorld != null && !this.spawnWorld.equals("")) { 94 CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld); 95 if (cworld != null && this.getBed() != null) { 96 world = cworld.getHandle(); 97 position = EntityHuman.getBed(cworld.getHandle(), this.getBed()); 98 } 99 } 100 if (world == null || position == null) { 101 world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); 102 position = world.getSpawn(); 103 } 104 this.world = world; 105 this.setPosition(position.x + 0.5, position.y, position.z + 0.5); 106 } 107 this.dimension = ((WorldServer) this.world).dimension; 108 // CraftBukkit end 109 this.itemInWorldManager = new ItemInWorldManager((WorldServer) world); 110 this.itemInWorldManager.player = this; 111 } 112 113 public void syncInventory() { 114 if (this.netServerHandler.networkManager.pvn <= 6) { 115 this.netServerHandler.refreshInventory(); 116 } 117 this.activeContainer.a((ICrafting) this); 118 } 119 120 public ItemStack[] getEquipment() { 121 return this.bN; 122 } 123 124 protected void s() { 125 this.height = 0.0F; 126 } 127 128 public float t() { 129 return 1.62F; 130 } 131 132 public void m_() { 133 this.itemInWorldManager.a(); 134 --this.bM; 135 this.activeContainer.a(); 136 137 for (int i = 0; i < 5; ++i) { 138 ItemStack itemstack = this.c_(i); 139 140 if (itemstack != this.bN[i]) { 141 this.b.getTracker(this.dimension).a(this, new Packet5EntityEquipment(this.id, i, itemstack)); 142 this.bN[i] = itemstack; 143 } 144 } 145 } 146 147 public ItemStack c_(int i) { 148 return i == 0 ? this.inventory.getItemInHand() : this.inventory.armor[i - 1]; 149 } 150 151 public void die(Entity entity) { 152 // CraftBukkit start 153 java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(); 154 155 for (int i = 0; i < this.inventory.items.length; ++i) { 156 if (this.inventory.items[i] != null) { 157 loot.add(new CraftItemStack(this.inventory.items[i])); 158 } 159 } 160 161 for (int i = 0; i < this.inventory.armor.length; ++i) { 162 if (this.inventory.armor[i] != null) { 163 loot.add(new CraftItemStack(this.inventory.armor[i])); 164 } 165 } 166 167 // uberbukkit 168 ArrayList<ItemStack> queue = this.packet5.queue.dropAllQueue(); 169 for (ItemStack item : queue) { 170 loot.add(new CraftItemStack(item)); 171 } 172 173 org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); 174 CraftWorld bworld = this.world.getWorld(); 175 176 PlayerDeathEvent event = new PlayerDeathEvent(bukkitEntity, loot); 177 this.world.getServer().getPluginManager().callEvent(event); 178 179 if (event.getDeathMessage() != null && !event.getDeathMessage().trim().isEmpty()) { 180 this.b.serverConfigurationManager.sendAll(new Packet3Chat(event.getDeathMessage())); 181 } 182 183 // CraftBukkit - we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. 184 185 //Poseidon - Only clear inventory if keep inventory is false 186 if (!event.getKeepInventory()) { 187 for (int i = 0; i < this.inventory.items.length; ++i) { 188 this.inventory.items[i] = null; 189 } 190 191 for (int i = 0; i < this.inventory.armor.length; ++i) { 192 this.inventory.armor[i] = null; 193 } 194 } 195 196 for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { 197 bworld.dropItemNaturally(bukkitEntity.getLocation(), stack); 198 } 199 200 this.y(); 201 // CraftBukkit end 202 } 203 204 public boolean damageEntity(Entity entity, int i) { 205 if (this.bM > 0) { 206 return false; 207 } else { 208 // CraftBukkit - this.b.pvpMode -> this.world.pvpMode 209 if (!this.world.pvpMode) { 210 if (entity instanceof EntityHuman) { 211 return false; 212 } 213 214 if (entity instanceof EntityArrow) { 215 EntityArrow entityarrow = (EntityArrow) entity; 216 217 if (entityarrow.shooter instanceof EntityHuman) { 218 return false; 219 } 220 } 221 } 222 223 return super.damageEntity(entity, i); 224 } 225 } 226 227 protected boolean j_() { 228 return this.b.pvpMode; 229 } 230 231 public void b(int i) { 232 super.b(i, RegainReason.EATING); 233 } 234 235 public WorldServer getWorldServer() { 236 return (WorldServer) this.world; 237 } 238 239 public void a(boolean flag) { 240 super.m_(); 241 242 // Poseidon start 243 while (!this.removeQueue.isEmpty()) { 244 int i = Math.min(this.removeQueue.size(), 127); 245 int[] aint = new int[i]; 246 Iterator iterator = this.removeQueue.iterator(); 247 int j = 0; 248 249 while (iterator.hasNext() && j < i) { 250 aint[j++] = ((Integer) iterator.next()).intValue(); 251 iterator.remove(); 252 } 253 254 for (int k = 0; k < aint.length; k++) { // cant use array since not supported in b1.7.3 255 this.netServerHandler.sendPacket(new Packet29DestroyEntity(aint[k])); 256 } 257 } 258 // poseidon end 259 260 for (int i = 0; i < this.inventory.getSize(); ++i) { 261 ItemStack itemstack = this.inventory.getItem(i); 262 263 if (itemstack != null && Item.byId[itemstack.id].b() && this.netServerHandler.b() <= 2) { 264 Packet packet = ((ItemWorldMapBase) Item.byId[itemstack.id]).b(itemstack, this.world, this); 265 266 if (packet != null) { 267 this.netServerHandler.sendPacket(packet); 268 } 269 } 270 } 271 272 // Poseidon start 273 if (flag && !this.chunkCoordIntPairQueue.isEmpty()) { 274 if (PoseidonConfig.getInstance().getBoolean("settings.faster-packets.enabled", true)) { 275 ArrayList arraylist = new ArrayList(); 276 Iterator iterator1 = this.chunkCoordIntPairQueue.iterator(); 277 ArrayList arraylist1 = new ArrayList(); 278 279 while (iterator1.hasNext() && arraylist.size() < 5) { 280 ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator1.next(); 281 282 iterator1.remove(); 283 if (chunkcoordintpair != null && this.world.isLoaded(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)) { 284 // CraftBukkit start - Get tile entities directly from the chunk instead of the world 285 Chunk chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z); 286 arraylist.add(chunk); 287 arraylist1.addAll(chunk.tileEntities.values()); 288 // CraftBukkit end 289 } 290 } 291 292 if (!arraylist.isEmpty()) { 293 Iterator iterator2 = arraylist.iterator(); 294 295 while (iterator2.hasNext()) { 296 Chunk chunk = (Chunk) iterator2.next(); 297 298 this.netServerHandler.sendPacket(new Packet51MapChunk(chunk.x * 16, 0, chunk.z * 16, 16, 128, 16, this.getWorldServer())); 299 this.getWorldServer().tracker.a(this, chunk); 300 } 301 302 iterator2 = arraylist1.iterator(); 303 304 while (iterator2.hasNext()) { 305 TileEntity tileentity = (TileEntity) iterator2.next(); 306 307 this.a(tileentity); 308 } 309 } 310 } else { 311 ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) this.chunkCoordIntPairQueue.get(0); 312 313 if (chunkcoordintpair != null) { 314 boolean flag1 = false; 315 316 if (this.netServerHandler.b() + ChunkCompressionThread.getPlayerQueueSize(this) < 4) { // CraftBukkit - Add check against Chunk Packets in the ChunkCompressionThread. 317 flag1 = true; 318 } 319 320 if (flag1) { 321 WorldServer worldserver = this.b.getWorldServer(this.dimension); 322 323 this.chunkCoordIntPairQueue.remove(chunkcoordintpair); 324 this.netServerHandler.sendPacket(new Packet51MapChunk(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, 16, 128, 16, worldserver)); 325 326 Chunk chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z); 327 this.getWorldServer().tracker.a(this, chunk); 328 329 List list = worldserver.getTileEntities(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 128, chunkcoordintpair.z * 16 + 16); 330 331 for (int j = 0; j < list.size(); ++j) { 332 this.a((TileEntity) list.get(j)); 333 } 334 } 335 } 336 } 337 } 338 // Poseidon end 339 340 if (this.E) { 341 //if (this.b.propertyManager.getBoolean("allow-nether", true)) { // CraftBukkit 342 if (this.activeContainer != this.defaultContainer) { 343 this.y(); 344 } 345 346 if (this.vehicle != null) { 347 this.mount(this.vehicle); 348 } else { 349 // uberbukkit - play portal sound 350 if (this.F == 0.0F) { 351 ((WorldServer) this.world).server.serverConfigurationManager.sendPacketNearby(this, this.locX, this.locY, this.locZ, 64D, this.dimension, new Packet62Sound("portal.trigger", this.locX, this.locY, this.locZ, 1.0F, this.random.nextFloat() * 0.4F + 0.8F)); 352 } 353 354 this.F += 0.0125F; 355 if (this.F >= 1.0F) { 356 this.F = 1.0F; 357 this.D = 10; 358 359 // uberbukkit 360 ((WorldServer) this.world).server.serverConfigurationManager.sendPacketNearby(this, this.locX, this.locY, this.locZ, 64D, this.dimension, new Packet62Sound("portal.travel", this.locX, this.locY, this.locZ, 1.0F, this.random.nextFloat() * 0.4F + 0.8F)); 361 362 this.b.serverConfigurationManager.f(this); 363 } 364 } 365 366 this.E = false; 367 //} // CraftBukkit 368 } else { 369 if (this.F > 0.0F) { 370 this.F -= 0.05F; 371 } 372 373 if (this.F < 0.0F) { 374 this.F = 0.0F; 375 } 376 } 377 378 if (this.D > 0) { 379 --this.D; 380 } 381 382 if (this.health != this.bL) { 383 this.netServerHandler.sendPacket(new Packet8UpdateHealth(this.health)); 384 this.bL = this.health; 385 } 386 } 387 388 private void a(TileEntity tileentity) { 389 if (tileentity != null) { 390 Packet packet = tileentity.f(); 391 392 if (packet != null) { 393 this.netServerHandler.sendPacket(packet); 394 } 395 } 396 } 397 398 public void v() { 399 super.v(); 400 } 401 402 public void receive(Entity entity, int i) { 403 if (!entity.dead) { 404 EntityTracker entitytracker = this.b.getTracker(this.dimension); 405 406 if (entity instanceof EntityItem) { 407 entitytracker.a(entity, new Packet22Collect(entity.id, this.id)); 408 } 409 410 if (entity instanceof EntityArrow) { 411 entitytracker.a(entity, new Packet22Collect(entity.id, this.id)); 412 } 413 } 414 415 super.receive(entity, i); 416 this.activeContainer.a(); 417 } 418 419 public void w() { 420 if (!this.p) { 421 this.q = -1; 422 this.p = true; 423 EntityTracker entitytracker = this.b.getTracker(this.dimension); 424 425 entitytracker.a(this, new Packet18ArmAnimation(this, 1)); 426 } 427 } 428 429 public void x() { 430 } 431 432 public EnumBedError a(int i, int j, int k) { 433 EnumBedError enumbederror = super.a(i, j, k); 434 435 if (enumbederror == EnumBedError.OK) { 436 EntityTracker entitytracker = this.b.getTracker(this.dimension); 437 Packet17 packet17 = new Packet17(this, 0, i, j, k); 438 439 entitytracker.a(this, packet17); 440 441 // uberbukkit - beds (b1.3 - b1.6.4) 442 if (!UberbukkitConfig.getInstance().getBoolean("mechanics.beds_pre_b1_6_5", false)) 443 this.netServerHandler.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); 444 445 this.netServerHandler.sendPacket(packet17); 446 } 447 448 return enumbederror; 449 } 450 451 public void a(boolean flag, boolean flag1, boolean flag2) { 452 if (this.isSleeping()) { 453 EntityTracker entitytracker = this.b.getTracker(this.dimension); 454 455 entitytracker.sendPacketToEntity(this, new Packet18ArmAnimation(this, 3)); 456 } 457 458 super.a(flag, flag1, flag2); 459 if (this.netServerHandler != null) { 460 this.netServerHandler.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); 461 } 462 } 463 464 public void mount(Entity entity) { 465 // CraftBukkit start 466 this.setPassengerOf(entity); 467 } 468 469 public void setPassengerOf(Entity entity) { 470 // mount(null) doesn't really fly for overloaded methods, 471 // so this method is needed 472 473 super.setPassengerOf(entity); 474 // CraftBukkit end 475 476 this.netServerHandler.sendPacket(new Packet39AttachEntity(this, this.vehicle)); 477 this.netServerHandler.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); 478 } 479 480 protected void a(double d0, boolean flag) { 481 } 482 483 public void b(double d0, boolean flag) { 484 super.a(d0, flag); 485 } 486 487 private void ai() { 488 this.bO = this.bO % 100 + 1; 489 } 490 491 public void b(int i, int j, int k) { 492 this.ai(); 493 this.netServerHandler.sendPacket(new Packet100OpenWindow(this.bO, 1, "Crafting", 9)); 494 this.activeContainer = new ContainerWorkbench(this.inventory, this.world, i, j, k); 495 this.activeContainer.setPosition(new Vec3i(i, j, k)); 496 this.activeContainer.windowId = this.bO; 497 this.activeContainer.a((ICrafting) this); 498 } 499 500 public void a(IInventory iinventory) { 501 this.ai(); 502 503 // Poseidon start 504 ChestOpenedEvent event = new ChestOpenedEvent((org.bukkit.entity.Player) this.getBukkitEntity(), iinventory.getContents()); 505 this.world.getServer().getPluginManager().callEvent(event); 506 if (event.isCancelled()) return; 507 // Poseidon end 508 509 this.netServerHandler.sendPacket(new Packet100OpenWindow(this.bO, 0, iinventory.getName(), iinventory.getSize())); 510 this.activeContainer = new ContainerChest(this.inventory, iinventory); 511 this.activeContainer.windowId = this.bO; 512 this.activeContainer.a((ICrafting) this); 513 } 514 515 public void a(IInventory iinventory, Vec3i position) { 516 this.ai(); 517 518 this.netServerHandler.sendPacket(new Packet100OpenWindow(this.bO, 0, iinventory.getName(), iinventory.getSize())); 519 this.activeContainer = new ContainerChest(this.inventory, iinventory); 520 this.activeContainer.setPosition(position); 521 this.activeContainer.windowId = this.bO; 522 this.activeContainer.a((ICrafting) this); 523 } 524 525 public void a(TileEntityFurnace tileentityfurnace) { 526 this.ai(); 527 this.netServerHandler.sendPacket(new Packet100OpenWindow(this.bO, 2, tileentityfurnace.getName(), tileentityfurnace.getSize())); 528 this.activeContainer = new ContainerFurnace(this.inventory, tileentityfurnace); 529 this.activeContainer.setPosition(new Vec3i(tileentityfurnace.x, tileentityfurnace.y, tileentityfurnace.z)); 530 this.activeContainer.windowId = this.bO; 531 this.activeContainer.a((ICrafting) this); 532 } 533 534 public void a(TileEntityDispenser tileentitydispenser) { 535 this.ai(); 536 this.netServerHandler.sendPacket(new Packet100OpenWindow(this.bO, 3, tileentitydispenser.getName(), tileentitydispenser.getSize())); 537 this.activeContainer = new ContainerDispenser(this.inventory, tileentitydispenser); 538 this.activeContainer.setPosition(new Vec3i(tileentitydispenser.x, tileentitydispenser.y, tileentitydispenser.z)); 539 this.activeContainer.windowId = this.bO; 540 this.activeContainer.a((ICrafting) this); 541 } 542 543 public void a(Container container, int i, ItemStack itemstack) { 544 if (!(container.b(i) instanceof SlotResult)) { 545 if (!this.h) { 546 // uberbukkit 547 if (this.netServerHandler.networkManager.pvn <= 6) { 548 this.netServerHandler.refreshInventory(); 549 //this.netServerHandler.sendPacket(new Packet5EntityEquipment(-1, this.inventory.items)); 550 //this.netServerHandler.sendPacket(new Packet5EntityEquipment(-2, this.inventory.craft)); 551 //this.netServerHandler.sendPacket(new Packet5EntityEquipment(-3, this.inventory.armor)); 552 } else { 553 this.netServerHandler.sendPacket(new Packet103SetSlot(container.windowId, i, itemstack)); 554 } 555 } 556 } 557 } 558 559 public void updateInventory(Container container) { 560 this.a(container, container.b()); 561 } 562 563 public void a(Container container, List list) { 564 // uberbukkit 565 if (this.netServerHandler.networkManager.pvn <= 6) { 566 this.netServerHandler.refreshInventory(); 567 } else { 568 this.netServerHandler.sendPacket(new Packet104WindowItems(container.windowId, list)); 569 this.netServerHandler.sendPacket(new Packet103SetSlot(-1, -1, this.inventory.j())); 570 } 571 } 572 573 public void a(Container container, int i, int j) { 574 this.netServerHandler.sendPacket(new Packet105CraftProgressBar(container.windowId, i, j)); 575 } 576 577 public void a(ItemStack itemstack) { 578 } 579 580 public void y() { 581 this.netServerHandler.sendPacket(new Packet101CloseWindow(this.activeContainer.windowId)); 582 this.A(); 583 } 584 585 public void z() { 586 if (!this.h) { 587 this.netServerHandler.sendPacket(new Packet103SetSlot(-1, -1, this.inventory.j())); 588 } 589 } 590 591 public void A() { 592 this.activeContainer.a((EntityHuman) this); 593 this.activeContainer = this.defaultContainer; 594 } 595 596 public void a(float f, float f1, boolean flag, boolean flag1, float f2, float f3) { 597 this.az = f; 598 this.aA = f1; 599 this.aC = flag; 600 this.setSneak(flag1); 601 this.pitch = f2; 602 this.yaw = f3; 603 } 604 605 public void a(Statistic statistic, int i) { 606 if (statistic != null) { 607 if (!statistic.g) { 608 while (i > 100) { 609 this.netServerHandler.sendPacket(new Packet200Statistic(statistic.e, 100)); 610 i -= 100; 611 } 612 613 this.netServerHandler.sendPacket(new Packet200Statistic(statistic.e, i)); 614 } 615 } 616 } 617 618 public void B() { 619 if (this.vehicle != null) { 620 this.mount(this.vehicle); 621 } 622 623 if (this.passenger != null) { 624 this.passenger.mount(this); 625 } 626 627 if (this.sleeping) { 628 this.a(true, false, false); 629 } 630 631 // uberbukkit - drop item queue on disconnect 632 if (this.netServerHandler.networkManager.pvn <= 6) { 633 ArrayList<ItemStack> queue = this.packet5.queue.dropAllQueue(); 634 Player bukkitEntity = (Player) this.getBukkitEntity(); 635 for (ItemStack item : queue) { 636 System.out.println("Drop queue id: " + item.id + ", dmg: " + item.damage + ", cnt: " + item.count); 637 HashMap<Integer, org.bukkit.inventory.ItemStack> map = bukkitEntity.getInventory().addItem(new CraftItemStack(item)); 638 // drop what couldn't fit in the inventory 639 for (org.bukkit.inventory.ItemStack stack : map.values()) { 640 bukkitEntity.getWorld().dropItemNaturally(bukkitEntity.getLocation(), stack); 641 } 642 } 643 } 644 } 645 646 public void C() { 647 this.bL = -99999999; 648 } 649 650 public void a(String s) { 651 // uberbukkit - fix for multiple bed alerts (b1.3 - b1.6.4) 652 if (this.netServerHandler.networkManager.pvn <= 11 || UberbukkitConfig.getInstance().getBoolean("mechanics.beds_pre_b1_6_5", false)) 653 return; 654 655 StatisticStorage statisticstorage = StatisticStorage.a(); 656 String s1 = statisticstorage.a(s); 657 658 this.netServerHandler.sendPacket(new Packet3Chat(s1)); 659 } 660 661 // CraftBukkit start 662 public long timeOffset = 0; 663 public boolean relativeTime = true; 664 665 public long getPlayerTime() { 666 if (this.relativeTime) { 667 // Adds timeOffset to the current server time. 668 return this.world.getTime() + this.timeOffset; 669 } else { 670 // Adds timeOffset to the beginning of this day. 671 return this.world.getTime() - (this.world.getTime() % 24000) + this.timeOffset; 672 } 673 } 674 675 @Override 676 public String toString() { 677 return super.toString() + "(" + this.name + " at " + this.locX + "," + this.locY + "," + this.locZ + ")"; 678 } 679 // CraftBukkit end 680}