Try playerlist handling via EntityTrackerEntry instead of adhoc event listening

This commit is contained in:
fullwall 2015-01-03 13:37:34 +08:00
parent db205f52ff
commit a46b1f440b
7 changed files with 96 additions and 127 deletions

View File

@ -49,10 +49,7 @@ import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
@ -275,30 +272,6 @@ public class EventListen implements Listener {
Bukkit.getPluginManager().callEvent(rightClickEvent);
}
@EventHandler(ignoreCancelled = true)
public void onPlayerJoin(final PlayerJoinEvent event) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
for (NPC npc : getAllNPCs()) {
if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) {
NMS.sendPlayerlistPacket(true, event.getPlayer(), npc);
}
}
}
}, 10);
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
for (NPC npc : getAllNPCs()) {
if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) {
NMS.sendPlayerlistPacket(false, event.getPlayer(), npc);
}
}
}
}, 60);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerQuit(PlayerQuitEvent event) {
Editor.leave(event.getPlayer());
@ -310,50 +283,6 @@ public class EventListen implements Listener {
}
}
@EventHandler
public void onPlayerTeleports(PlayerTeleportEvent event) {
Location from = roundLocation(event.getFrom());
Location to = roundLocation(event.getTo());
if (from.equals(to)) {
return; // Don't fire on every movement, just full block+.
}
int maxRad = 50 * 50; // TODO: Adjust me to perfection
Location npcPos = new Location(null, 0, 0, 0);
for (final NPC npc : getAllNPCs()) {
if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) {
npc.getEntity().getLocation(npcPos);
if ((to.getWorld() == npcPos.getWorld() && npcPos.distanceSquared(to) < maxRad)
&& ((from.getWorld() == npcPos.getWorld() && npcPos.distanceSquared(from) > maxRad) || from
.getWorld() != to.getWorld())) {
NMS.showNPCReset(event.getPlayer(), npc);
}
}
}
}
@EventHandler
public void onPlayerWalks(final PlayerMoveEvent event) {
Location from = roundLocation(event.getFrom());
Location to = roundLocation(event.getTo());
if (from.equals(to)) {
return;
}
if (from.getWorld() != to.getWorld()) {
return; // Ignore cross-world movement
}
int maxRad = 50 * 50; // TODO: Adjust me to perfection
Location loc = new Location(null, 0, 0, 0);
for (final NPC npc : getAllNPCs()) {
if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) {
npc.getEntity().getLocation(loc);
if (from.getWorld() == loc.getWorld() && loc.distanceSquared(to) < maxRad
&& loc.distanceSquared(from) > maxRad) {
NMS.showNPCReset(event.getPlayer(), npc);
}
}
}
}
@EventHandler(ignoreCancelled = true)
public void onVehicleEnter(VehicleEnterEvent event) {
if (!npcRegistry.isNPC(event.getEntered()))

View File

@ -215,6 +215,9 @@ public class CitizensNPC extends AbstractNPC {
if (NMS.getStepHeight(entity) < 1) {
NMS.setStepHeight(NMS.getHandle(entity), 1);
}
if (getEntity() instanceof Player) {
NMS.replaceTrackerEntry((Player) getEntity());
}
}
return true;
}

View File

@ -291,9 +291,9 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
break;
}
}
// NMS.sendToOnline(getListPacket(getBukkitEntity(), true));
NMS.sendPlayerlistPacket(true, getBukkitEntity(), npc);
if (otherOnline != null) {
// NMS.sendToOnline(getListPacket(otherOnline, false));
NMS.sendPlayerlistPacket(false, otherOnline, npc);
}
NMS.sendPacketsNearby(getBukkitEntity(), current, packets);
}

View File

@ -26,7 +26,6 @@ import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R1.CraftServer;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import com.google.common.collect.Iterables;
@ -83,15 +82,6 @@ public class HumanController extends AbstractEntityController {
}
}, 1);
handle.getBukkitEntity().setSleepingIgnored(true);
NMS.sendPlayerlistPacket(true, null, handle.getBukkitEntity());
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
if (npc.isSpawned() && npc.getEntity().getType() == EntityType.PLAYER) {
NMS.sendPlayerlistPacket(false, null, npc);
}
}
}, 2);
return handle.getBukkitEntity();
}

View File

@ -81,17 +81,9 @@ public class WitherController extends MobEntityController {
}
@Override
protected void D() {
protected void E() {
if (npc == null) {
super.D();
}
}
@Override
public void doTick() {
super.doTick();
if (npc != null) {
npc.update();
super.E();
}
}
@ -129,6 +121,16 @@ public class WitherController extends MobEntityController {
return npc;
}
@Override
public void m() {
if (npc == null) {
super.m();
} else {
NMS.updateAI(this);
npc.update();
}
}
@Override
protected String z() {
return npc == null || !npc.data().has(NPC.AMBIENT_SOUND_METADATA) ? super.z() : npc.data().get(

View File

@ -8,15 +8,16 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.WeakHashMap;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.command.exception.CommandException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.npc.entity.EntityHumanNPC;
import net.citizensnpcs.npc.network.EmptyChannel;
import net.citizensnpcs.util.nms.PlayerlistTrackerEntry;
import net.minecraft.server.v1_8_R1.AttributeInstance;
import net.minecraft.server.v1_8_R1.Block;
import net.minecraft.server.v1_8_R1.BlockPosition;
@ -30,6 +31,8 @@ import net.minecraft.server.v1_8_R1.EntityInsentient;
import net.minecraft.server.v1_8_R1.EntityLiving;
import net.minecraft.server.v1_8_R1.EntityMinecartAbstract;
import net.minecraft.server.v1_8_R1.EntityPlayer;
import net.minecraft.server.v1_8_R1.EntityTracker;
import net.minecraft.server.v1_8_R1.EntityTrackerEntry;
import net.minecraft.server.v1_8_R1.EntityTypes;
import net.minecraft.server.v1_8_R1.EnumPlayerInfoAction;
import net.minecraft.server.v1_8_R1.GenericAttributes;
@ -37,11 +40,10 @@ import net.minecraft.server.v1_8_R1.MathHelper;
import net.minecraft.server.v1_8_R1.NavigationAbstract;
import net.minecraft.server.v1_8_R1.NetworkManager;
import net.minecraft.server.v1_8_R1.Packet;
import net.minecraft.server.v1_8_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R1.PacketPlayOutNamedEntitySpawn;
import net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo;
import net.minecraft.server.v1_8_R1.PathfinderGoalSelector;
import net.minecraft.server.v1_8_R1.World;
import net.minecraft.server.v1_8_R1.WorldServer;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
@ -353,9 +355,25 @@ public class NMS {
((CraftServer) Bukkit.getServer()).getHandle().players.remove(handle);
}
private static void sendDestroyPacket(final Player player, final NPC npc) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityDestroy(npc.getEntity()
.getEntityId()));
@SuppressWarnings("rawtypes")
public static void replaceTrackerEntry(Player player) {
WorldServer server = (WorldServer) NMS.getHandle(player).getWorld();
EntityTrackerEntry entry = (EntityTrackerEntry) server.getTracker().trackedEntities.get(player.getEntityId());
if (entry == null)
return;
PlayerlistTrackerEntry replace = new PlayerlistTrackerEntry(entry);
server.getTracker().trackedEntities.a(player.getEntityId(), replace);
if (TRACKED_ENTITY_SET != null) {
try {
Set set = (Set) TRACKED_ENTITY_SET.get(server.getTracker());
set.remove(entry);
set.add(replace);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public static void sendPacket(Player player, Packet packet) {
@ -413,11 +431,6 @@ public class NMS {
}
}
private static void sendSpawnPacket(final Player player, final NPC npc) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutNamedEntitySpawn(
((CraftPlayer) npc.getEntity()).getHandle()));
}
public static void sendToOnline(Packet... packets) {
Validate.notNull(packets, "packets cannot be null");
for (Player player : Bukkit.getOnlinePlayers()) {
@ -493,29 +506,6 @@ public class NMS {
return false;
}
public static void showNPCReset(final Player player, final NPC npc) {
sendDestroyPacket(player, npc);
sendPlayerlistPacket(true, player, npc);
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
if (player.isOnline() && player.isValid() && npc.isSpawned()
&& npc.getEntity().getType() == EntityType.PLAYER) {
sendSpawnPacket(player, npc);
}
}
}, 1);
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
if (player.isOnline() && player.isValid() && npc.isSpawned()
&& npc.getEntity().getType() == EntityType.PLAYER) {
sendPlayerlistPacket(false, player, npc);
}
}
}, 10);
}
public static org.bukkit.entity.Entity spawnCustomEntity(org.bukkit.World world, Location at,
Class<? extends Entity> clazz, EntityType type) {
World handle = ((CraftWorld) world).getHandle();
@ -605,6 +595,7 @@ public class NMS {
}
private static final float DEFAULT_SPEED = 1F;
private static Map<Class<?>, Integer> ENTITY_CLASS_TO_INT;
private static Map<Class<?>, String> ENTITY_CLASS_TO_NAME;
private static final Map<Class<?>, Constructor<?>> ENTITY_CONSTRUCTOR_CACHE = new WeakHashMap<Class<?>, Constructor<?>>();
@ -619,6 +610,7 @@ public class NMS {
private static final Location PACKET_CACHE_LOCATION = new Location(null, 0, 0, 0);
private static Field PATHFINDING_RANGE = getField(NavigationAbstract.class, "a");
private static final Random RANDOM = Util.getFastRandom();
private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c");
static {
try {

View File

@ -0,0 +1,53 @@
package net.citizensnpcs.util.nms;
import java.lang.reflect.Field;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_8_R1.Entity;
import net.minecraft.server.v1_8_R1.EntityPlayer;
import net.minecraft.server.v1_8_R1.EntityTrackerEntry;
import net.minecraft.server.v1_8_R1.EnumPlayerInfoAction;
import net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo;
import org.bukkit.entity.Player;
public class PlayerlistTrackerEntry extends EntityTrackerEntry {
public PlayerlistTrackerEntry(Entity entity, int i, int j, boolean flag) {
super(entity, i, j, flag);
}
public PlayerlistTrackerEntry(EntityTrackerEntry entry) {
this(entry.tracker, entry.b, entry.c, getU(entry));
}
@Override
public void updatePlayer(EntityPlayer entityplayer) {
if (entityplayer != this.tracker && c(entityplayer)) {
if (!this.trackedPlayers.contains(entityplayer)
&& ((entityplayer.u().getPlayerChunkMap().a(entityplayer, this.tracker.ae, this.tracker.ag)) || (this.tracker.attachedToPlayer))) {
if ((this.tracker instanceof EntityPlayer)) {
Player player = ((EntityPlayer) this.tracker).getBukkitEntity();
if (!entityplayer.getBukkitEntity().canSee(player)) {
return;
}
entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(
EnumPlayerInfoAction.ADD_PLAYER, (EntityPlayer) this.tracker));
}
}
}
super.updatePlayer(entityplayer);
}
private static boolean getU(EntityTrackerEntry entry) {
try {
return (Boolean) U.get(entry);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
private static Field U = NMS.getField(EntityTrackerEntry.class, "u");
}