From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jedediah Smith Date: Wed, 2 Mar 2016 23:13:07 -0600 Subject: [PATCH] Send absolute position the first time an entity is seen diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java index a75e0ec54e9dfd98c1bcbd13cb022ab05d8410b9..a13fd9b3404381879663c1f694a5d1903d1fd884 100644 --- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java +++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -2,6 +2,7 @@ package net.minecraft.server; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -21,7 +22,7 @@ public class EntityTrackerEntry { private final Entity tracker; private final int d; private final boolean e; - private final Consumer> f; + private final Consumer> f; private Consumer> getPacketConsumer() { return f; } // Paper - OBFHELPER private long xLoc; private long yLoc; private long zLoc; @@ -36,8 +37,23 @@ public class EntityTrackerEntry { private boolean r; // CraftBukkit start private final Set trackedPlayers; + // Paper start + private java.util.Map trackedPlayerMap = null; + + /** + * Requested in https://github.com/PaperMC/Paper/issues/1537 to allow intercepting packets + */ + public void sendPlayerPacket(EntityPlayer player, Packet packet) { + player.playerConnection.sendPacket(packet); + } + + public EntityTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag, Consumer> consumer, java.util.Map trackedPlayers) { + this(worldserver, entity, i, flag, consumer, trackedPlayers.keySet()); + trackedPlayerMap = trackedPlayers; + } public EntityTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag, Consumer> consumer, Set trackedPlayers) { + // Paper end this.trackedPlayers = trackedPlayers; // CraftBukkit end this.m = Vec3D.a; @@ -159,7 +175,25 @@ public class EntityTrackerEntry { } if (packet1 != null) { - this.f.accept(packet1); + // paper start + if (trackedPlayerMap == null || packet1 instanceof PacketPlayOutEntityTeleport) { + this.f.accept((packet1)); + } else { + PacketPlayOutEntityTeleport teleportPacket = null; + + for (java.util.Map.Entry viewer : trackedPlayerMap.entrySet()) { + if (viewer.getValue()) { + viewer.setValue(false); + if (teleportPacket == null) { + teleportPacket = new PacketPlayOutEntityTeleport(this.tracker); + } + sendPlayerPacket(viewer.getKey(), teleportPacket); + } else { + sendPlayerPacket(viewer.getKey(), packet1); + } + } + } + // Paper end } this.c(); diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java index 65134c87772cb6d4d732fc223929cfda7524dde2..eece2f689cce58a35d33c6e8d9d56ea4e9dfd88c 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -1220,10 +1220,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { private final Entity tracker; private final int trackingDistance; private SectionPosition e; - public final Set trackedPlayers = Sets.newHashSet(); + // Paper start + // Replace trackedPlayers Set with a Map. The value is true until the player receives + // their first update (which is forced to have absolute coordinates), false afterward. + public java.util.Map trackedPlayerMap = new java.util.HashMap<>(); + public Set trackedPlayers = trackedPlayerMap.keySet(); public EntityTracker(Entity entity, int i, int j, boolean flag) { - this.trackerEntry = new EntityTrackerEntry(PlayerChunkMap.this.world, entity, j, flag, this::broadcast, trackedPlayers); // CraftBukkit + this.trackerEntry = new EntityTrackerEntry(PlayerChunkMap.this.world, entity, j, flag, this::broadcast, trackedPlayerMap); // CraftBukkit // Paper this.tracker = entity; this.trackingDistance = i; this.e = SectionPosition.a(entity); @@ -1305,7 +1309,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.getId())); // CraftBukkit end - if (flag1 && this.trackedPlayers.add(entityplayer)) { + if (flag1 && this.trackedPlayerMap.putIfAbsent(entityplayer, true) == null) { // Paper this.trackerEntry.b(entityplayer); } } else if (this.trackedPlayers.remove(entityplayer)) {