Fix some bugs

This commit is contained in:
fullwall 2015-07-19 14:51:51 +08:00
parent 27eb290eb3
commit 62a9cad24d
9 changed files with 176 additions and 55 deletions

View File

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

View File

@ -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<String, Collection<Property>> 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) {

View File

@ -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", "<e>"),
KEEP_CHUNKS_LOADED("npc.chunks.always-keep-loaded", false),
LOCALE("general.translation.locale", ""),

View File

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

View File

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

View File

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

View File

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

View File

@ -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 {

View File

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