Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import java.util.HashSet;
4import java.util.Iterator;
5import java.util.List;
6import java.util.Set;
7
8import org.bukkit.entity.Player;
9
10public class EntityTrackerEntry {
11
12 public Entity tracker;
13 // uberbukkit
14 public boolean b_ = false;
15 public boolean c_ = false;
16 public boolean d_ = false;
17
18 public int b;
19 public int c;
20 public int d;
21 public int e;
22 public int f;
23 public int g;
24 public int h;
25 public double i;
26 public double j;
27 public double k;
28 public int l = 0;
29 private double o;
30 private double p;
31 private double q;
32 private boolean r = false;
33 private boolean isMoving;
34 private int t = 0;
35 public boolean m = false;
36 public Set trackedPlayers = new HashSet();
37
38 public EntityTrackerEntry(Entity entity, int i, int j, boolean flag) {
39 this.tracker = entity;
40 this.b = i;
41 this.c = j;
42 this.isMoving = flag;
43 this.d = MathHelper.floor(entity.locX * 32.0D);
44 this.e = MathHelper.floor(entity.locY * 32.0D);
45 this.f = MathHelper.floor(entity.locZ * 32.0D);
46 this.g = MathHelper.d(entity.yaw * 256.0F / 360.0F);
47 this.h = MathHelper.d(entity.pitch * 256.0F / 360.0F);
48 }
49
50 public boolean equals(Object object) {
51 return object instanceof EntityTrackerEntry ? ((EntityTrackerEntry) object).tracker.id == this.tracker.id : false;
52 }
53
54 public int hashCode() {
55 return this.tracker.id;
56 }
57
58 public void track(List list) {
59 this.m = false;
60 if (!this.r || this.tracker.e(this.o, this.p, this.q) > 16.0D) {
61 this.o = this.tracker.locX;
62 this.p = this.tracker.locY;
63 this.q = this.tracker.locZ;
64 this.r = true;
65 this.m = true;
66 this.scanPlayers(list);
67 }
68
69 if (++this.l % this.c == 0 || this.tracker.airBorne || this.tracker.aa().a()) {
70 ++this.t; // Poseidon - moved below
71
72 // encoded means multiplied by 32
73 // this is required to send it to the client, as the relative position is sent as the float multiplied by 32
74 int newEncodedPosX = MathHelper.floor(this.tracker.locX * 32.0D);
75 int newEncodedPosY = MathHelper.floor(this.tracker.locY * 32.0D);
76 int newEncodedPosZ = MathHelper.floor(this.tracker.locZ * 32.0D);
77 int newEncodedRotationYaw = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F);
78 int newEncodedRotationPitch = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F);
79 int encodedDiffX = newEncodedPosX - this.d;
80 int encodedDiffY = newEncodedPosY - this.e;
81 int encodedDiffZ = newEncodedPosZ - this.f;
82 Object packet = null;
83 // mob movement fix, credit to Oldmana#7086 from the Modification Station discord server
84 // https://discordapp.com/channels/397834523028488203/397839387465089054/684637208199823377
85 int movementUpdateTreshold = 1;
86 int rotationUpdateTreshold = 1;
87 boolean needsPositionUpdate = Math.abs(encodedDiffX) >= movementUpdateTreshold || Math.abs(encodedDiffY) >= movementUpdateTreshold || Math.abs(encodedDiffZ) >= movementUpdateTreshold || tracker instanceof EntityBoat || tracker instanceof EntityMinecart;
88
89 boolean needsRotationUpdate = Math.abs(newEncodedRotationYaw - this.g) >= rotationUpdateTreshold || Math.abs(newEncodedRotationPitch - this.h) >= rotationUpdateTreshold;
90
91 // CraftBukkit start - Code moved from below
92 if (needsPositionUpdate) {
93 this.d = newEncodedPosX;
94 this.e = newEncodedPosY;
95 this.f = newEncodedPosZ;
96 }
97
98 if (needsRotationUpdate) {
99 this.g = newEncodedRotationYaw;
100 this.h = newEncodedRotationPitch;
101 }
102 // CraftBukkit end
103
104 if (encodedDiffX >= -128 && encodedDiffX < 128 && encodedDiffY >= -128 && encodedDiffY < 128 && encodedDiffZ >= -128 && encodedDiffZ < 128 && this.t <= 400) {
105 // entity has moved less than 4 blocks
106 if (needsPositionUpdate && needsRotationUpdate) {
107 packet = new Packet33RelEntityMoveLook(this.tracker.id, (byte) encodedDiffX, (byte) encodedDiffY, (byte) encodedDiffZ, (byte) newEncodedRotationYaw, (byte) newEncodedRotationPitch);
108 } else if (needsPositionUpdate) {
109 packet = new Packet31RelEntityMove(this.tracker.id, (byte) encodedDiffX, (byte) encodedDiffY, (byte) encodedDiffZ);
110 } else if (needsRotationUpdate) {
111 packet = new Packet32EntityLook(this.tracker.id, (byte) newEncodedRotationYaw, (byte) newEncodedRotationPitch);
112 }
113 } else {
114 this.t = 0;
115 // minecart clipping fix
116 //this.tracker.locX = (double) i / 32.0D;
117 //this.tracker.locY = (double) j / 32.0D;
118 //this.tracker.locZ = (double) k / 32.0D;
119 // entity has moved more than 4 blocks, send teleport
120
121 // CraftBukkit start - Refresh list of who can see a player before sending teleport packet
122 if (this.tracker instanceof EntityPlayer) {
123 this.scanPlayers(new java.util.ArrayList(this.trackedPlayers));
124 }
125 // CraftBukkit end
126
127 packet = new Packet34EntityTeleport(this.tracker.id, newEncodedPosX, newEncodedPosY, newEncodedPosZ, (byte) newEncodedRotationYaw, (byte) newEncodedRotationPitch);
128 }
129
130 if (this.isMoving) {
131 double d0 = this.tracker.motX - this.i;
132 double d1 = this.tracker.motY - this.j;
133 double d2 = this.tracker.motZ - this.k;
134 double d3 = 0.02D;
135 double d4 = d0 * d0 + d1 * d1 + d2 * d2;
136
137 if (d4 > d3 * d3 || d4 > 0.0D && this.tracker.motX == 0.0D && this.tracker.motY == 0.0D && this.tracker.motZ == 0.0D) {
138 this.i = this.tracker.motX;
139 this.j = this.tracker.motY;
140 this.k = this.tracker.motZ;
141 this.a((Packet) (new Packet28EntityVelocity(this.tracker.id, this.i, this.j, this.k)));
142 }
143 }
144
145 if (packet != null) {
146 this.a((Packet) packet);
147 }
148
149
150 DataWatcher datawatcher = this.tracker.aa();
151
152 if (datawatcher.a()) {
153 this.b((Packet) (new Packet40EntityMetadata(this.tracker.id, datawatcher)));
154 }
155
156 // uberbukkit - send both methods. legacy packet 18 gets ignored by clients that support packet 40
157 if (this.b_ && this.tracker.vehicle == null) {
158 this.b_ = false;
159 this.b((Packet) (new Packet18ArmAnimation(this.tracker, 101)));
160 } else if (!this.b_ && this.tracker.vehicle != null) {
161 this.b_ = true;
162 this.b((Packet) (new Packet18ArmAnimation(this.tracker, 100)));
163 }
164
165 if (this.tracker instanceof EntityLiving) {
166 if (this.d_ && !this.tracker.isSneaking()) {
167 this.d_ = false;
168 this.b((Packet) (new Packet18ArmAnimation(this.tracker, 105)));
169 } else if (!this.d_ && this.tracker.isSneaking()) {
170 this.d_ = true;
171 this.b((Packet) (new Packet18ArmAnimation(this.tracker, 104)));
172 }
173 }
174
175 if (this.c_ && this.tracker.fireTicks <= 0) {
176 this.c_ = false;
177 this.b((Packet) (new Packet18ArmAnimation(this.tracker, 103)));
178 } else if (!this.c_ && this.tracker.fireTicks > 0) {
179 this.c_ = true;
180 this.b((Packet) (new Packet18ArmAnimation(this.tracker, 102)));
181 }
182
183 /* CraftBukkit start - Code moved up
184 if (needsPositionUpdate) {
185 this.d = newEncodedPosX;
186 this.e = newEncodedPosY;
187 this.f = newEncodedPosZ;
188 }
189
190 if (needsRotationUpdate) {
191 this.g = newEncodedRotationYaw;
192 this.h = newEncodedRotationPitch;
193 }
194 // Craftbukkit end */
195 this.tracker.airBorne = false;
196 }
197
198 if (this.tracker.velocityChanged) {
199 // CraftBukkit start - create PlayerVelocity event
200 boolean cancelled = false;
201
202 if (this.tracker instanceof EntityPlayer) {
203 org.bukkit.entity.Player player = (org.bukkit.entity.Player) this.tracker.getBukkitEntity();
204 org.bukkit.util.Vector velocity = player.getVelocity();
205
206 org.bukkit.event.player.PlayerVelocityEvent event = new org.bukkit.event.player.PlayerVelocityEvent(player, velocity);
207 this.tracker.world.getServer().getPluginManager().callEvent(event);
208
209 if (event.isCancelled()) {
210 cancelled = true;
211 } else if (!velocity.equals(event.getVelocity())) {
212 player.setVelocity(velocity);
213 }
214 }
215
216 if (!cancelled) {
217 this.b((Packet) (new Packet28EntityVelocity(this.tracker)));
218 }
219 // CraftBukkit end
220 this.tracker.velocityChanged = false;
221 }
222 }
223
224 public void a(Packet packet) {
225 Iterator iterator = this.trackedPlayers.iterator();
226
227 while (iterator.hasNext()) {
228 EntityPlayer entityplayer = (EntityPlayer) iterator.next();
229
230 entityplayer.netServerHandler.sendPacket(packet.clone()); // uberbukkit - .clone()
231 }
232 }
233
234 public void b(Packet packet) {
235 this.a(packet);
236 if (this.tracker instanceof EntityPlayer) {
237 ((EntityPlayer) this.tracker).netServerHandler.sendPacket(packet.clone()); // uberbukkit - .clone()
238 }
239 }
240
241 public void a() {
242 // Poseidon start
243 //this.a((Packet) (new Packet29DestroyEntity(this.tracker.id)));
244 Iterator iterator = this.trackedPlayers.iterator();
245
246 while (iterator.hasNext()) {
247 EntityPlayer entityplayer = (EntityPlayer) iterator.next();
248
249 entityplayer.removeQueue.add(Integer.valueOf(this.tracker.id));
250 }
251 // Poseidon end
252 }
253
254 public void a(EntityPlayer entityplayer) {
255 if (this.trackedPlayers.contains(entityplayer)) {
256 entityplayer.removeQueue.add(Integer.valueOf(this.tracker.id)); // Poseidon
257 this.trackedPlayers.remove(entityplayer);
258 }
259 }
260
261 public void b(EntityPlayer entityplayer) {
262 if (entityplayer != this.tracker) {
263 double d0 = entityplayer.locX - (double) (this.d / 32);
264 double d1 = entityplayer.locZ - (double) (this.f / 32);
265
266 if (d0 >= (double) (-this.b) && d0 <= (double) this.b && d1 >= (double) (-this.b) && d1 <= (double) this.b) {
267 if (!this.trackedPlayers.contains(entityplayer) && this.d(entityplayer)) {
268 // CraftBukkit start
269 if (tracker instanceof EntityPlayer) {
270 org.bukkit.entity.Player player = (Player) ((EntityPlayer) tracker).getBukkitEntity();
271 if (!((Player) entityplayer.getBukkitEntity()).canSee(player)) {
272 return;
273 }
274 }
275
276 entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.id));
277 // CraftBukkit end
278
279 this.trackedPlayers.add(entityplayer);
280 // Poseidon start
281 Packet packet = this.b(entityplayer.netServerHandler.networkManager.pvn);
282 entityplayer.netServerHandler.sendPacket(packet);
283
284 // uberbukkit
285 if (!entityplayer.protocol.canReceivePacket(40)) {
286 if (this.d_) {
287 entityplayer.netServerHandler.sendPacket((Packet) (new Packet18ArmAnimation(this.tracker, 104)));
288 }
289
290 if (this.b_) {
291 entityplayer.netServerHandler.sendPacket((Packet) (new Packet18ArmAnimation(this.tracker, 100)));
292 }
293
294 if (this.c_) {
295 entityplayer.netServerHandler.sendPacket((Packet) (new Packet18ArmAnimation(this.tracker, 102)));
296 }
297 } else {
298 if (!this.tracker.datawatcher.getD()) {
299 entityplayer.netServerHandler.sendPacket(new Packet40EntityMetadata(this.tracker.id, this.tracker.datawatcher));
300 }
301 }
302
303 this.i = this.tracker.motX;
304 this.j = this.tracker.motY;
305 this.k = this.tracker.motZ;
306 if (this.isMoving) {
307 entityplayer.netServerHandler.sendPacket(new Packet28EntityVelocity(this.tracker.id, this.tracker.motX, this.tracker.motY, this.tracker.motZ));
308 }
309
310 if (this.tracker.vehicle != null) {
311 entityplayer.netServerHandler.sendPacket(new Packet39AttachEntity(this.tracker, this.tracker.vehicle));
312 }
313 // Poseidon end
314
315 // CraftBukkit start
316 if (this.tracker.passenger != null) {
317 entityplayer.netServerHandler.sendPacket(new Packet39AttachEntity(this.tracker.passenger, this.tracker));
318 }
319 // CraftBukkit end
320
321 ItemStack[] aitemstack = this.tracker.getEquipment();
322
323 if (aitemstack != null) {
324 for (int i = 0; i < aitemstack.length; ++i) {
325 entityplayer.netServerHandler.sendPacket(new Packet5EntityEquipment(this.tracker.id, i, aitemstack[i]));
326 }
327 }
328
329 if (this.tracker instanceof EntityHuman) {
330 EntityHuman entityhuman = (EntityHuman) this.tracker;
331
332 // uberbukkit
333 if (entityhuman.isSleeping() && entityplayer.protocol.canReceivePacket(17)) {
334 entityplayer.netServerHandler.sendPacket(new Packet17(this.tracker, 0, MathHelper.floor(this.tracker.locX), MathHelper.floor(this.tracker.locY), MathHelper.floor(this.tracker.locZ)));
335 }
336 }
337 }
338 } else if (this.trackedPlayers.contains(entityplayer)) {
339 this.trackedPlayers.remove(entityplayer);
340 entityplayer.removeQueue.add(Integer.valueOf(this.tracker.id)); // Poseidon
341 //entityplayer.netServerHandler.sendPacket(new Packet29DestroyEntity(this.tracker.id));
342 }
343 }
344 }
345
346 private boolean d(EntityPlayer entityplayer) {
347 return entityplayer.getWorldServer().getPlayerManager().a(entityplayer, this.tracker.bH, this.tracker.bJ);
348 }
349
350 public void scanPlayers(List list) {
351 for (int i = 0; i < list.size(); ++i) {
352 this.b((EntityPlayer) list.get(i));
353 }
354 }
355
356 private Packet b(int pvn) {
357 if (this.tracker.dead) { // Poseidon
358 // CraftBukkit start - Remove useless error spam, just return
359 // System.out.println("Fetching addPacket for removed entity");
360 return null;
361 // CraftBukkit end
362 }
363
364 if (this.tracker instanceof EntityItem) {
365 EntityItem entityitem = (EntityItem) this.tracker;
366 Packet21PickupSpawn packet21pickupspawn = new Packet21PickupSpawn(entityitem);
367
368 // There's no reason to set the item's position to the compressed position
369 //entityitem.locX = (double) packet21pickupspawn.b / 32.0D;
370 //entityitem.locY = (double) packet21pickupspawn.c / 32.0D;
371 //entityitem.locZ = (double) packet21pickupspawn.d / 32.0D;
372 return packet21pickupspawn;
373 } else if (this.tracker instanceof EntityPlayer) {
374 // CraftBukkit start - limit name length to 16 characters
375 if (((EntityHuman) this.tracker).name.length() > 16) {
376 ((EntityHuman) this.tracker).name = ((EntityHuman) this.tracker).name.substring(0, 16);
377 }
378 // CraftBukkit end
379 return new Packet20NamedEntitySpawn((EntityHuman) this.tracker);
380 } else {
381 if (this.tracker instanceof EntityMinecart) {
382 EntityMinecart entityminecart = (EntityMinecart) this.tracker;
383
384 if (entityminecart.type == 0) {
385 return new Packet23VehicleSpawn(this.tracker, 10);
386 }
387
388 if (entityminecart.type == 1) {
389 return new Packet23VehicleSpawn(this.tracker, 11);
390 }
391
392 if (entityminecart.type == 2) {
393 return new Packet23VehicleSpawn(this.tracker, 12);
394 }
395 }
396
397 if (this.tracker instanceof EntityBoat) {
398 return new Packet23VehicleSpawn(this.tracker, 1);
399 } else if (this.tracker instanceof IAnimal) {
400 return new Packet24MobSpawn((EntityLiving) this.tracker);
401 } else if (this.tracker instanceof EntityFish) {
402 return new Packet23VehicleSpawn(this.tracker, 90);
403 } else if (this.tracker instanceof EntityArrow) {
404 EntityLiving entityliving = ((EntityArrow) this.tracker).shooter;
405
406 return new Packet23VehicleSpawn(this.tracker, 60, entityliving != null ? entityliving.id : this.tracker.id);
407 // uberbukkit
408 } else if (this.tracker instanceof EntitySnowball || (this.tracker instanceof EntityFireball && pvn < 12)) {
409 return new Packet23VehicleSpawn(this.tracker, 61);
410 } else if (this.tracker instanceof EntityFireball && pvn >= 12) {
411 EntityFireball entityfireball = (EntityFireball) this.tracker;
412 // CraftBukkit start - added check for null shooter
413 int shooter = ((EntityFireball) this.tracker).shooter != null ? ((EntityFireball) this.tracker).shooter.id : 1;
414 Packet23VehicleSpawn packet23vehiclespawn = new Packet23VehicleSpawn(this.tracker, 63, shooter);
415 // CraftBukkit end
416
417 packet23vehiclespawn.e = (int) (entityfireball.c * 8000.0D);
418 packet23vehiclespawn.f = (int) (entityfireball.d * 8000.0D);
419 packet23vehiclespawn.g = (int) (entityfireball.e * 8000.0D);
420 return packet23vehiclespawn;
421 } else if (this.tracker instanceof EntityEgg) {
422 return new Packet23VehicleSpawn(this.tracker, 62);
423 } else if (this.tracker instanceof EntityTNTPrimed) {
424 return new Packet23VehicleSpawn(this.tracker, 50);
425 } else {
426 if (this.tracker instanceof EntityFallingSand) {
427 EntityFallingSand entityfallingsand = (EntityFallingSand) this.tracker;
428
429 if (entityfallingsand.a == Block.SAND.id) {
430 return new Packet23VehicleSpawn(this.tracker, 70);
431 }
432
433 if (entityfallingsand.a == Block.GRAVEL.id) {
434 return new Packet23VehicleSpawn(this.tracker, 71);
435 }
436 }
437
438 if (this.tracker instanceof EntityPainting) {
439 return new Packet25EntityPainting((EntityPainting) this.tracker);
440 } else {
441 throw new IllegalArgumentException("Don\'t know how to add " + this.tracker.getClass() + "!");
442 }
443 }
444 }
445 }
446
447 public void c(EntityPlayer entityplayer) {
448 if (this.trackedPlayers.contains(entityplayer)) {
449 this.trackedPlayers.remove(entityplayer);
450 entityplayer.removeQueue.add(Integer.valueOf(this.tracker.id)); // Poseidon
451 //entityplayer.netServerHandler.sendPacket(new Packet29DestroyEntity(this.tracker.id));
452 }
453 }
454}