Rework tablist for recent versions

This commit is contained in:
fullwall 2020-05-12 23:12:39 +08:00
parent 5e2a7efb9e
commit 0b922011bd
5 changed files with 97 additions and 160 deletions

View File

@ -321,9 +321,6 @@ public class CitizensNPC extends AbstractNPC {
if (isSpawned() && getEntity().getLocation(CACHE_LOCATION).distanceSquared(location) < 1) {
NMS.setHeadYaw(getEntity(), location.getYaw());
}
if (getEntity() instanceof SkinnableEntity) {
((SkinnableEntity) getEntity()).getSkinTracker().updateNearbyViewers(48);
}
}
@Override

View File

@ -2,94 +2,38 @@ package net.citizensnpcs.nms.v1_14_R1.util;
import java.lang.invoke.MethodHandle;
import org.bukkit.entity.Player;
import net.citizensnpcs.nms.v1_14_R1.entity.EntityHumanNPC;
import net.citizensnpcs.npc.skin.SkinnableEntity;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntityTrackerEntry;
import net.minecraft.server.v1_14_R1.PlayerChunk;
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
import net.minecraft.server.v1_14_R1.PlayerChunkMap.EntityTracker;
import net.minecraft.server.v1_14_R1.Vec3D;
public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
private final PlayerChunkMap map;
private final Entity tracker;
private final EntityTrackerEntry trackerEntry;
private final int trackingDistance;
public PlayerlistTracker(PlayerChunkMap map, Entity entity, int i, int j, boolean flag) {
map.super(entity, i, j, flag);
this.map = map;
this.tracker = getTracker(this);
this.trackerEntry = getTrackerEntry(this);
this.trackingDistance = i;
setTrackerEntry(new TablistRemovingTrackerEntry(map.world, entity, j, flag, this::broadcast, trackedPlayers));
}
public PlayerlistTracker(PlayerChunkMap map, EntityTracker entry) {
this(map, getTracker(entry), getI(entry), getD(entry), getE(entry));
this(map, getTracker(entry), getTrackingDistance(entry), getD(entry), getE(entry));
}
private int getb(ChunkCoordIntPair chunkcoordintpair, EntityPlayer entityplayer, boolean b) {
private void setTrackerEntry(EntityTrackerEntry entry) {
try {
return (int) B.invoke(chunkcoordintpair, entityplayer, b);
TRACKER_ENTRY_SETTER.invoke(this, entry);
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private int getViewDistance(PlayerChunkMap map2) {
try {
return (int) VIEW_DISTANCE.invoke(map2);
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private PlayerChunk getVisibleChunk(long pair) {
try {
return (PlayerChunk) GET_VISIBLE_CHUNK.invoke(map, pair);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
@Override
public void updatePlayer(final EntityPlayer entityplayer) {
if (entityplayer instanceof EntityHumanNPC)
return; // prevent updates to NPC "viewers"
Entity tracker = getTracker(this);
final Vec3D vec3d = new Vec3D(entityplayer.locX, entityplayer.locY, entityplayer.locZ).d(this.trackerEntry.b());
final int i = Math.min(this.trackingDistance, (getViewDistance(map) - 1) * 16);
final boolean flag = vec3d.x >= -i && vec3d.x <= i && vec3d.z >= -i && vec3d.z <= i
&& this.tracker.a(entityplayer);
if (entityplayer != tracker && flag && tracker instanceof SkinnableEntity) {
/* boolean flag1 = this.tracker.attachedToPlayer;
if (!flag1) {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ);
PlayerChunk playerchunk = getVisibleChunk(chunkcoordintpair.pair());
if (playerchunk.getChunk() != null) {
flag1 = getb(chunkcoordintpair, entityplayer, false) <= getViewDistance(map);
}
}*/
if (!this.trackedPlayers.contains(entityplayer)) {
SkinnableEntity skinnable = (SkinnableEntity) tracker;
Player player = skinnable.getBukkitEntity();
if (!entityplayer.getBukkitEntity().canSee(player))
return;
skinnable.getSkinTracker().updateViewer(entityplayer.getBukkitEntity());
}
if (!(entityplayer instanceof EntityHumanNPC)) {
// prevent updates to NPC "viewers"
super.updatePlayer(entityplayer);
}
super.updatePlayer(entityplayer);
}
private static int getD(EntityTracker entry) {
@ -110,15 +54,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return false;
}
private static int getI(EntityTracker entry) {
try {
return (Integer) I.invoke(entry);
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private static Entity getTracker(EntityTracker entry) {
try {
return (Entity) TRACKER.invoke(entry);
@ -128,23 +63,19 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return null;
}
private static EntityTrackerEntry getTrackerEntry(EntityTracker entry) {
private static int getTrackingDistance(EntityTracker entry) {
try {
return (EntityTrackerEntry) TRACKER_ENTRY.invoke(entry);
return (Integer) TRACKING_DISTANCE.invoke(entry);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
return 0;
}
private static final MethodHandle B = NMS.getMethodHandle(PlayerChunkMap.class, "b", true, ChunkCoordIntPair.class,
EntityPlayer.class, boolean.class);
private static final MethodHandle D = NMS.getGetter(EntityTrackerEntry.class, "d");
private static final MethodHandle E = NMS.getGetter(EntityTrackerEntry.class, "e");
private static final MethodHandle GET_VISIBLE_CHUNK = NMS.getMethodHandle(PlayerChunkMap.class, "getVisibleChunk",
true, long.class);
private static final MethodHandle I = NMS.getGetter(EntityTracker.class, "trackingDistance");
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 VIEW_DISTANCE = NMS.getGetter(PlayerChunkMap.class, "viewDistance");
private static final MethodHandle TRACKER_ENTRY_SETTER = NMS.getSetter(EntityTracker.class, "trackerEntry");
private static final MethodHandle TRACKING_DISTANCE = NMS.getGetter(EntityTracker.class, "trackingDistance");
}

View File

@ -0,0 +1,39 @@
package net.citizensnpcs.nms.v1_14_R1.util;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.entity.Player;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntityTrackerEntry;
import net.minecraft.server.v1_14_R1.Packet;
import net.minecraft.server.v1_14_R1.PlayerConnection;
import net.minecraft.server.v1_14_R1.WorldServer;
public class TablistRemovingTrackerEntry extends EntityTrackerEntry {
private final Entity tracker;
public TablistRemovingTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag,
Consumer<Packet<?>> consumer, Set<EntityPlayer> trackedPlayers) {
super(worldserver, entity, i, flag, consumer, trackedPlayers);
this.tracker = entity;
}
@Override
public void b(EntityPlayer entityplayer) {
PlayerConnection playerconnection = entityplayer.playerConnection;
if (!tracker.dead) {
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}
this.a(playerconnection::sendPacket, entityplayer);
this.tracker.b(entityplayer);
entityplayer.d(this.tracker);
if (!tracker.dead && Setting.DISABLE_TABLIST.asBoolean()) {
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}
}
}

View File

@ -2,94 +2,38 @@ package net.citizensnpcs.nms.v1_15_R1.util;
import java.lang.invoke.MethodHandle;
import org.bukkit.entity.Player;
import net.citizensnpcs.nms.v1_15_R1.entity.EntityHumanNPC;
import net.citizensnpcs.npc.skin.SkinnableEntity;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_15_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.EntityTrackerEntry;
import net.minecraft.server.v1_15_R1.PlayerChunk;
import net.minecraft.server.v1_15_R1.PlayerChunkMap;
import net.minecraft.server.v1_15_R1.PlayerChunkMap.EntityTracker;
import net.minecraft.server.v1_15_R1.Vec3D;
public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
private final PlayerChunkMap map;
private final Entity tracker;
private final EntityTrackerEntry trackerEntry;
private final int trackingDistance;
public PlayerlistTracker(PlayerChunkMap map, Entity entity, int i, int j, boolean flag) {
map.super(entity, i, j, flag);
this.map = map;
this.tracker = getTracker(this);
this.trackerEntry = getTrackerEntry(this);
this.trackingDistance = i;
setTrackerEntry(new TablistRemovingTrackerEntry(map.world, entity, j, flag, this::broadcast, trackedPlayers));
}
public PlayerlistTracker(PlayerChunkMap map, EntityTracker entry) {
this(map, getTracker(entry), getTrackingDistance(entry), getD(entry), getE(entry));
}
private int getb(ChunkCoordIntPair chunkcoordintpair, EntityPlayer entityplayer, boolean b) {
private void setTrackerEntry(EntityTrackerEntry entry) {
try {
return (int) B.invoke(chunkcoordintpair, entityplayer, b);
TRACKER_ENTRY_SETTER.invoke(this, entry);
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private int getViewDistance(PlayerChunkMap map2) {
try {
return (int) VIEW_DISTANCE.invoke(map2);
} catch (Throwable e) {
e.printStackTrace();
}
return 0;
}
private PlayerChunk getVisibleChunk(long pair) {
try {
return (PlayerChunk) GET_VISIBLE_CHUNK.invoke(map, pair);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
@Override
public void updatePlayer(final EntityPlayer entityplayer) {
if (entityplayer instanceof EntityHumanNPC)
return; // prevent updates to NPC "viewers"
Entity tracker = getTracker(this);
final Vec3D vec3d = new Vec3D(entityplayer.locX(), entityplayer.locY(), entityplayer.locZ())
.d(this.trackerEntry.b());
final int i = Math.min(this.trackingDistance, (getViewDistance(map) - 1) * 16);
final boolean flag = vec3d.x >= -i && vec3d.x <= i && vec3d.z >= -i && vec3d.z <= i
&& this.tracker.a(entityplayer);
if (entityplayer != tracker && flag && tracker instanceof SkinnableEntity) {
/* boolean flag1 = this.tracker.attachedToPlayer;
if (!flag1) {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ);
PlayerChunk playerchunk = getVisibleChunk(chunkcoordintpair.pair());
if (playerchunk.getChunk() != null) {
flag1 = getb(chunkcoordintpair, entityplayer, false) <= getViewDistance(map);
}
}*/
if (!this.trackedPlayers.contains(entityplayer)) {
SkinnableEntity skinnable = (SkinnableEntity) tracker;
Player player = skinnable.getBukkitEntity();
if (entityplayer.getBukkitEntity().canSee(player)) {
skinnable.getSkinTracker().updateViewer(entityplayer.getBukkitEntity());
}
}
if (!(entityplayer instanceof EntityHumanNPC)) {
// prevent updates to NPC "viewers"
super.updatePlayer(entityplayer);
}
super.updatePlayer(entityplayer);
}
private static int getD(EntityTracker entry) {
@ -119,15 +63,6 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return null;
}
private static EntityTrackerEntry getTrackerEntry(EntityTracker entry) {
try {
return (EntityTrackerEntry) TRACKER_ENTRY.invoke(entry);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
private static int getTrackingDistance(EntityTracker entry) {
try {
return (Integer) TRACKING_DISTANCE.invoke(entry);
@ -137,14 +72,10 @@ public class PlayerlistTracker extends PlayerChunkMap.EntityTracker {
return 0;
}
private static final MethodHandle B = NMS.getMethodHandle(PlayerChunkMap.class, "b", true, ChunkCoordIntPair.class,
EntityPlayer.class, boolean.class);
private static final MethodHandle D = NMS.getGetter(EntityTrackerEntry.class, "d");
private static final MethodHandle E = NMS.getGetter(EntityTrackerEntry.class, "e");
private static final MethodHandle GET_VISIBLE_CHUNK = NMS.getMethodHandle(PlayerChunkMap.class, "getVisibleChunk",
true, long.class);
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 TRACKER_ENTRY_SETTER = NMS.getSetter(EntityTracker.class, "trackerEntry");
private static final MethodHandle TRACKING_DISTANCE = NMS.getGetter(EntityTracker.class, "trackingDistance");
private static final MethodHandle VIEW_DISTANCE = NMS.getGetter(PlayerChunkMap.class, "viewDistance");
}

View File

@ -0,0 +1,39 @@
package net.citizensnpcs.nms.v1_15_R1.util;
import java.util.Set;
import java.util.function.Consumer;
import org.bukkit.entity.Player;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_15_R1.Entity;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.EntityTrackerEntry;
import net.minecraft.server.v1_15_R1.Packet;
import net.minecraft.server.v1_15_R1.PlayerConnection;
import net.minecraft.server.v1_15_R1.WorldServer;
public class TablistRemovingTrackerEntry extends EntityTrackerEntry {
private final Entity tracker;
public TablistRemovingTrackerEntry(WorldServer worldserver, Entity entity, int i, boolean flag,
Consumer<Packet<?>> consumer, Set<EntityPlayer> trackedPlayers) {
super(worldserver, entity, i, flag, consumer, trackedPlayers);
this.tracker = entity;
}
@Override
public void b(EntityPlayer entityplayer) {
PlayerConnection playerconnection = entityplayer.playerConnection;
if (!tracker.dead) {
NMS.sendTabListAdd(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}
this.a(playerconnection::sendPacket, entityplayer);
this.tracker.b(entityplayer);
entityplayer.d(this.tracker);
if (!tracker.dead && Setting.DISABLE_TABLIST.asBoolean()) {
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
}
}
}