Paper/Spigot-Server-Patches/0037-Send-absolute-position-the-first-time-an-entity-is-s.patch
Shane Freeder ff085b8e8e
Improve timings around chunk loading
Timers such as syncChunkLoad are hit persistently due to changes in how
this mechanism works which impacts the usablity of timings
2019-07-12 05:13:15 +01:00

112 lines
5.4 KiB
Diff

From 02d36a1ddf62541417ea624258a0019b01584fc4 Mon Sep 17 00:00:00 2001
From: Jedediah Smith <jedediah@silencegreys.com>
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 cf0e1a6a0..f04a9d18c 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<Packet<?>> f;
+ private final Consumer<Packet<?>> f; private Consumer<Packet<?>> 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<EntityPlayer> trackedPlayers;
+ // Paper start
+ private java.util.Map<EntityPlayer, Boolean> 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<Packet<?>> consumer, java.util.Map<EntityPlayer, Boolean> trackedPlayers) {
+ this(worldserver, entity, i, flag, consumer, trackedPlayers.keySet());
+ trackedPlayerMap = trackedPlayers;
+ }
public EntityTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<EntityPlayer> 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<EntityPlayer, Boolean> 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 85da52e2c..312845ec0 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1090,10 +1090,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
private final Entity tracker;
private final int trackingDistance;
private SectionPosition e;
- public final Set<EntityPlayer> 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<EntityPlayer, Boolean> trackedPlayerMap = new java.util.HashMap<>();
+ public Set<EntityPlayer> 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);
@@ -1175,7 +1179,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)) {
--
2.22.0