Skip to content

Commit

Permalink
Try playerlist handling via EntityTrackerEntry instead of adhoc event…
Browse files Browse the repository at this point in the history
… listening
  • Loading branch information
fullwall committed Jan 3, 2015
1 parent c5b50f0 commit e4c5ed4
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 127 deletions.
71 changes: 0 additions & 71 deletions src/main/java/net/citizensnpcs/EventListen.java
Expand Up @@ -49,10 +49,7 @@
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;
Expand Down Expand Up @@ -275,30 +272,6 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
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());
Expand All @@ -310,50 +283,6 @@ public void onPlayerQuit(PlayerQuitEvent event) {
}
}

@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()))
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/net/citizensnpcs/npc/CitizensNPC.java
Expand Up @@ -215,6 +215,9 @@ public boolean spawn(Location at) {
if (NMS.getStepHeight(entity) < 1) {
NMS.setStepHeight(NMS.getHandle(entity), 1);
}
if (getEntity() instanceof Player) {
NMS.replaceTrackerEntry((Player) getEntity());
}
}
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java
Expand Up @@ -291,9 +291,9 @@ private void updatePackets(boolean navigating) {
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);
}
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/net/citizensnpcs/npc/entity/HumanController.java
Expand Up @@ -26,7 +26,6 @@
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;
Expand Down Expand Up @@ -83,15 +82,6 @@ public void run() {
}
}, 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();
}

Expand Down
22 changes: 12 additions & 10 deletions src/main/java/net/citizensnpcs/npc/entity/WitherController.java
Expand Up @@ -81,17 +81,9 @@ public boolean d(NBTTagCompound save) {
}

@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();
}
}

Expand Down Expand Up @@ -129,6 +121,16 @@ public NPC getNPC() {
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(
Expand Down
60 changes: 26 additions & 34 deletions src/main/java/net/citizensnpcs/util/NMS.java
Expand Up @@ -8,15 +8,16 @@
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;
Expand All @@ -30,18 +31,19 @@
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;
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;
Expand Down Expand Up @@ -353,9 +355,25 @@ public static void removeFromServerPlayerList(Player player) {
((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) {
Expand Down Expand Up @@ -413,11 +431,6 @@ public static void sendPlayerlistPacket(boolean showInPlayerlist, Player player,
}
}

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()) {
Expand Down Expand Up @@ -493,29 +506,6 @@ public static boolean shouldJump(net.minecraft.server.v1_8_R1.Entity entity) {
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();
Expand Down Expand Up @@ -605,6 +595,7 @@ public static void updatePathfindingRange(NPC npc, float pathfindingRange) {
}

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<?>>();
Expand All @@ -619,6 +610,7 @@ public static void updatePathfindingRange(NPC npc, float pathfindingRange) {
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 {
Expand Down
@@ -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");
}

0 comments on commit e4c5ed4

Please sign in to comment.