Force skin updates on /npc skin -p

This commit is contained in:
fullwall 2016-05-20 16:41:02 +08:00
parent 5a066d27b5
commit 01ed1dd0d4
6 changed files with 79 additions and 48 deletions

View File

@ -1481,7 +1481,7 @@ public class NPCCommands {
SkinnableEntity skinnable = NMS.getSkinnable(npc.getEntity()); SkinnableEntity skinnable = NMS.getSkinnable(npc.getEntity());
if (skinnable != null) { if (skinnable != null) {
skinnable.setSkinName(skinName); skinnable.setSkinName(skinName, args.hasFlag('p'));
} }
} }
} }

View File

@ -348,10 +348,15 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
@Override @Override
public void setSkinName(String name) { public void setSkinName(String name) {
setSkinName(name, false);
}
@Override
public void setSkinName(String name, boolean forceUpdate) {
Preconditions.checkNotNull(name); Preconditions.checkNotNull(name);
npc.data().setPersistent(NPC.PLAYER_SKIN_UUID_METADATA, name.toLowerCase()); npc.data().setPersistent(NPC.PLAYER_SKIN_UUID_METADATA, name.toLowerCase());
skinTracker.notifySkinChange(); skinTracker.notifySkinChange(forceUpdate);
} }
public void setTargetLook(Entity target, float yawOffset, float renderOffset) { public void setTargetLook(Entity target, float yawOffset, float renderOffset) {
@ -455,8 +460,14 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
public void setSkinName(String name) { public void setSkinName(String name) {
((SkinnableEntity) this.entity).setSkinName(name); ((SkinnableEntity) this.entity).setSkinName(name);
} }
@Override
public void setSkinName(String skinName, boolean forceUpdate) {
((SkinnableEntity) this.entity).setSkinName(skinName, forceUpdate);
}
} }
private static final float EPSILON = 0.005F; private static final float EPSILON = 0.005F;
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0); private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
} }

View File

@ -1,6 +1,7 @@
package net.citizensnpcs.npc.profile; package net.citizensnpcs.npc.profile;
import java.util.Collection; import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -45,10 +46,8 @@ public class ProfileFetcher {
} }
repo.findProfilesByNames(playerNames, Agent.MINECRAFT, new ProfileLookupCallback() { repo.findProfilesByNames(playerNames, Agent.MINECRAFT, new ProfileLookupCallback() {
@Override @Override
public void onProfileLookupFailed(GameProfile profile, Exception e) { public void onProfileLookupFailed(GameProfile profile, Exception e) {
if (Messaging.isDebugging()) { if (Messaging.isDebugging()) {
Messaging.debug( Messaging.debug(
"Profile lookup for player '" + profile.getName() + "' failed: " + getExceptionMsg(e)); "Profile lookup for player '" + profile.getName() + "' failed: " + getExceptionMsg(e));
@ -69,7 +68,6 @@ public class ProfileFetcher {
@Override @Override
public void onProfileLookupSucceeded(final GameProfile profile) { public void onProfileLookupSucceeded(final GameProfile profile) {
if (Messaging.isDebugging()) { if (Messaging.isDebugging()) {
Messaging.debug("Fetched profile " + profile.getId() + " for player " + profile.getName()); Messaging.debug("Fetched profile " + profile.getId() + " for player " + profile.getName());
} }
@ -81,7 +79,6 @@ public class ProfileFetcher {
try { try {
request.setResult(NMS.fillProfileProperties(profile, true), ProfileFetchResult.SUCCESS); request.setResult(NMS.fillProfileProperties(profile, true), ProfileFetchResult.SUCCESS);
} catch (Exception e) { } catch (Exception e) {
if (Messaging.isDebugging()) { if (Messaging.isDebugging()) {
Messaging.debug( Messaging.debug(
"Profile lookup for player '" + profile.getName() + "' failed: " + getExceptionMsg(e)); "Profile lookup for player '" + profile.getName() + "' failed: " + getExceptionMsg(e));
@ -114,20 +111,14 @@ public class ProfileFetcher {
PROFILE_THREAD.fetch(name, handler); PROFILE_THREAD.fetch(name, handler);
} }
/**
* Clear all queued and cached requests.
*/
public static void reset() {
initThread();
}
@Nullable @Nullable
private static ProfileRequest findRequest(String name, Collection<ProfileRequest> requests) { private static ProfileRequest findRequest(String name, Collection<ProfileRequest> requests) {
name = name.toLowerCase(); name = name.toLowerCase();
for (ProfileRequest request : requests) { for (ProfileRequest request : requests) {
if (request.getPlayerName().equals(name)) if (request.getPlayerName().equals(name)) {
return request; return request;
}
} }
return null; return null;
} }
@ -138,6 +129,15 @@ public class ProfileFetcher {
return cause != null ? cause : message; return cause != null ? cause : message;
} }
private static void initThread() {
if (THREAD_TASK != null) {
THREAD_TASK.cancel();
}
PROFILE_THREAD = new ProfileFetchThread();
THREAD_TASK = Bukkit.getScheduler().runTaskTimerAsynchronously(CitizensAPI.getPlugin(), PROFILE_THREAD, 21, 20);
}
private static boolean isProfileNotFound(Exception e) { private static boolean isProfileNotFound(Exception e) {
String message = e.getMessage(); String message = e.getMessage();
String cause = e.getCause() != null ? e.getCause().getMessage() : null; String cause = e.getCause() != null ? e.getCause().getMessage() : null;
@ -155,13 +155,11 @@ public class ProfileFetcher {
|| (cause != null && cause.contains("too many requests")); || (cause != null && cause.contains("too many requests"));
} }
private static void initThread() { /**
if (THREAD_TASK != null) * Clear all queued and cached requests.
THREAD_TASK.cancel(); */
public static void reset() {
PROFILE_THREAD = new ProfileFetchThread(); initThread();
THREAD_TASK = Bukkit.getScheduler().runTaskTimerAsynchronously(
CitizensAPI.getPlugin(), PROFILE_THREAD, 21, 20);
} }
private static ProfileFetchThread PROFILE_THREAD; private static ProfileFetchThread PROFILE_THREAD;

View File

@ -44,6 +44,7 @@ public class Skin {
* *
* @param skinName * @param skinName
* The name of the player the skin belongs to. * The name of the player the skin belongs to.
* @param forceUpdate
*/ */
Skin(String skinName) { Skin(String skinName) {
this.skinName = skinName.toLowerCase(); this.skinName = skinName.toLowerCase();
@ -205,6 +206,7 @@ public class Skin {
} }
private void setData(@Nullable GameProfile profile) { private void setData(@Nullable GameProfile profile) {
System.out.println("SET DATA");
if (profile == null) { if (profile == null) {
isValid = false; isValid = false;
return; return;
@ -251,10 +253,26 @@ public class Skin {
* The skinnable entity. * The skinnable entity.
*/ */
public static Skin get(SkinnableEntity entity) { public static Skin get(SkinnableEntity entity) {
return get(entity, false);
}
/**
* Get a skin for a skinnable entity.
*
* <p>
* If a Skin instance does not exist, a new one is created and the skin data is automatically fetched.
* </p>
*
* @param entity
* The skinnable entity.
* @param forceUpdate
* if the skin should be checked via the cache
*/
public static Skin get(SkinnableEntity entity, boolean forceUpdate) {
Preconditions.checkNotNull(entity); Preconditions.checkNotNull(entity);
String skinName = entity.getSkinName().toLowerCase(); String skinName = entity.getSkinName().toLowerCase();
return get(skinName); return get(skinName, forceUpdate);
} }
/** /**
@ -267,7 +285,7 @@ public class Skin {
* @param skinName * @param skinName
* The name of the skin. * The name of the skin.
*/ */
public static Skin get(String skinName) { public static Skin get(String skinName, boolean forceUpdate) {
Preconditions.checkNotNull(skinName); Preconditions.checkNotNull(skinName);
skinName = skinName.toLowerCase(); skinName = skinName.toLowerCase();
@ -279,6 +297,8 @@ public class Skin {
if (skin == null) { if (skin == null) {
skin = new Skin(skinName); skin = new Skin(skinName);
} else if (forceUpdate) {
skin.fetch();
} }
return skin; return skin;

View File

@ -94,28 +94,11 @@ public class SkinPacketTracker {
/** /**
* Notify that the NPC skin has been changed. * Notify that the NPC skin has been changed.
*/ */
public void notifySkinChange() { public void notifySkinChange(boolean forceUpdate) {
this.skin = Skin.get(entity); this.skin = Skin.get(entity, forceUpdate);
skin.applyAndRespawn(entity); skin.applyAndRespawn(entity);
} }
/**
* Invoke when the NPC entity is spawned.
*/
public void onSpawnNPC() {
isRemoved = false;
new BukkitRunnable() {
@Override
public void run() {
if (!entity.getNPC().isSpawned())
return;
double viewDistance = Settings.Setting.NPC_SKIN_VIEW_DISTANCE.asDouble();
updateNearbyViewers(viewDistance);
}
}.runTaskLater(CitizensAPI.getPlugin(), 20);
}
/** /**
* Invoke when the NPC entity is removed. * Invoke when the NPC entity is removed.
* *
@ -139,6 +122,23 @@ public class SkinPacketTracker {
} }
} }
/**
* Invoke when the NPC entity is spawned.
*/
public void onSpawnNPC() {
isRemoved = false;
new BukkitRunnable() {
@Override
public void run() {
if (!entity.getNPC().isSpawned())
return;
double viewDistance = Settings.Setting.NPC_SKIN_VIEW_DISTANCE.asDouble();
updateNearbyViewers(viewDistance);
}
}.runTaskLater(CitizensAPI.getPlugin(), 20);
}
private void scheduleRemovePacket(final PlayerEntry entry) { private void scheduleRemovePacket(final PlayerEntry entry) {
if (isRemoved) if (isRemoved)
return; return;
@ -162,8 +162,7 @@ public class SkinPacketTracker {
} }
private boolean shouldRemoveFromTabList() { private boolean shouldRemoveFromTabList() {
return entity.getNPC().data().get("removefromtablist", return entity.getNPC().data().get("removefromtablist", Settings.Setting.DISABLE_TABLIST.asBoolean());
Settings.Setting.DISABLE_TABLIST.asBoolean());
} }
/** /**

View File

@ -1,9 +1,11 @@
package net.citizensnpcs.npc.skin; package net.citizensnpcs.npc.skin;
import com.mojang.authlib.GameProfile;
import net.citizensnpcs.npc.ai.NPCHolder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.mojang.authlib.GameProfile;
import net.citizensnpcs.npc.ai.NPCHolder;
/** /**
* Interface for player entities that are skinnable. * Interface for player entities that are skinnable.
*/ */
@ -42,8 +44,7 @@ public interface SkinnableEntity extends NPCHolder {
void setSkinFlags(byte flags); void setSkinFlags(byte flags);
/** /**
* Set the name of the player whose skin the NPC * Set the name of the player whose skin the NPC uses.
* uses.
* *
* <p> * <p>
* Setting the skin name automatically updates and respawn the NPC. * Setting the skin name automatically updates and respawn the NPC.
@ -53,4 +54,6 @@ public interface SkinnableEntity extends NPCHolder {
* The skin name. * The skin name.
*/ */
void setSkinName(String name); void setSkinName(String name);
void setSkinName(String skinName, boolean forceUpdate);
} }