Add setSkin for playerdisguise. This may be removed in future versions

This commit is contained in:
libraryaddict 2014-06-01 06:47:05 +12:00
parent 8a9c2fa225
commit 841dab296d
8 changed files with 155 additions and 9 deletions

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>LibsDisguises</groupId>
<artifactId>LibsDisguises</artifactId>
<version>8.2.4</version>
<version>8.2.4-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>

View File

@ -439,7 +439,7 @@ public abstract class Disguise {
}
}
}
DisguiseUtilities.removeGameprofile(name);
DisguiseUtilities.getGameProfiles().remove(name);
}
}
}

View File

@ -1,7 +1,15 @@
package me.libraryaddict.disguise.disguisetypes;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.LibsProfileLookup;
import me.libraryaddict.disguise.utilities.ReflectionManager;
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
public class PlayerDisguise extends TargetedDisguise {
private LibsProfileLookup currentLookup;
private Object gameProfile;
private String playerName;
private String skinToUse;
public PlayerDisguise(String name) {
if (name.length() > 16)
@ -16,9 +24,21 @@ public class PlayerDisguise extends TargetedDisguise {
this.setReplaceSounds(replaceSounds);
}
@Deprecated
public PlayerDisguise(String name, String skinToUse) {
this(name);
setSkin(skinToUse);
}
@Override
public PlayerDisguise clone() {
PlayerDisguise disguise = new PlayerDisguise(getName());
if (disguise.currentLookup == null && disguise.gameProfile != null) {
disguise.skinToUse = getSkin();
disguise.gameProfile = gameProfile;
} else {
disguise.setSkin(getSkin());
}
disguise.setReplaceSounds(isSoundsReplaced());
disguise.setViewSelfDisguise(isSelfDisguiseVisible());
disguise.setHearSelfDisguise(isSelfDisguiseSoundsReplaced());
@ -30,13 +50,66 @@ public class PlayerDisguise extends TargetedDisguise {
return disguise;
}
@Deprecated
public Object getGameProfile() {
if (getSkin() != null) {
if (gameProfile != null) {
return gameProfile;
}
return ReflectionManager.getGameProfile(null, getName());
} else {
return DisguiseUtilities.getProfileFromMojang(getName());
}
}
public String getName() {
return playerName;
}
@Deprecated
public String getSkin() {
return skinToUse;
}
@Override
public boolean isPlayerDisguise() {
return true;
}
@Deprecated
public void setGameProfile(Object gameProfile) {
this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(null, getName(), gameProfile);
}
@Deprecated
public void setSkin(String skinToUse) {
this.skinToUse = skinToUse;
if (skinToUse == null) {
this.currentLookup = null;
this.gameProfile = null;
} else {
if (skinToUse.length() > 16) {
this.skinToUse = skinToUse.substring(0, 16);
}
if (LibVersion.is1_7()) {
currentLookup = new LibsProfileLookup() {
@Override
public void onLookup(Object gameProfile) {
if (currentLookup == this && gameProfile != null) {
setGameProfile(gameProfile);
if (DisguiseUtilities.isDisguiseInUse(PlayerDisguise.this)) {
DisguiseUtilities.refreshTrackers(PlayerDisguise.this);
}
}
}
};
Object obj = DisguiseUtilities.getProfileFromMojang(this.skinToUse, currentLookup);
if (obj != null) {
setGameProfile(obj);
}
}
}
}
}

View File

@ -10,6 +10,7 @@ import com.comphenix.protocol.reflect.StructureModifier;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
@ -39,6 +40,10 @@ public class PlayerWatcher extends LivingWatcher {
sendData(9);
}
public void setSkin(String playerName) {
((PlayerDisguise) getDisguise()).setSkin(playerName);
}
/**
* The facing direction for the bed is the block metadata. 0 - 90 degrees. 1 - 0 degrees. 2 - 270 degrees. 3 - 180 degrees.
*/

View File

@ -19,7 +19,6 @@ import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@ -57,6 +56,7 @@ public class DisguiseUtilities {
*/
private static HashMap<String, Object> gameProfiles = new HashMap<String, Object>();
private static LibsDisguises libsDisguises;
private static HashMap<String, ArrayList<Object>> runnables = new HashMap<String, ArrayList<Object>>();
/**
* A internal storage of fake entity ID's each entity has. Realistically I could probably use a ID like "4" for everyone,
* seeing as no one sees each others entity ID
@ -81,6 +81,11 @@ public class DisguiseUtilities {
futureDisguises.get(entityId).add(disguise);
}
public static void addGameProfile(String string, Object gameProfile) {
getGameProfiles().put(string, gameProfile);
addedByPlugins.add(string);
}
/**
* If name isn't null. Make sure that the name doesn't see any other disguise. Else if name is null. Make sure that the
* observers in the disguise don't see any other disguise.
@ -245,6 +250,10 @@ public class DisguiseUtilities {
return gameProfiles.get(playerName);
}
public static HashMap<String, Object> getGameProfiles() {
return gameProfiles;
}
public static TargetedDisguise getMainDisguise(UUID entityId) {
TargetedDisguise toReturn = null;
if (getDisguises().containsKey(entityId)) {
@ -286,8 +295,11 @@ public class DisguiseUtilities {
}
public static Object getProfileFromMojang(final String playerName) {
return getProfileFromMojang(playerName, new Runnable() {
public void run() {
return getProfileFromMojang(playerName, new LibsProfileLookup() {
@Override
public void onLookup(Object gameProfile) {
getAddedByPlugins().remove(playerName);
for (HashSet<TargetedDisguise> disguises : DisguiseUtilities.getDisguises().values()) {
for (TargetedDisguise disguise : disguises) {
if (disguise.getType() == DisguiseType.PLAYER && ((PlayerDisguise) disguise).getName().equals(playerName)) {
@ -306,7 +318,11 @@ public class DisguiseUtilities {
* Thread safe to use. This returns a GameProfile. And if its GameProfile doesn't have a skin blob. Then it does a lookup
* using schedulers. The runnable is run once the GameProfile has been successfully dealt with
*/
public static Object getProfileFromMojang(final String playerName, final Runnable runnable) {
public static Object getProfileFromMojang(String playerName, LibsProfileLookup runnableIfCantReturn) {
return getProfileFromMojang(playerName, (Object) runnableIfCantReturn);
}
private static Object getProfileFromMojang(final String playerName, final Object runnable) {
if (gameProfiles.containsKey(playerName)) {
if (gameProfiles.get(playerName) != null) {
return gameProfiles.get(playerName);
@ -331,8 +347,14 @@ public class DisguiseUtilities {
public void run() {
if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) {
gameProfiles.put(playerName, gameProfile);
if (runnable != null) {
runnable.run();
}
if (runnables.containsKey(playerName)) {
for (Object obj : runnables.remove(playerName)) {
if (obj instanceof Runnable) {
((Runnable) obj).run();
} else if (obj instanceof LibsProfileLookup) {
((LibsProfileLookup) obj).onLookup(gameProfile);
}
}
}
}
@ -348,9 +370,23 @@ public class DisguiseUtilities {
}
});
}
if (runnable != null) {
if (!runnables.containsKey(playerName)) {
runnables.put(playerName, new ArrayList<Object>());
}
runnables.get(playerName).add(runnable);
}
return ReflectionManager.getGameProfile(null, playerName);
}
/**
* Thread safe to use. This returns a GameProfile. And if its GameProfile doesn't have a skin blob. Then it does a lookup
* using schedulers. The runnable is run once the GameProfile has been successfully dealt with
*/
public static Object getProfileFromMojang(String playerName, Runnable runnableIfCantReturn) {
return getProfileFromMojang(playerName, (Object) runnableIfCantReturn);
}
public static List<TargetedDisguise> getSeenDisguises(String viewer) {
List<TargetedDisguise> dis = new ArrayList<TargetedDisguise>();
for (HashSet<TargetedDisguise> disguises : getDisguises().values()) {
@ -521,10 +557,15 @@ public class DisguiseUtilities {
return false;
}
@Deprecated
public static void removeGameprofile(String string) {
gameProfiles.remove(string);
}
public static void removeGameProfile(String string) {
gameProfiles.remove(string);
}
public static void removeSelfDisguise(Player player) {
if (selfDisguisesIds.containsKey(player.getUniqueId())) {
// Send a packet to destroy the fake entity

View File

@ -0,0 +1,6 @@
package me.libraryaddict.disguise.utilities;
public interface LibsProfileLookup {
public void onLookup(Object gameProfile);
}

View File

@ -186,7 +186,7 @@ public class PacketsManager {
if (!DisguiseUtilities.hasGameProfile(name)) {
removeName = !DisguiseUtilities.getAddedByPlugins().contains(name);
}
gameProfile = DisguiseUtilities.getProfileFromMojang(name);
gameProfile = ((PlayerDisguise) disguise).getGameProfile();
if (removeName) {
DisguiseUtilities.getAddedByPlugins().remove(name);
}

View File

@ -233,6 +233,27 @@ public class ReflectionManager {
return null;
}
public static Object getGameProfileWithThisSkin(UUID uuid, String playerName, Object profileWithSkin) {
try {
Object gameProfile;
try {
gameProfile = Class.forName("net.minecraft.util.com.mojang.authlib.GameProfile")
.getConstructor(UUID.class, String.class)
.newInstance(uuid != null ? uuid : UUID.randomUUID(), playerName);
} catch (NoSuchMethodException ex) {
gameProfile = Class.forName("net.minecraft.util.com.mojang.authlib.GameProfile")
.getConstructor(String.class, String.class).newInstance(uuid != null ? uuid.toString() : "", playerName);
}
Field properties = gameProfile.getClass().getDeclaredField("properties");
properties.setAccessible(true);
properties.set(gameProfile, properties.get(profileWithSkin));
return gameProfile;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Class getNmsClass(String className) {
try {
return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className);