Backport entitytrackerentry changes to fix duplicate tablist adds

This commit is contained in:
fullwall 2023-05-03 23:30:37 +08:00
parent 71ab3d8dd2
commit 6b4ef37a46
12 changed files with 181 additions and 84 deletions

View File

@ -1,36 +1,76 @@
package net.citizensnpcs.nms.v1_11_R1.util;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.ForwardingSet;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_11_R1.entity.EntityHumanNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.npc.skin.SkinnableEntity;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.EntityTrackerEntry;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private Entity tracker;
public PlayerlistTrackerEntry(Entity entity, int i, int j, int k, boolean flag) {
super(entity, i, j, k, flag);
tracker = getTracker(this);
try {
Set<EntityPlayer> delegate = super.trackedPlayers;
TRACKING_SET_SETTER.invoke(this, new ForwardingSet<EntityPlayer>() {
@Override
public boolean add(EntityPlayer player) {
boolean res = super.add(player);
if (res) {
updateLastPlayer(player);
}
return res;
}
@Override
protected Set<EntityPlayer> delegate() {
return delegate;
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}
public PlayerlistTrackerEntry(EntityTrackerEntry entry) {
this(getTracker(entry), getE(entry), getF(entry), getG(entry), getU(entry));
}
public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
if (lastUpdatedPlayer == null || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
lastUpdatedPlayer = null;
if (!Setting.DISABLE_TABLIST.asBoolean())
return;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(),
() -> NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity()),
Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
}
@Override
public void updatePlayer(final EntityPlayer entityplayer) {
// prevent updates to NPC "viewers"
if (entityplayer instanceof EntityHumanNPC)
return;
Entity tracker = getTracker(this);
if (tracker instanceof NPCHolder) {
NPC npc = ((NPCHolder) tracker).getNPC();
NPCSeenByPlayerEvent event = new NPCSeenByPlayerEvent(npc, entityplayer.getBukkitEntity());
@ -38,21 +78,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
if (event.isCancelled())
return;
}
if (tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
if (entityplayer != tracker && c(entityplayer)) {
if (!this.trackedPlayers.contains(entityplayer)
&& ((entityplayer.x().getPlayerChunkMap().a(entityplayer, tracker.ab, tracker.ad))
|| (tracker.attachedToPlayer))) {
if ((tracker instanceof SkinnableEntity)) {
SkinnableEntity skinnable = (SkinnableEntity) tracker;
Player player = skinnable.getBukkitEntity();
if (!entityplayer.getBukkitEntity().canSee(player))
return;
skinnable.getSkinTracker().updateViewer(entityplayer.getBukkitEntity());
}
}
}
super.updatePlayer(entityplayer);
}
@ -119,5 +144,7 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private static Field F = NMS.getField(EntityTrackerEntry.class, "f");
private static Field G = NMS.getField(EntityTrackerEntry.class, "g");
private static Field TRACKER = NMS.getField(EntityTrackerEntry.class, "tracker");
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
Set.class);
private static Field U = NMS.getField(EntityTrackerEntry.class, "u");
}

View File

@ -47,7 +47,6 @@ import net.minecraft.server.v1_12_R1.AxisAlignedBB;
import net.minecraft.server.v1_12_R1.BlockPosition;
import net.minecraft.server.v1_12_R1.ChatComponentText;
import net.minecraft.server.v1_12_R1.DamageSource;
import net.minecraft.server.v1_12_R1.DataWatcher;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntityHuman;
import net.minecraft.server.v1_12_R1.EntityPlayer;
@ -228,14 +227,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return controllerMove;
}
@Override
public DataWatcher getDataWatcher() {
if (trackerEntry != null && trackerEntry.isUpdating()) {
trackerEntry.updateLastPlayer();
}
return super.getDataWatcher();
}
public NavigationAbstract getNavigation() {
return navigation;
}

View File

@ -2,11 +2,14 @@ package net.citizensnpcs.nms.v1_12_R1.util;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.ForwardingSet;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
@ -16,29 +19,42 @@ import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_12_R1.Entity;
import net.minecraft.server.v1_12_R1.EntityPlayer;
import net.minecraft.server.v1_12_R1.EntityTracker;
import net.minecraft.server.v1_12_R1.EntityTrackerEntry;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private EntityPlayer lastUpdatedPlayer;
private final Entity tracker;
public PlayerlistTrackerEntry(Entity entity, int i, int j, int k, boolean flag) {
super(entity, i, j, k, flag);
this.tracker = getTracker(this);
try {
Set<EntityPlayer> delegate = super.trackedPlayers;
TRACKING_SET_SETTER.invoke(this, new ForwardingSet<EntityPlayer>() {
@Override
public boolean add(EntityPlayer player) {
boolean res = super.add(player);
if (res) {
updateLastPlayer(player);
}
return res;
}
@Override
protected Set<EntityPlayer> delegate() {
return delegate;
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}
public PlayerlistTrackerEntry(EntityTrackerEntry entry) {
this(getTracker(entry), getE(entry), getF(entry), getG(entry), getU(entry));
}
public boolean isUpdating() {
return lastUpdatedPlayer != null;
}
public void updateLastPlayer() {
if ((lastUpdatedPlayer == null) || tracker.dead || lastUpdatedPlayer == null
|| tracker.getBukkitEntity().getType() != EntityType.PLAYER)
public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
if (lastUpdatedPlayer == null || tracker.dead || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
@ -73,7 +89,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
if (entityplayer instanceof EntityHumanNPC)
return;
this.lastUpdatedPlayer = entityplayer;
super.updatePlayer(entityplayer);
}
@ -136,6 +151,9 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private static Field F = NMS.getField(EntityTrackerEntry.class, "f");
private static Field G = NMS.getField(EntityTrackerEntry.class, "g");
private static Field TRACKER = NMS.getField(EntityTrackerEntry.class, "tracker");
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class);
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
int.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
Set.class);
private static Field U = NMS.getField(EntityTrackerEntry.class, "u");
}

View File

@ -47,7 +47,6 @@ import net.minecraft.server.v1_13_R2.AxisAlignedBB;
import net.minecraft.server.v1_13_R2.BlockPosition;
import net.minecraft.server.v1_13_R2.ChatComponentText;
import net.minecraft.server.v1_13_R2.DamageSource;
import net.minecraft.server.v1_13_R2.DataWatcher;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityHuman;
import net.minecraft.server.v1_13_R2.EntityPlayer;
@ -216,14 +215,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return controllerMove;
}
@Override
public DataWatcher getDataWatcher() {
if (trackerEntry != null && trackerEntry.isUpdating()) {
trackerEntry.updateLastPlayer();
}
return super.getDataWatcher();
}
public NavigationAbstract getNavigation() {
return navigation;
}

View File

@ -2,11 +2,14 @@ package net.citizensnpcs.nms.v1_13_R2.util;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.ForwardingSet;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
@ -16,28 +19,42 @@ import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.EntityTracker;
import net.minecraft.server.v1_13_R2.EntityTrackerEntry;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntity.PacketPlayOutEntityLook;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
private EntityPlayer lastUpdatedPlayer;
private final Entity tracker;
public PlayerlistTrackerEntry(Entity entity, int i, int j, int k, boolean flag) {
super(entity, i, j, k, flag);
tracker = getTracker(this);
try {
Set<EntityPlayer> delegate = super.trackedPlayers;
TRACKING_SET_SETTER.invoke(this, new ForwardingSet<EntityPlayer>() {
@Override
public boolean add(EntityPlayer player) {
boolean res = super.add(player);
if (res) {
updateLastPlayer(player);
}
return res;
}
@Override
protected Set<EntityPlayer> delegate() {
return delegate;
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}
public PlayerlistTrackerEntry(EntityTrackerEntry entry) {
this(getTracker(entry), getE(entry), getF(entry), getG(entry), getU(entry));
}
public boolean isUpdating() {
return lastUpdatedPlayer != null;
}
public void updateLastPlayer() {
public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
@ -78,7 +95,6 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
if (entityplayer instanceof EntityHumanNPC)
return;
this.lastUpdatedPlayer = entityplayer;
super.updatePlayer(entityplayer);
}
@ -138,9 +154,14 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry {
}
private static Field E = NMS.getField(EntityTrackerEntry.class, "e");
private static Field F = NMS.getField(EntityTrackerEntry.class, "f");
private static Field G = NMS.getField(EntityTrackerEntry.class, "g");
private static Field TRACKER = NMS.getField(EntityTrackerEntry.class, "tracker");
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class);
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
int.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTrackerEntry.class,
Set.class);
private static Field U = NMS.getField(EntityTrackerEntry.class, "u");
}

View File

@ -328,14 +328,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
}
}
@Override
public Packet<?> N() {
if (playerlistTracker != null) {
playerlistTracker.updateLastPlayer();
}
return super.N();
}
@Override
public void playerTick() {
if (npc == null) {

View File

@ -1,11 +1,14 @@
package net.citizensnpcs.nms.v1_14_R1.util;
import java.lang.invoke.MethodHandle;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.ForwardingSet;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
@ -21,19 +24,38 @@ import net.minecraft.server.v1_14_R1.PlayerChunkMap;
import net.minecraft.server.v1_14_R1.PlayerChunkMap.EntityTracker;
public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
private EntityPlayer lastUpdatedPlayer;
private final Entity tracker;
public PlayerlistTracker(PlayerChunkMap map, Entity entity, int i, int j, boolean flag) {
map.super(entity, i, j, flag);
this.tracker = entity;
try {
Set<EntityPlayer> delegate = super.trackedPlayers;
TRACKING_SET_SETTER.invoke(this, new ForwardingSet<EntityPlayer>() {
@Override
public boolean add(EntityPlayer player) {
boolean res = super.add(player);
if (res) {
updateLastPlayer(player);
}
return res;
}
@Override
protected Set<EntityPlayer> delegate() {
return delegate;
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}
public PlayerlistTracker(PlayerChunkMap map, EntityTracker entry) {
this(map, getTracker(entry), getTrackingDistance(entry), getD(entry), getE(entry));
}
public void updateLastPlayer() {
public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
@ -73,7 +95,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
if (entityplayer instanceof EntityHumanNPC)
return;
this.lastUpdatedPlayer = entityplayer;
super.updatePlayer(entityplayer);
}
@ -114,9 +135,11 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
}
private static final MethodHandle D = NMS.getGetter(EntityTrackerEntry.class, "d");
private static final MethodHandle E = NMS.getGetter(EntityTrackerEntry.class, "e");
private static final MethodHandle TRACKER = NMS.getGetter(EntityTracker.class, "tracker");
private static final MethodHandle TRACKER_ENTRY = NMS.getGetter(EntityTracker.class, "trackerEntry");
private static final MethodHandle TRACKING_RANGE = NMS.getGetter(EntityTracker.class, "trackingDistance");
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, Set.class);
}

View File

@ -301,14 +301,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return npc.getNavigator().isNavigating();
}
@Override
public Packet<?> L() {
if (playerlistTracker != null) {
playerlistTracker.updateLastPlayer();
}
return super.L();
}
private void moveOnCurrentHeading() {
if (jumping) {
if (onGround && jumpTicks == 0) {

View File

@ -1,11 +1,14 @@
package net.citizensnpcs.nms.v1_15_R1.util;
import java.lang.invoke.MethodHandle;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.ForwardingSet;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
@ -21,19 +24,38 @@ import net.minecraft.server.v1_15_R1.PlayerChunkMap;
import net.minecraft.server.v1_15_R1.PlayerChunkMap.EntityTracker;
public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
private EntityPlayer lastUpdatedPlayer;
private final Entity tracker;
public PlayerlistTracker(PlayerChunkMap map, Entity entity, int i, int j, boolean flag) {
map.super(entity, i, j, flag);
this.tracker = entity;
try {
Set<EntityPlayer> delegate = super.trackedPlayers;
TRACKING_SET_SETTER.invoke(this, new ForwardingSet<EntityPlayer>() {
@Override
public boolean add(EntityPlayer player) {
boolean res = super.add(player);
if (res) {
updateLastPlayer(player);
}
return res;
}
@Override
protected Set<EntityPlayer> delegate() {
return delegate;
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}
public PlayerlistTracker(PlayerChunkMap map, EntityTracker entry) {
this(map, getTracker(entry), getTrackingDistance(entry), getD(entry), getE(entry));
}
public void updateLastPlayer() {
public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
@ -73,7 +95,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
if (entityplayer instanceof EntityHumanNPC)
return;
this.lastUpdatedPlayer = entityplayer;
super.updatePlayer(entityplayer);
}
@ -119,4 +140,5 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
private static final MethodHandle TRACKER_ENTRY = NMS.getGetter(EntityTracker.class, "trackerEntry");
private static final MethodHandle TRACKING_RANGE = NMS.getGetter(EntityTracker.class, "trackingDistance");
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, Set.class);
}

View File

@ -291,9 +291,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
@Override
public Packet<?> P() {
if (playerlistTracker != null) {
playerlistTracker.updateLastPlayer();
}
return super.P();
}

View File

@ -1,11 +1,14 @@
package net.citizensnpcs.nms.v1_16_R3.util;
import java.lang.invoke.MethodHandle;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.ForwardingSet;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCSeenByPlayerEvent;
@ -21,19 +24,38 @@ import net.minecraft.server.v1_16_R3.PlayerChunkMap;
import net.minecraft.server.v1_16_R3.PlayerChunkMap.EntityTracker;
public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
private EntityPlayer lastUpdatedPlayer;
private final Entity tracker;
public PlayerlistTracker(PlayerChunkMap map, Entity entity, int i, int j, boolean flag) {
map.super(entity, i, j, flag);
this.tracker = entity;
try {
Set<EntityPlayer> delegate = super.trackedPlayers;
TRACKING_SET_SETTER.invoke(this, new ForwardingSet<EntityPlayer>() {
@Override
public boolean add(EntityPlayer player) {
boolean res = super.add(player);
if (res) {
updateLastPlayer(player);
}
return res;
}
@Override
protected Set<EntityPlayer> delegate() {
return delegate;
}
});
} catch (Throwable e) {
e.printStackTrace();
}
}
public PlayerlistTracker(PlayerChunkMap map, EntityTracker entry) {
this(map, getTracker(entry), getTrackingDistance(entry), getD(entry), getE(entry));
}
public void updateLastPlayer() {
public void updateLastPlayer(EntityPlayer lastUpdatedPlayer) {
if (tracker.dead || lastUpdatedPlayer == null || tracker.getBukkitEntity().getType() != EntityType.PLAYER)
return;
final EntityPlayer entityplayer = lastUpdatedPlayer;
@ -73,7 +95,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
if (entityplayer instanceof EntityHumanNPC)
return;
this.lastUpdatedPlayer = entityplayer;
super.updatePlayer(entityplayer);
}
@ -114,9 +135,11 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
}
private static final MethodHandle D = NMS.getGetter(EntityTrackerEntry.class, "d");
private static final MethodHandle E = NMS.getGetter(EntityTrackerEntry.class, "e");
private static final MethodHandle TRACKER = NMS.getGetter(EntityTracker.class, "tracker");
private static final MethodHandle TRACKER_ENTRY = NMS.getGetter(EntityTracker.class, "trackerEntry");
private static final MethodHandle TRACKING_RANGE = NMS.getGetter(EntityTracker.class, "trackingDistance");
private static final MethodHandle TRACKING_RANGE_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, int.class);
private static final MethodHandle TRACKING_SET_SETTER = NMS.getFirstFinalSetter(EntityTracker.class, Set.class);
}

View File

@ -43,7 +43,7 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
}
@Override
protected Set delegate() {
protected Set<ServerPlayerConnection> delegate() {
return set;
}
});