Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
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}