From 62a9cad24de9be4e8bd7397bc650d148c796475b Mon Sep 17 00:00:00 2001 From: fullwall Date: Sun, 19 Jul 2015 14:51:51 +0800 Subject: [PATCH] Fix some bugs --- src/main/java/net/citizensnpcs/Citizens.java | 2 +- .../java/net/citizensnpcs/EventListen.java | 85 ++++++++++++++++--- src/main/java/net/citizensnpcs/Settings.java | 5 +- .../citizensnpcs/commands/NPCCommands.java | 5 ++ .../net/citizensnpcs/npc/CitizensNPC.java | 22 ++--- .../npc/ai/MCNavigationStrategy.java | 1 + .../npc/entity/CreeperController.java | 20 +++-- src/main/java/net/citizensnpcs/util/NMS.java | 71 ++++++++++++---- .../util/nms/PlayerlistTrackerEntry.java | 20 +++-- 9 files changed, 176 insertions(+), 55 deletions(-) diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java index c0e3b3a0f..d49183930 100644 --- a/src/main/java/net/citizensnpcs/Citizens.java +++ b/src/main/java/net/citizensnpcs/Citizens.java @@ -105,7 +105,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { try { npc.despawn(DespawnReason.REMOVAL); for (Trait trait : npc.getTraits()) { - trait.onRemove(); + trait.onDespawn(); } } catch (Throwable e) { e.printStackTrace(); diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index 460e5efa1..a7e76525f 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -1,12 +1,16 @@ package net.citizensnpcs; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -34,6 +38,7 @@ import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; +import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scoreboard.Team; @@ -41,9 +46,13 @@ import com.google.common.base.Predicates; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.ListMultimap; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.event.CitizensDeserialiseMetaEvent; +import net.citizensnpcs.api.event.CitizensSerialiseMetaEvent; import net.citizensnpcs.api.event.CommandSenderCreateNPCEvent; import net.citizensnpcs.api.event.DespawnReason; import net.citizensnpcs.api.event.EntityTargetNPCEvent; @@ -62,6 +71,7 @@ import net.citizensnpcs.api.event.PlayerCreateNPCEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPCRegistry; import net.citizensnpcs.api.trait.trait.Owner; +import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.editor.Editor; import net.citizensnpcs.trait.Controllable; @@ -249,6 +259,57 @@ public class EventListen implements Listener { Bukkit.getPluginManager().callEvent(new EntityTargetNPCEvent(event, npc)); } + @EventHandler + public void onMetaDeserialise(CitizensDeserialiseMetaEvent event) { + if (event.getKey().keyExists("skull")) { + String owner = event.getKey().getString("skull.owner", ""); + UUID uuid = event.getKey().keyExists("skull.uuid") ? UUID.fromString(event.getKey().getString("skull.uuid")) + : null; + GameProfile profile = new GameProfile(uuid, owner); + for (DataKey sub : event.getKey().getRelative("skull.properties").getSubKeys()) { + String propertyName = sub.name(); + for (DataKey property : sub.getIntegerSubKeys()) { + profile.getProperties().put(propertyName, + new Property(property.getString("name"), property.getString("value"), + property.keyExists("signature") ? property.getString("signature") : null)); + } + } + SkullMeta meta = (SkullMeta) Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM); + NMS.setProfile(meta, profile); + event.getItemStack().setItemMeta(meta); + } + } + + @EventHandler + public void onMetaSerialise(CitizensSerialiseMetaEvent event) { + if (event.getMeta() instanceof SkullMeta) { + SkullMeta meta = (SkullMeta) event.getMeta(); + GameProfile profile = NMS.getProfile(meta); + if (profile == null) + return; + if (profile.getName() != null) { + event.getKey().setString("skull.owner", profile.getName()); + } + if (profile.getId() != null) { + event.getKey().setString("skull.uuid", profile.getId().toString()); + } + if (profile.getProperties() != null) { + for (Entry> entry : profile.getProperties().asMap().entrySet()) { + DataKey relative = event.getKey().getRelative("skull.properties." + entry.getKey()); + int i = 0; + for (Property value : entry.getValue()) { + relative.getRelative(i).setString("name", value.getName()); + if (value.getSignature() != null) { + relative.getRelative(i).setString("signature", value.getSignature()); + } + relative.getRelative(i).setString("value", value.getValue()); + i++; + } + } + } + } + } + @EventHandler public void onNeedsRespawn(NPCNeedsRespawnEvent event) { ChunkCoord coord = toCoord(event.getSpawnLocation()); @@ -419,18 +480,20 @@ public class EventListen implements Listener { NMS.sendPacket(player, new PacketPlayOutPlayerInfo( PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, nearbyNPC)); } - new BukkitRunnable() { - @Override - public void run() { - if (!player.isValid()) - return; - for (EntityPlayer nearbyNPC : nearbyNPCs) { - if (nearbyNPC.isAlive()) - NMS.sendPacket(player, new PacketPlayOutPlayerInfo( - PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, nearbyNPC)); + if (Setting.DISABLE_TABLIST.asBoolean()) { + new BukkitRunnable() { + @Override + public void run() { + if (!player.isValid()) + return; + for (EntityPlayer nearbyNPC : nearbyNPCs) { + if (nearbyNPC.isAlive()) + NMS.sendPacket(player, new PacketPlayOutPlayerInfo( + PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, nearbyNPC)); + } } - } - }.runTaskLater(CitizensAPI.getPlugin(), 2); + }.runTaskLater(CitizensAPI.getPlugin(), 2); + } } private boolean spawn(NPC npc) { diff --git a/src/main/java/net/citizensnpcs/Settings.java b/src/main/java/net/citizensnpcs/Settings.java index 10f8b02bd..05843b0f4 100644 --- a/src/main/java/net/citizensnpcs/Settings.java +++ b/src/main/java/net/citizensnpcs/Settings.java @@ -4,13 +4,13 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import com.google.common.collect.Lists; + import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.api.util.Storage; import net.citizensnpcs.api.util.YamlStorage; -import com.google.common.collect.Lists; - public class Settings { private final Storage config; private final DataKey root; @@ -83,6 +83,7 @@ public class Settings { value = list; } }, + DISABLE_TABLIST("npc.tablist.disable", true), HIGHLIGHT_COLOUR("general.color-scheme.message-highlight", ""), KEEP_CHUNKS_LOADED("npc.chunks.always-keep-loaded", false), LOCALE("general.translation.locale", ""), diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 316ce9410..c4c28b140 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -851,6 +851,11 @@ public class NPCCommands { public void name(CommandContext args, CommandSender sender, NPC npc) { LivingEntity entity = (LivingEntity) npc.getEntity(); entity.setCustomNameVisible(!entity.isCustomNameVisible()); + if (!entity.isCustomNameVisible()) { + entity.setCustomName(""); + } else { + entity.setCustomName(npc.getFullName()); + } npc.data().setPersistent(NPC.NAMEPLATE_VISIBLE_METADATA, entity.isCustomNameVisible()); Messaging.sendTr(sender, Messages.NAMEPLATE_VISIBILITY_TOGGLED); } diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index 8dc947828..8a71d4424 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -252,16 +252,18 @@ public class CitizensNPC extends AbstractNPC { Arrays.asList((Packet) new PacketPlayOutPlayerInfo( PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, player.getHandle())), 200.0); - new BukkitRunnable() { - @Override - public void run() { - NMS.sendPacketsNearby(player, player.getLocation(), - Arrays.asList((Packet) new PacketPlayOutPlayerInfo( - PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, - player.getHandle())), - 200.0); - } - }.runTaskLater(CitizensAPI.getPlugin(), 2); + if (Setting.DISABLE_TABLIST.asBoolean()) { + new BukkitRunnable() { + @Override + public void run() { + NMS.sendPacketsNearby(player, player.getLocation(), + Arrays.asList((Packet) new PacketPlayOutPlayerInfo( + PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, + player.getHandle())), + 200.0); + } + }.runTaskLater(CitizensAPI.getPlugin(), 2); + } } }.runTaskLater(CitizensAPI.getPlugin(), 2); } diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java index add45a887..0069d9595 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java @@ -67,6 +67,7 @@ public class MCNavigationStrategy extends AbstractPathStrategy { navigation.a(target.getX(), target.getY(), target.getZ(), parameters.speed()); lastSpeed = parameters.speed(); } + navigation.a(parameters.speed()); parameters.run(); if (distanceSquared() < parameters.distanceMargin()) { stop(); diff --git a/src/main/java/net/citizensnpcs/npc/entity/CreeperController.java b/src/main/java/net/citizensnpcs/npc/entity/CreeperController.java index f36793636..561ff591b 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CreeperController.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CreeperController.java @@ -1,5 +1,12 @@ package net.citizensnpcs.npc.entity; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_8_R3.CraftServer; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreeper; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.entity.Creeper; +import org.bukkit.util.Vector; + import net.citizensnpcs.api.event.NPCPushEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.npc.CitizensNPC; @@ -10,17 +17,11 @@ import net.citizensnpcs.util.Util; import net.minecraft.server.v1_8_R3.Block; import net.minecraft.server.v1_8_R3.BlockPosition; import net.minecraft.server.v1_8_R3.EntityCreeper; +import net.minecraft.server.v1_8_R3.EntityHuman; import net.minecraft.server.v1_8_R3.EntityLightning; import net.minecraft.server.v1_8_R3.NBTTagCompound; import net.minecraft.server.v1_8_R3.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_8_R3.CraftServer; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreeper; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.entity.Creeper; -import org.bukkit.util.Vector; - public class CreeperController extends MobEntityController { public CreeperController() { super(EntityCreeperNPC.class); @@ -68,6 +69,11 @@ public class CreeperController extends MobEntityController { } } + @Override + protected boolean a(EntityHuman entityhuman) { + return npc == null || !npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true) ? super.a(entityhuman) : false; + } + @Override protected String bo() { return npc == null ? super.bo() : npc.data().get(NPC.HURT_SOUND_METADATA, super.bo()); diff --git a/src/main/java/net/citizensnpcs/util/NMS.java b/src/main/java/net/citizensnpcs/util/NMS.java index 5d2b4d1e6..107c84f6f 100644 --- a/src/main/java/net/citizensnpcs/util/NMS.java +++ b/src/main/java/net/citizensnpcs/util/NMS.java @@ -11,6 +11,26 @@ import java.util.Random; import java.util.Set; import java.util.WeakHashMap; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_8_R3.CraftServer; +import org.bukkit.craftbukkit.v1_8_R3.CraftSound; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.plugin.PluginLoadOrder; + +import com.mojang.authlib.GameProfile; + +import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.command.exception.CommandException; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.util.Messaging; @@ -45,22 +65,6 @@ import net.minecraft.server.v1_8_R3.PathfinderGoalSelector; import net.minecraft.server.v1_8_R3.World; import net.minecraft.server.v1_8_R3.WorldServer; -import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.craftbukkit.v1_8_R3.CraftServer; -import org.bukkit.craftbukkit.v1_8_R3.CraftSound; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Horse; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.plugin.PluginLoadOrder; - @SuppressWarnings("unchecked") public class NMS { private NMS() { @@ -301,6 +305,22 @@ public class NMS { : handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getNavigation() : null; } + public static GameProfile getProfile(SkullMeta meta) { + if (SKULL_PROFILE_FIELD == null) { + try { + SKULL_PROFILE_FIELD = meta.getClass().getDeclaredField("profile"); + SKULL_PROFILE_FIELD.setAccessible(true); + } catch (Exception e) { + return null; + } + } + try { + return (GameProfile) SKULL_PROFILE_FIELD.get(meta); + } catch (Exception e) { + return null; + } + } + public static String getSound(String flag) throws CommandException { try { String ret = CraftSound.getSound(Sound.valueOf(flag.toUpperCase())); @@ -487,6 +507,8 @@ public class NMS { } public static void sendPlayerlistPacket(boolean showInPlayerlist, Player npc) { + if (!showInPlayerlist && !Setting.DISABLE_TABLIST.asBoolean()) + return; PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo( showInPlayerlist ? EnumPlayerInfoAction.ADD_PLAYER : EnumPlayerInfoAction.REMOVE_PLAYER, ((CraftPlayer) npc).getHandle()); @@ -526,6 +548,21 @@ public class NMS { handle.aL = yaw; } + public static void setProfile(SkullMeta meta, GameProfile profile) { + if (SKULL_PROFILE_FIELD == null) { + try { + SKULL_PROFILE_FIELD = meta.getClass().getDeclaredField("profile"); + SKULL_PROFILE_FIELD.setAccessible(true); + } catch (Exception e) { + return; + } + } + try { + SKULL_PROFILE_FIELD.set(meta, profile); + } catch (Exception e) { + } + } + public static void setShouldJump(org.bukkit.entity.Entity entity) { Entity handle = getHandle(entity); if (handle == null) @@ -663,6 +700,8 @@ 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 SKULL_PROFILE_FIELD; + private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c"); static { diff --git a/src/main/java/net/citizensnpcs/util/nms/PlayerlistTrackerEntry.java b/src/main/java/net/citizensnpcs/util/nms/PlayerlistTrackerEntry.java index 8f11e6030..3e6758b0e 100644 --- a/src/main/java/net/citizensnpcs/util/nms/PlayerlistTrackerEntry.java +++ b/src/main/java/net/citizensnpcs/util/nms/PlayerlistTrackerEntry.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; +import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.util.NMS; import net.minecraft.server.v1_8_R3.Entity; @@ -34,14 +35,17 @@ public class PlayerlistTrackerEntry extends EntityTrackerEntry { } entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo( PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, (EntityPlayer) this.tracker)); - new BukkitRunnable() { - @Override - public void run() { - entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo( - PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, - (EntityPlayer) tracker)); - } - }.runTaskLater(CitizensAPI.getPlugin(), 2); + + if (Setting.DISABLE_TABLIST.asBoolean()) { + new BukkitRunnable() { + @Override + public void run() { + entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo( + PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, + (EntityPlayer) tracker)); + } + }.runTaskLater(CitizensAPI.getPlugin(), 2); + } } } }