- Changed entire project to gradle

- Updated for 1.8.3
- No more errors, woo
This commit is contained in:
NavidK0
2015-03-09 20:28:41 -04:00
parent 14757a035b
commit 573f4cdc88
81 changed files with 299 additions and 645 deletions

View File

@@ -0,0 +1,736 @@
package me.libraryaddict.disguise.utilities;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import me.libraryaddict.disguise.disguisetypes.AnimalColor;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.disguisetypes.RabbitType;
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Monster;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.potion.PotionEffectType;
public abstract class BaseDisguiseCommand implements CommandExecutor {
public class DisguiseParseException extends Exception {
private static final long serialVersionUID = 1276971370793124510L;
public DisguiseParseException() {
super();
}
public DisguiseParseException(String string) {
super(string);
}
}
protected ArrayList<String> getAllowedDisguises(HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> hashMap) {
ArrayList<String> allowedDisguises = new ArrayList<String>();
for (DisguiseType type : hashMap.keySet()) {
allowedDisguises.add(type.toReadable().replace(" ", "_"));
}
Collections.sort(allowedDisguises, String.CASE_INSENSITIVE_ORDER);
return allowedDisguises;
}
protected HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> getPermissions(CommandSender sender) {
return getPermissions(sender, "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + ".");
}
protected HashMap<String, Boolean> getDisguisePermission(CommandSender sender, DisguiseType type) {
switch (type) {
case PLAYER:
case FALLING_BLOCK:
case PAINTING:
case SPLASH_POTION:
case FISHING_HOOK:
case DROPPED_ITEM:
HashMap<String, Boolean> returns = new HashMap<String, Boolean>();
String beginning = "libsdisguises.options." + getClass().getSimpleName().toLowerCase().replace("command", "") + ".";
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
String lowerPerm = permission.getPermission().toLowerCase();
if (lowerPerm.startsWith(beginning)) {
String[] split = lowerPerm.substring(beginning.length()).split("\\.");
if (split.length > 1) {
if (split[0].replace("_", "").equals(type.name().toLowerCase().replace("_", ""))) {
for (int i = 1; i < split.length; i++) {
returns.put(split[i], permission.getValue());
}
}
}
}
}
return returns;
default:
return new HashMap<String, Boolean>();
}
}
protected Method[] getDisguiseWatcherMethods(Class<? extends FlagWatcher> watcherClass) {
Method[] methods = watcherClass.getMethods();
methods = Arrays.copyOf(methods, methods.length + 4);
int i = 4;
for (String methodName : new String[] { "setViewSelfDisguise", "setHideHeldItemFromSelf", "setHideArmorFromSelf",
"setHearSelfDisguise" }) {
try {
methods[methods.length - i--] = Disguise.class.getMethod(methodName, boolean.class);
} catch (Exception ex) {
ex.printStackTrace();
}
}
return methods;
}
/**
* Get perms for the node. Returns a hashmap of allowed disguisetypes and their options
*/
protected HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> getPermissions(CommandSender sender,
String permissionNode) {
HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> singleDisguises = new HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>>();
HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> rangeDisguises = new HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>>();
HashMap<String, Boolean> perms = new HashMap<String, Boolean>();
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
String perm = permission.getPermission().toLowerCase();
if (perm.startsWith(permissionNode) && (!perms.containsKey(perm) || !permission.getValue())) {
perms.put(perm, permission.getValue());
}
}
if (!perms.containsKey(permissionNode + "*") && sender.hasPermission(permissionNode + "*")) {
perms.put(permissionNode + "*", true);
}
if (!perms.containsKey(permissionNode + "*.*") && sender.hasPermission(permissionNode + "*.*")) {
perms.put(permissionNode + "*.*", true);
}
for (String perm : perms.keySet()) {
if (perms.get(perm)) {
perm = perm.substring(permissionNode.length());
String disguiseType = perm.split("\\.")[0];
DisguiseType dType = null;
for (DisguiseType t : DisguiseType.values()) {
if (t.name().replace("_", "").equalsIgnoreCase(disguiseType.replace("_", ""))) {
dType = t;
break;
}
}
if (dType != null) {
HashMap<ArrayList<String>, Boolean> list;
if (singleDisguises.containsKey(dType)) {
list = singleDisguises.get(dType);
} else {
list = new HashMap<ArrayList<String>, Boolean>();
singleDisguises.put(dType, list);
}
HashMap<ArrayList<String>, Boolean> map1 = getOptions(perm);
list.put(map1.keySet().iterator().next(), map1.values().iterator().next());
} else {
for (DisguiseType type : DisguiseType.values()) {
HashMap<ArrayList<String>, Boolean> options = null;
Class entityClass = type.getEntityClass();
if (disguiseType.equals("mob")) {
if (type.isMob()) {
options = getOptions(perm);
}
} else if (disguiseType.equals("animal") || disguiseType.equals("animals")) {
if (Animals.class.isAssignableFrom(entityClass)) {
options = getOptions(perm);
}
} else if (disguiseType.equals("monster") || disguiseType.equals("monsters")) {
if (Monster.class.isAssignableFrom(entityClass)) {
options = getOptions(perm);
}
} else if (disguiseType.equals("misc")) {
if (type.isMisc()) {
options = getOptions(perm);
}
} else if (disguiseType.equals("ageable")) {
if (Ageable.class.isAssignableFrom(entityClass)) {
options = getOptions(perm);
}
} else if (disguiseType.equals("*")) {
options = getOptions(perm);
}
if (options != null) {
HashMap<ArrayList<String>, Boolean> list;
if (rangeDisguises.containsKey(type)) {
list = rangeDisguises.get(type);
} else {
list = new HashMap<ArrayList<String>, Boolean>();
rangeDisguises.put(type, list);
}
HashMap<ArrayList<String>, Boolean> map1 = getOptions(perm);
list.put(map1.keySet().iterator().next(), map1.values().iterator().next());
}
}
}
}
}
for (String perm : perms.keySet()) {
if (!perms.get(perm)) {
perm = perm.substring(permissionNode.length());
String disguiseType = perm.split("\\.")[0];
DisguiseType dType = null;
for (DisguiseType t : DisguiseType.values()) {
if (t.name().replace("_", "").equalsIgnoreCase(disguiseType.replace("_", ""))) {
dType = t;
break;
}
}
if (dType != null) {
singleDisguises.remove(dType);
rangeDisguises.remove(dType);
} else {
for (DisguiseType type : DisguiseType.values()) {
boolean foundHim = false;
Class entityClass = type.getEntityClass();
if (disguiseType.equals("mob")) {
if (type.isMob()) {
foundHim = true;
}
} else if (disguiseType.equals("animal") || disguiseType.equals("animals")) {
if (Animals.class.isAssignableFrom(entityClass)) {
foundHim = true;
}
} else if (disguiseType.equals("monster") || disguiseType.equals("monsters")) {
if (Monster.class.isAssignableFrom(entityClass)) {
foundHim = true;
}
} else if (disguiseType.equals("misc")) {
if (type.isMisc()) {
foundHim = true;
}
} else if (disguiseType.equals("ageable")) {
if (Ageable.class.isAssignableFrom(entityClass)) {
foundHim = true;
}
} else if (disguiseType.equals("*")) {
foundHim = true;
}
if (foundHim) {
rangeDisguises.remove(type);
}
}
}
}
}
HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> map = new HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>>();
for (DisguiseType type : DisguiseType.values()) {
HashMap<ArrayList<String>, Boolean> temp = new HashMap<ArrayList<String>, Boolean>();
if (singleDisguises.containsKey(type)) {
temp.putAll(singleDisguises.get(type));
}
if (rangeDisguises.containsKey(type)) {
temp.putAll(rangeDisguises.get(type));
}
if (!temp.isEmpty()) {
map.put(type, temp);
}
}
return map;
}
private HashMap<ArrayList<String>, Boolean> getOptions(String perm) {
ArrayList<String> list = new ArrayList<String>();
boolean isRemove = true;
String[] split = perm.split("\\.");
for (int i = 1; i < split.length; i++) {
String option = split[i];
boolean value = option.startsWith("-");
if (value) {
option = option.substring(1);
isRemove = false;
}
if (option.equals("baby"))
option = "setbaby";
list.add(option);
}
HashMap<ArrayList<String>, Boolean> options = new HashMap<ArrayList<String>, Boolean>();
options.put(list, isRemove);
return options;
}
protected boolean isDouble(String string) {
try {
Float.parseFloat(string);
return true;
} catch (Exception ex) {
return false;
}
}
protected boolean isNumeric(String string) {
try {
Integer.parseInt(string);
return true;
} catch (Exception ex) {
return false;
}
}
/**
* Returns the disguise if it all parsed correctly. Returns a exception with a complete message if it didn't. The
* commandsender is purely used for checking permissions. Would defeat the purpose otherwise. To reach this point, the
* disguise has been feed a proper disguisetype.
*/
protected Disguise parseDisguise(CommandSender sender, String[] args,
HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> map) throws DisguiseParseException,
IllegalAccessException, InvocationTargetException {
if (map.isEmpty()) {
throw new DisguiseParseException(ChatColor.RED + "You are forbidden to use this command.");
}
if (args.length == 0) {
sendCommandUsage(sender, map);
throw new DisguiseParseException();
}
// How many args to skip due to the disugise being constructed
// Time to start constructing the disguise.
// We will need to check between all 3 kinds of disguises
int toSkip = 1;
ArrayList<String> usedOptions = new ArrayList<String>();
Disguise disguise = null;
HashMap<ArrayList<String>, Boolean> optionPermissions;
if (args[0].startsWith("@")) {
if (sender.hasPermission("libsdisguises.disguise.disguiseclone")) {
disguise = DisguiseUtilities.getClonedDisguise(args[0].toLowerCase());
if (disguise == null) {
throw new DisguiseParseException(ChatColor.RED + "Cannot find a disguise under the reference " + args[0]);
}
} else {
throw new DisguiseParseException(ChatColor.RED + "You do not have perimssion to use disguise references!");
}
optionPermissions = (map.containsKey(disguise.getType()) ? map.get(disguise.getType())
: new HashMap<ArrayList<String>, Boolean>());
} else {
DisguiseType disguiseType = null;
if (args[0].equalsIgnoreCase("p")) {
disguiseType = DisguiseType.PLAYER;
} else {
for (DisguiseType type : DisguiseType.values()) {
if (args[0].equalsIgnoreCase(type.name()) || args[0].equalsIgnoreCase(type.name().replace("_", ""))) {
disguiseType = type;
break;
}
}
}
if (disguiseType == null) {
throw new DisguiseParseException(ChatColor.RED + "Error! The disguise " + ChatColor.GREEN + args[0]
+ ChatColor.RED + " doesn't exist!");
}
if (disguiseType.getEntityType() == null) {
throw new DisguiseParseException(ChatColor.RED + "Error! This version of minecraft does not have that disguise!");
}
if (!map.containsKey(disguiseType)) {
throw new DisguiseParseException(ChatColor.RED + "You are forbidden to use this disguise.");
}
optionPermissions = map.get(disguiseType);
HashMap<String, Boolean> disguiseOptions = this.getDisguisePermission(sender, disguiseType);
if (disguiseType.isPlayer()) {// If he is doing a player disguise
if (args.length == 1) {
// He needs to give the player name
throw new DisguiseParseException(ChatColor.RED + "Error! You need to give a player name!");
} else {
if (!disguiseOptions.isEmpty()
&& (!disguiseOptions.containsKey(args[1].toLowerCase()) || !disguiseOptions
.get(args[1].toLowerCase()))) {
throw new DisguiseParseException(ChatColor.RED + "Error! You don't have permission to use that name!");
}
// Construct the player disguise
disguise = new PlayerDisguise(ChatColor.translateAlternateColorCodes('&', args[1]));
toSkip++;
}
} else {
if (disguiseType.isMob()) { // Its a mob, use the mob constructor
boolean adult = true;
if (args.length > 1) {
if (args[1].equalsIgnoreCase("baby") || args[1].equalsIgnoreCase("adult")) {
usedOptions.add("setbaby");
doCheck(optionPermissions, usedOptions);
adult = args[1].equalsIgnoreCase("adult");
toSkip++;
}
}
disguise = new MobDisguise(disguiseType, adult);
} else if (disguiseType.isMisc()) {
// Its a misc, we are going to use the MiscDisguise constructor.
int miscId = -1;
int miscData = -1;
String secondArg = null;
if (args.length > 1) {
// They have defined more arguements!
// If the first arg is a number
if (args[1].contains(":")) {
String[] split = args[1].split(":");
if (isNumeric(split[1])) {
secondArg = split[1];
}
args[1] = split[0];
}
if (isNumeric(args[1])) {
miscId = Integer.parseInt(args[1]);
} else {
if (disguiseType == DisguiseType.FALLING_BLOCK || disguiseType == DisguiseType.DROPPED_ITEM) {
for (Material mat : Material.values()) {
if (mat.name().replace("_", "").equalsIgnoreCase(args[1].replace("_", ""))) {
miscId = mat.getId();
break;
}
}
}
}
if (miscId != -1) {
switch (disguiseType) {
case PAINTING:
case FALLING_BLOCK:
case SPLASH_POTION:
case DROPPED_ITEM:
case FISHING_HOOK:
case ARROW:
case SMALL_FIREBALL:
case FIREBALL:
case WITHER_SKULL:
break;
default:
throw new DisguiseParseException(ChatColor.RED + "Error! " + disguiseType.toReadable()
+ " doesn't know what to do with " + args[1] + "!");
}
toSkip++;
// If they also defined a data value
if (args.length > 2 && secondArg == null && isNumeric(args[2])) {
secondArg = args[2];
toSkip++;
}
if (secondArg != null) {
if (disguiseType != DisguiseType.FALLING_BLOCK && disguiseType != DisguiseType.DROPPED_ITEM) {
throw new DisguiseParseException(ChatColor.RED + "Error! Only the disguises "
+ DisguiseType.FALLING_BLOCK.toReadable() + " and "
+ DisguiseType.DROPPED_ITEM.toReadable() + " uses a second number!");
}
miscData = Integer.parseInt(secondArg);
}
}
}
if (!disguiseOptions.isEmpty() && miscId != -1) {
String toCheck = "" + miscId;
if (miscData == 0 || miscData == -1) {
if (!disguiseOptions.containsKey(toCheck) || !disguiseOptions.get(toCheck)) {
toCheck += ":0";
}
} else {
toCheck += ":" + miscData;
}
if (!disguiseOptions.containsKey(toCheck) || !disguiseOptions.get(toCheck)) {
throw new DisguiseParseException(ChatColor.RED
+ "Error! You do not have permission to use the parameter " + toCheck + " on the "
+ disguiseType.toReadable() + " disguise!");
}
}
if (miscId != -1) {
if (disguiseType == DisguiseType.FALLING_BLOCK) {
usedOptions.add("setblock");
doCheck(optionPermissions, usedOptions);
} else if (disguiseType == DisguiseType.PAINTING) {
usedOptions.add("setpainting");
doCheck(optionPermissions, usedOptions);
} else if (disguiseType == DisguiseType.SPLASH_POTION) {
usedOptions.add("setpotionid");
doCheck(optionPermissions, usedOptions);
}
}
// Construct the disguise
disguise = new MiscDisguise(disguiseType, miscId, miscData);
}
}
}
// Copy strings to their new range
String[] newArgs = new String[args.length - toSkip];
System.arraycopy(args, toSkip, newArgs, 0, args.length - toSkip);
args = newArgs;
Method[] methods = this.getDisguiseWatcherMethods(disguise.getWatcher().getClass());
for (int i = 0; i < args.length; i += 2) {
String methodName = args[i];
String valueString = (args.length - 1 == i ? null : args[i + 1]);
Method methodToUse = null;
Object value = null;
DisguiseParseException storedEx = null;
int c = 0;
while (c < methods.length) {
try {
Entry<Method, Integer> entry = getMethod(methods, methodName, c);
if (entry == null) {
break;
}
methodToUse = entry.getKey();
c = entry.getValue();
methodName = methodToUse.getName();
Class<?>[] types = methodToUse.getParameterTypes();
Class param = types[0];
if (valueString != null) {
if (int.class == param) {
// Parse to integer
if (isNumeric(valueString)) {
value = (int) Integer.parseInt(valueString);
} else {
throw parseToException("number", valueString, methodName);
}
} else if (float.class == param || double.class == param) {
// Parse to number
if (isDouble(valueString)) {
float obj = Float.parseFloat(valueString);
if (param == float.class) {
value = (float) obj;
} else if (param == double.class) {
value = (double) obj;
}
} else {
throw parseToException("number.0", valueString, methodName);
}
} else if (param == String.class) {
// Parse to string
value = ChatColor.translateAlternateColorCodes('&', valueString);
} else if (param == AnimalColor.class) {
// Parse to animal color
try {
value = AnimalColor.valueOf(valueString.toUpperCase());
} catch (Exception ex) {
throw parseToException("animal color", valueString, methodName);
}
} else if (param == ItemStack.class) {
// Parse to itemstack
try {
value = parseToItemstack(valueString);
} catch (Exception ex) {
throw new DisguiseParseException(String.format(ex.getMessage(), methodName));
}
} else if (param == ItemStack[].class) {
// Parse to itemstack array
ItemStack[] items = new ItemStack[4];
String[] split = valueString.split(",");
if (split.length == 4) {
for (int a = 0; a < 4; a++) {
try {
items[a] = parseToItemstack(split[a]);
} catch (Exception ex) {
throw parseToException("item ID,ID,ID,ID" + ChatColor.RED + " or " + ChatColor.GREEN
+ "ID:Data,ID:Data,ID:Data,ID:Data combo", valueString, methodName);
}
}
} else {
throw parseToException("item ID,ID,ID,ID" + ChatColor.RED + " or " + ChatColor.GREEN
+ "ID:Data,ID:Data,ID:Data,ID:Data combo", valueString, methodName);
}
value = items;
} else if (param.getSimpleName().equals("Color")) {
// Parse to horse color
value = callValueOf(param, valueString, methodName, "a horse color");
} else if (param.getSimpleName().equals("Style")) {
// Parse to horse style
value = callValueOf(param, valueString, methodName, "a horse style");
} else if (param.getSimpleName().equals("Profession")) {
// Parse to villager profession
value = callValueOf(param, valueString, methodName, "a villager profession");
} else if (param.getSimpleName().equals("Art")) {
// Parse to art type
value = callValueOf(param, valueString, methodName, "a painting art");
} else if (param.getSimpleName().equals("Type")) {
// Parse to ocelot type
value = callValueOf(param, valueString, methodName, "a ocelot type");
} else if (param == PotionEffectType.class) {
// Parse to potion effect
try {
PotionEffectType potionType = PotionEffectType.getByName(valueString.toUpperCase());
if (potionType == null && isNumeric(valueString)) {
potionType = PotionEffectType.getById(Integer.parseInt(valueString));
}
if (potionType == null)
throw new DisguiseParseException();
value = potionType;
} catch (Exception ex) {
throw parseToException("a potioneffect type", valueString, methodName);
}
} else if (param == int[].class) {
String[] split = valueString.split(",");
int[] values = new int[split.length];
for (int b = 0; b < values.length; b++) {
try {
values[b] = Integer.parseInt(split[b]);
} catch (NumberFormatException ex) {
throw parseToException("Number,Number,Number...", valueString, methodName);
}
}
value = values;
} else if (param == BlockFace.class) {
try {
BlockFace face = BlockFace.valueOf(valueString.toUpperCase());
if (face.ordinal() > 4)
throw new DisguiseParseException();
value = face;
} catch (Exception ex) {
throw parseToException("a direction (north, east, south, west, up)", valueString, methodName);
}
} else if (param == RabbitType.class) {
try {
for (RabbitType type : RabbitType.values()) {
if (type.name().replace("_", "")
.equalsIgnoreCase(valueString.replace("_", "").replace(" ", ""))) {
value = type;
break;
}
}
if (value == null) {
throw new Exception();
}
} catch (Exception ex) {
throw parseToException("rabbit type (white, brown, patches...)", valueString, methodName);
}
}
}
if (value == null && boolean.class == param) {
if (valueString == null) {
value = true;
i--;
} else if (valueString.equalsIgnoreCase("true")) {
value = true;
} else if (valueString.equalsIgnoreCase("false")) {
value = false;
} else {
if (getMethod(methods, valueString, 0) == null) {
throw parseToException("true/false", valueString, methodName);
} else {
value = true;
i--;
}
}
}
if (value != null) {
break;
}
} catch (DisguiseParseException ex) {
storedEx = ex;
methodToUse = null;
} catch (Exception ex) {
ex.printStackTrace();
methodToUse = null;
}
}
if (methodToUse == null) {
if (storedEx != null) {
throw storedEx;
}
throw new DisguiseParseException(ChatColor.RED + "Cannot find the option " + methodName);
}
if (value == null) {
throw new DisguiseParseException(ChatColor.RED + "No value was given for the option " + methodName);
}
if (!usedOptions.contains(methodName.toLowerCase())) {
usedOptions.add(methodName.toLowerCase());
}
doCheck(optionPermissions, usedOptions);
if (FlagWatcher.class.isAssignableFrom(methodToUse.getDeclaringClass()))
methodToUse.invoke(disguise.getWatcher(), value);
else
methodToUse.invoke(disguise, value);
}
// Alright. We've constructed our disguise.
return disguise;
}
private Entry<Method, Integer> getMethod(Method[] methods, String methodName, int toStart) {
for (int i = toStart; i < methods.length; i++) {
Method method = methods[i];
if (!method.getName().startsWith("get") && method.getName().equalsIgnoreCase(methodName)
&& method.getAnnotation(Deprecated.class) == null && method.getParameterTypes().length == 1) {
return new HashMap.SimpleEntry(method, ++i);
}
}
return null;
}
private Object callValueOf(Class<?> param, String valueString, String methodName, String description)
throws DisguiseParseException {
Object value;
try {
value = param.getMethod("valueOf", String.class).invoke(null, valueString.toUpperCase());
} catch (Exception ex) {
throw parseToException(description, valueString, methodName);
}
return value;
}
private boolean passesCheck(HashMap<ArrayList<String>, Boolean> map1, ArrayList<String> usedOptions) {
boolean hasPermission = false;
for (ArrayList<String> list : map1.keySet()) {
boolean myPerms = true;
for (String option : usedOptions) {
if (!(map1.get(list) && list.contains("*")) && (list.contains(option) != map1.get(list))) {
myPerms = false;
break;
}
}
if (myPerms) {
hasPermission = true;
}
}
return hasPermission;
}
private void doCheck(HashMap<ArrayList<String>, Boolean> optionPermissions, ArrayList<String> usedOptions)
throws DisguiseParseException {
if (!passesCheck(optionPermissions, usedOptions)) {
throw new DisguiseParseException(ChatColor.RED + "You do not have the permission to use the option "
+ usedOptions.get(usedOptions.size() - 1));
}
}
private DisguiseParseException parseToException(String expectedValue, String receivedInstead, String methodName) {
return new DisguiseParseException(ChatColor.RED + "Expected " + ChatColor.GREEN + expectedValue + ChatColor.RED
+ ", received " + ChatColor.GREEN + receivedInstead + ChatColor.RED + " instead for " + ChatColor.GREEN
+ methodName);
}
private ItemStack parseToItemstack(String string) throws Exception {
String[] split = string.split(":", -1);
if (isNumeric(split[0])) {
int itemId = Integer.parseInt(split[0]);
short itemDura = 0;
if (split.length > 1) {
if (isNumeric(split[1])) {
itemDura = Short.parseShort(split[1]);
} else {
throw parseToException("item ID:Durability combo", string, "%s");
}
}
return new ItemStack(itemId, 1, itemDura);
} else {
if (split.length == 1) {
throw parseToException("item ID", string, "%s");
} else {
throw parseToException("item ID:Durability combo", string, "%s");
}
}
}
protected abstract void sendCommandUsage(CommandSender sender, HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> map);
}

View File

@@ -0,0 +1,70 @@
package me.libraryaddict.disguise.utilities;
import org.bukkit.entity.Entity;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* User: Austin Date: 4/22/13 Time: 11:47 PM (c) lazertester
*/
// Code for this taken and slightly modified from
// https://github.com/ddopson/java-class-enumerator
public class ClassGetter {
public static ArrayList<Class<?>> getClassesForPackage(String pkgname) {
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
// String relPath = pkgname.replace('.', '/');
// Get a File object for the package
CodeSource src = Entity.class.getProtectionDomain().getCodeSource();
if (src != null) {
URL resource = src.getLocation();
resource.getPath();
processJarfile(resource, pkgname, classes);
}
return classes;
}
private static Class<?> loadClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'");
} catch (NoClassDefFoundError e) {
return null;
}
}
private static void processJarfile(URL resource, String pkgname, ArrayList<Class<?>> classes) {
try {
String relPath = pkgname.replace('.', '/');
String resPath = URLDecoder.decode(resource.getPath(), "UTF-8");
String jarPath = resPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", "");
JarFile jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String entryName = entry.getName();
String className = null;
if (entryName.endsWith(".class") && entryName.startsWith(relPath)
&& entryName.length() > (relPath.length() + "/".length())) {
className = entryName.replace('/', '.').replace('\\', '.').replace(".class", "");
}
if (className != null) {
Class<?> c = loadClass(className);
if (c != null)
classes.add(c);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@@ -0,0 +1,230 @@
package me.libraryaddict.disguise.utilities;
import java.util.HashMap;
import java.util.HashSet;
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
import org.bukkit.Sound;
/**
* Only living disguises go in here!
*/
public enum DisguiseSound {
ARROW(null, null, null, null, "random.bowhit"),
BAT("mob.bat.hurt", null, "mob.bat.death", "mob.bat.idle", "damage.fallsmall", "mob.bat.loop", "damage.fallbig",
"mob.bat.takeoff"),
BLAZE("mob.blaze.hit", null, "mob.blaze.death", "mob.blaze.breathe", "damage.fallsmall", "damage.fallbig"),
CAVE_SPIDER("mob.spider.say", "mob.spider.step", "mob.spider.death", "mob.spider.say"),
CHICKEN("mob.chicken.hurt", "mob.chicken.step", "mob.chicken.hurt", "mob.chicken.say", "damage.fallsmall",
"mob.chicken.plop", "damage.fallbig"),
COW("mob.cow.hurt", "mob.cow.step", "mob.cow.hurt", "mob.cow.say"),
CREEPER("mob.creeper.say", "step.grass", "mob.creeper.death", null),
DONKEY("mob.horse.donkey.hit", "step.grass", "mob.horse.donkey.death", "mob.horse.donkey.idle", "mob.horse.gallop",
"mob.horse.leather", "mob.horse.donkey.angry", "mob.horse.wood", "mob.horse.armor", "mob.horse.soft",
"mob.horse.land", "mob.horse.jump", "mob.horse.angry"),
ELDER_GUARDIAN("mob.guardian.elder.hit", null, "mob.guardian.elder.death", "mob.guardian.elder.death"),
ENDER_DRAGON("mob.enderdragon.hit", null, "mob.enderdragon.end", "mob.enderdragon.growl", "damage.fallsmall",
"mob.enderdragon.wings", "damage.fallbig"),
ENDERMAN("mob.endermen.hit", "step.grass", "mob.endermen.death", "mob.endermen.idle", "mob.endermen.scream",
"mob.endermen.portal", "mob.endermen.stare"),
ENDERMITE("mob.silverfish.hit", "mob.silverfish.step", "mob.silverfish.kill", "mob.silverfish.say"),
GHAST("mob.ghast.scream", null, "mob.ghast.death", "mob.ghast.moan", "damage.fallsmall", "mob.ghast.fireball",
"damage.fallbig", "mob.ghast.affectionate_scream", "mob.ghast.charge"),
GIANT("damage.hit", "step.grass", null, null),
GUARDIAN("mob.guardian.hit", null, "mob.guardian.death", "mob.guardian.death"),
HORSE("mob.horse.hit", "step.grass", "mob.horse.death", "mob.horse.idle", "mob.horse.gallop", "mob.horse.leather",
"mob.horse.wood", "mob.horse.armor", "mob.horse.soft", "mob.horse.land", "mob.horse.jump", "mob.horse.angry",
"mob.horse.leather"),
IRON_GOLEM("mob.irongolem.hit", "mob.irongolem.walk", "mob.irongolem.death", "mob.irongolem.throw"),
MAGMA_CUBE("mob.slime.attack", "mob.slime.big", null, null, "mob.slime.small"),
MULE("mob.horse.donkey.hit", "step.grass", "mob.horse.donkey.death", "mob.horse.donkey.idle"),
MUSHROOM_COW("mob.cow.hurt", "mob.cow.step", "mob.cow.hurt", "mob.cow.say"),
OCELOT("mob.cat.hitt", "step.grass", "mob.cat.hitt", "mob.cat.meow", "mob.cat.purreow", "mob.cat.purr"),
PIG("mob.pig.say", "mob.pig.step", "mob.pig.death", "mob.pig.say"),
PIG_ZOMBIE("mob.zombiepig.zpighurt", null, "mob.zombiepig.zpigdeath", "mob.zombiepig.zpig", "mob.zombiepig.zpigangry"),
PLAYER("game.player.hurt", "step.grass", "game.player.hurt", null),
RABBIT("mob.rabbit.hurt", "mob.rabbit.hop", "mob.rabbit.death", "mob.rabbit.idle"),
SHEEP("mob.sheep.say", "mob.sheep.step", null, "mob.sheep.say", "mob.sheep.shear"),
SILVERFISH("mob.silverfish.hit", "mob.silverfish.step", "mob.silverfish.kill", "mob.silverfish.say"),
SKELETON("mob.skeleton.hurt", "mob.skeleton.step", "mob.skeleton.death", "mob.skeleton.say"),
SKELETON_HORSE("mob.horse.skeleton.hit", "step.grass", "mob.horse.skeleton.death", "mob.horse.skeleton.idle",
"mob.horse.gallop", "mob.horse.leather", "mob.horse.wood", "mob.horse.armor", "mob.horse.soft", "mob.horse.land",
"mob.horse.jump", "mob.horse.angry"),
SLIME("mob.slime.attack", "mob.slime.big", null, null, "mob.slime.small"),
SNOWMAN(),
SPIDER("mob.spider.say", "mob.spider.step", "mob.spider.death", "mob.spider.say"),
SQUID(),
UNDEAD_HORSE("mob.horse.zombie.hit", "step.grass", "mob.horse.zombie.death", "mob.horse.zombie.idle", "mob.horse.gallop",
"mob.horse.leather", "mob.horse.wood", "mob.horse.armor", "mob.horse.soft", "mob.horse.land", "mob.horse.jump",
"mob.horse.angry"),
VILLAGER("mob.villager.hit", null, "mob.villager.death", "mob.villager.idle", "mob.villager.haggle", "mob.villager.no",
"mob.villager.yes"),
WITCH("mob.witch.hurt", null, "mob.witch.death", "mob.witch.idle"),
WITHER("mob.wither.hurt", null, "mob.wither.death", "mob.wither.idle", "damage.fallsmall", "mob.wither.spawn",
"damage.fallbig", "mob.wither.shoot"),
WITHER_SKELETON("mob.skeleton.hurt", "mob.skeleton.step", "mob.skeleton.death", "mob.skeleton.say"),
WOLF("mob.wolf.hurt", "mob.wolf.step", "mob.wolf.death", "mob.wolf.bark", "mob.wolf.panting", "mob.wolf.whine",
"mob.wolf.howl", "mob.wolf.growl", "mob.wolf.shake"),
ZOMBIE("mob.zombie.hurt", "mob.zombie.step", "mob.zombie.death", "mob.zombie.say", "mob.zombie.infect",
"mob.zombie.woodbreak", "mob.zombie.metal", "mob.zombie.wood"),
ZOMBIE_VILLAGER("mob.zombie.hurt", "mob.zombie.step", "mob.zombie.death", "mob.zombie.say", "mob.zombie.infect",
"mob.zombie.woodbreak", "mob.zombie.metal", "mob.zombie.wood");
public enum SoundType {
CANCEL, DEATH, HURT, IDLE, STEP;
}
public static DisguiseSound getType(String name) {
try {
return valueOf(name);
} catch (Exception ex) {
return null;
}
}
private HashSet<String> cancelSounds = new HashSet<String>();
private float damageSoundVolume = 1F;
private HashMap<SoundType, String> disguiseSounds = new HashMap<SoundType, String>();
private DisguiseSound(Object... sounds) {
for (int i = 0; i < sounds.length; i++) {
Object obj = sounds[i];
String s;
if (obj == null)
continue;
else if (obj instanceof String) {
s = (String) obj;
} else if (obj instanceof Sound) {
s = ReflectionManager.getCraftSound((Sound) obj);
System.out.print("Warning! The sound " + obj + " needs to be converted to a string");
} else {
throw new RuntimeException("Was given a unknown object " + obj);
}
switch (i) {
case 0:
disguiseSounds.put(SoundType.HURT, s);
break;
case 1:
disguiseSounds.put(SoundType.STEP, s);
break;
case 2:
disguiseSounds.put(SoundType.DEATH, s);
break;
case 3:
disguiseSounds.put(SoundType.IDLE, s);
break;
default:
cancelSounds.add(s);
break;
}
}
}
public float getDamageAndIdleSoundVolume() {
return damageSoundVolume;
}
public String getSound(SoundType type) {
if (type == null || !disguiseSounds.containsKey(type))
return null;
return disguiseSounds.get(type);
}
public HashSet<String> getSoundsToCancel() {
return cancelSounds;
}
/**
* Used to check if this sound name is owned by this disguise sound.
*/
public SoundType getType(String sound, boolean ignoreDamage) {
if (isCancelSound(sound))
return SoundType.CANCEL;
if (disguiseSounds.containsKey(SoundType.STEP) && disguiseSounds.get(SoundType.STEP).startsWith("step.")
&& sound.startsWith("step."))
return SoundType.STEP;
for (SoundType type : SoundType.values()) {
if (!disguiseSounds.containsKey(type) || type == SoundType.DEATH || (ignoreDamage && type == SoundType.HURT))
continue;
String s = disguiseSounds.get(type);
if (s != null) {
if (s.equals(sound))
return type;
}
}
return null;
}
public boolean isCancelSound(String sound) {
return getSoundsToCancel().contains(sound);
}
public void removeSound(SoundType type, Sound sound) {
removeSound(type, ReflectionManager.getCraftSound(sound));
}
public void removeSound(SoundType type, String sound) {
if (type == SoundType.CANCEL)
cancelSounds.remove(sound);
else {
disguiseSounds.remove(type);
}
}
public void setDamageAndIdleSoundVolume(float strength) {
this.damageSoundVolume = strength;
}
public void setSound(SoundType type, Sound sound) {
setSound(type, ReflectionManager.getCraftSound(sound));
}
public void setSound(SoundType type, String sound) {
if (type == SoundType.CANCEL)
cancelSounds.add(sound);
else {
disguiseSounds.put(type, sound);
}
}
}

View File

@@ -0,0 +1,990 @@
package me.libraryaddict.disguise.utilities;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
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;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
public class DisguiseUtilities {
/**
* This is a list of names which was called by other plugins. As such, don't remove from the gameProfiles as its the duty of
* the plugin to do that.
*/
private static HashSet<String> addedByPlugins = new HashSet<String>();
private static Object bedChunk;
private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<String, Disguise>();
/**
* A hashmap of the uuid's of entitys, alive and dead. And their disguises in use
**/
private static HashMap<UUID, HashSet<TargetedDisguise>> disguisesInUse = new HashMap<UUID, HashSet<TargetedDisguise>>();
/**
* Disguises which are stored ready for a entity to be seen by a player Preferably, disguises in this should only stay in for
* a max of a second.
*/
private static HashMap<Integer, HashSet<TargetedDisguise>> futureDisguises = new HashMap<Integer, HashSet<TargetedDisguise>>();
/**
* A hashmap storing the uuid and skin of a playername
*/
private static HashMap<String, WrappedGameProfile> gameProfiles = new HashMap<String, WrappedGameProfile>();
private static LibsDisguises libsDisguises;
private static HashMap<String, ArrayList<Object>> runnables = new HashMap<String, ArrayList<Object>>();
private static HashSet<UUID> selfDisguised = new HashSet<UUID>();
private static Field xChunk, zChunk;
static {
try {
Object server = ReflectionManager.getNmsMethod("MinecraftServer", "getServer").invoke(null);
Object world = ((List) server.getClass().getField("worlds").get(server)).get(0);
bedChunk = ReflectionManager.getNmsClass("Chunk")
.getConstructor(ReflectionManager.getNmsClass("World"), int.class, int.class).newInstance(world, 0, 0);
Field cSection = bedChunk.getClass().getDeclaredField("sections");
cSection.setAccessible(true);
Object chunkSection = ReflectionManager.getNmsClass("ChunkSection").getConstructor(int.class, boolean.class)
.newInstance(0, true);
Object block;
try {
block = ReflectionManager.getNmsClass("Block").getMethod("getById", int.class)
.invoke(null, Material.BED_BLOCK.getId());
} catch (Exception ex) {
block = ((Object[]) ReflectionManager.getNmsField(ReflectionManager.getNmsClass("Block"), "byId").get(null))[Material.BED_BLOCK
.getId()];
}
Method fromLegacyData = block.getClass().getMethod("fromLegacyData", int.class);
Method setType = chunkSection.getClass().getMethod("setType", int.class, int.class, int.class,
ReflectionManager.getNmsClass("IBlockData"));
Method setSky = chunkSection.getClass().getMethod("a", int.class, int.class, int.class, int.class);
Method setEmitted = chunkSection.getClass().getMethod("b", int.class, int.class, int.class, int.class);
for (BlockFace face : new BlockFace[] { BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH }) {
setType.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), fromLegacyData.invoke(block, face.ordinal()));
setSky.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), 0);
setEmitted.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), 0);
}
Object[] array = (Object[]) Array.newInstance(chunkSection.getClass(), 16);
array[0] = chunkSection;
cSection.set(bedChunk, array);
xChunk = bedChunk.getClass().getField("locX");
xChunk.setAccessible(true);
zChunk = bedChunk.getClass().getField("locZ");
zChunk.setAccessible(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static boolean addClonedDisguise(String key, Disguise disguise) {
if (DisguiseConfig.getMaxClonedDisguises() > 0) {
if (clonedDisguises.containsKey(key)) {
clonedDisguises.remove(key);
} else if (DisguiseConfig.getMaxClonedDisguises() == clonedDisguises.size()) {
clonedDisguises.remove(clonedDisguises.keySet().iterator().next());
}
if (DisguiseConfig.getMaxClonedDisguises() > clonedDisguises.size()) {
clonedDisguises.put(key, disguise);
return true;
}
}
return false;
}
public static void addDisguise(UUID entityId, TargetedDisguise disguise) {
if (!getDisguises().containsKey(entityId)) {
getDisguises().put(entityId, new HashSet<TargetedDisguise>());
}
getDisguises().get(entityId).add(disguise);
checkConflicts(disguise, null);
if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS && disguise.isModifyBoundingBox()) {
doBoundingBox(disguise);
}
}
public static void addFutureDisguise(final int entityId, final TargetedDisguise disguise) {
if (!futureDisguises.containsKey(entityId)) {
futureDisguises.put(entityId, new HashSet<TargetedDisguise>());
}
futureDisguises.get(entityId).add(disguise);
final BukkitRunnable runnable = new BukkitRunnable() {
public void run() {
if (futureDisguises.containsKey(entityId) && futureDisguises.get(entityId).contains(disguise)) {
for (World world : Bukkit.getWorlds()) {
for (Entity entity : world.getEntities()) {
if (entity.getEntityId() == entityId) {
UUID uniqueId = entity.getUniqueId();
for (TargetedDisguise disguise : futureDisguises.remove(entityId)) {
addDisguise(uniqueId, disguise);
}
return;
}
}
}
futureDisguises.get(entityId).remove(disguise);
if (futureDisguises.get(entityId).isEmpty()) {
futureDisguises.remove(entityId);
}
}
}
};
runnable.runTaskLater(libsDisguises, 20);
}
public static void addGameProfile(String string, WrappedGameProfile gameProfile) {
getGameProfiles().put(string, gameProfile);
getAddedByPlugins().add(string.toLowerCase());
}
/**
* 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.
*/
public static void checkConflicts(TargetedDisguise disguise, String name) {
// If the disguise is being used.. Else we may accidentally undisguise something else
if (DisguiseAPI.isDisguiseInUse(disguise)) {
Iterator<TargetedDisguise> disguiseItel = getDisguises().get(disguise.getEntity().getUniqueId()).iterator();
// Iterate through the disguises
while (disguiseItel.hasNext()) {
TargetedDisguise d = disguiseItel.next();
// Make sure the disguise isn't the same thing
if (d != disguise) {
// If the loop'd disguise is hiding the disguise to everyone in its list
if (d.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) {
// If player is a observer in the loop
if (disguise.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) {
// If player is a observer in the disguise
// Remove them from the loop
if (name != null) {
d.removePlayer(name);
} else {
for (String playername : disguise.getObservers()) {
d.silentlyRemovePlayer(playername);
}
}
} else if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) {
// If player is not a observer in the loop
if (name != null) {
if (!disguise.getObservers().contains(name)) {
d.removePlayer(name);
}
} else {
for (String playername : new ArrayList<String>(d.getObservers())) {
if (!disguise.getObservers().contains(playername)) {
d.silentlyRemovePlayer(playername);
}
}
}
}
} else if (d.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) {
// Here you add it to the loop if they see the disguise
if (disguise.getDisguiseTarget() == TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS) {
// Everyone who is in the disguise needs to be added to the loop
if (name != null) {
d.addPlayer(name);
} else {
for (String playername : disguise.getObservers()) {
d.silentlyAddPlayer(playername);
}
}
} else if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) {
// This here is a paradox.
// If fed a name. I can do this.
// But the rest of the time.. Its going to conflict.
// The below is debug output. Most people wouldn't care for it.
// System.out.print("Cannot set more than one " + TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS
// + " on a entity. Removed the old disguise.");
disguiseItel.remove();
d.removeDisguise();
}
}
}
}
}
}
/**
* Sends entity removal packets, as this disguise was removed
*/
public static void destroyEntity(TargetedDisguise disguise) {
try {
Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) {
HashSet trackedPlayers = (HashSet) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(
entityTrackerEntry);
HashSet cloned = (HashSet) trackedPlayers.clone();
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, new int[] { disguise.getEntity().getEntityId() });
for (Object p : cloned) {
Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (player == disguise.getEntity() || disguise.canSee(player)) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void doBoundingBox(TargetedDisguise disguise) {
// TODO Slimes
Entity entity = disguise.getEntity();
if (entity != null) {
if (isDisguiseInUse(disguise)) {
DisguiseValues disguiseValues = DisguiseValues.getDisguiseValues(disguise.getType());
FakeBoundingBox disguiseBox = disguiseValues.getAdultBox();
if (disguiseValues.getBabyBox() != null) {
if ((disguise.getWatcher() instanceof AgeableWatcher && ((AgeableWatcher) disguise.getWatcher()).isBaby())
|| (disguise.getWatcher() instanceof ZombieWatcher && ((ZombieWatcher) disguise.getWatcher())
.isBaby())) {
disguiseBox = disguiseValues.getBabyBox();
}
}
ReflectionManager.setBoundingBox(entity, disguiseBox);
} else {
DisguiseValues entityValues = DisguiseValues.getDisguiseValues(DisguiseType.getType(entity.getType()));
FakeBoundingBox entityBox = entityValues.getAdultBox();
if (entityValues.getBabyBox() != null) {
if ((entity instanceof Ageable && !((Ageable) entity).isAdult())
|| (entity instanceof Zombie && ((Zombie) entity).isBaby())) {
entityBox = entityValues.getBabyBox();
}
}
ReflectionManager.setBoundingBox(entity, entityBox);
}
}
}
public static HashSet<String> getAddedByPlugins() {
return addedByPlugins;
}
public static PacketContainer[] getBedChunkPacket(Player player, Location newLoc, Location oldLoc) {
int i = 0;
PacketContainer[] packets = new PacketContainer[newLoc != null ? 2 + (oldLoc != null ? 1 : 0) : 1];
for (Location loc : new Location[] { oldLoc, newLoc }) {
if (loc == null) {
continue;
}
try {
int chunkX = (int) Math.floor(loc.getX() / 16D) - 17, chunkZ = (int) Math.floor(loc.getZ() / 16D) - 17;
chunkX -= chunkX % 8;
chunkZ -= chunkZ % 8;
xChunk.set(bedChunk, chunkX);
zChunk.set(bedChunk, chunkZ);
} catch (Exception ex) {
ex.printStackTrace();
}
// Make unload packets
try {
packets[i] = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, bedChunk, true, 0, 40)
.createPacket(bedChunk, true, 0, 48);
} catch (IllegalArgumentException ex) {
packets[i] = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, bedChunk, true, 0)
.createPacket(bedChunk, true, 0);
}
i++;
// Make load packets
if (oldLoc == null || i > 1) {
packets[i] = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.MAP_CHUNK_BULK, Arrays.asList(bedChunk))
.createPacket(Arrays.asList(bedChunk));
i++;
}
}
return packets;
}
public static PacketContainer[] getBedPackets(Player player, Location loc, Location playerLocation, PlayerDisguise disguise) {
Entity entity = disguise.getEntity();
PacketContainer setBed = new PacketContainer(PacketType.Play.Server.BED);
StructureModifier<Integer> bedInts = setBed.getIntegers();
bedInts.write(0, entity.getEntityId());
PlayerWatcher watcher = disguise.getWatcher();
int chunkX = (int) Math.floor(playerLocation.getX() / 16D) - 17, chunkZ = (int) Math
.floor(playerLocation.getZ() / 16D) - 17;
chunkX -= chunkX % 8;
chunkZ -= chunkZ % 8;
bedInts.write(1, (chunkX * 16) + 1 + watcher.getSleepingDirection().getModX());
bedInts.write(3, (chunkZ * 16) + 1 + watcher.getSleepingDirection().getModZ());
PacketContainer teleport = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
StructureModifier<Integer> ints = teleport.getIntegers();
ints.write(0, entity.getEntityId());
ints.write(1, (int) Math.floor(loc.getX() * 32));
ints.write(2, (int) Math.floor((PacketsManager.getYModifier(disguise.getEntity(), disguise) + loc.getY()) * 32));
ints.write(3, (int) Math.floor(loc.getZ() * 32));
return new PacketContainer[] { setBed, teleport };
}
public static Disguise getClonedDisguise(String key) {
if (clonedDisguises.containsKey(key)) {
return clonedDisguises.get(key).clone();
}
return null;
}
public static PacketContainer getDestroyPacket(int... ids) {
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, ids);
return destroyPacket;
}
public static TargetedDisguise getDisguise(Player observer, Entity entity) {
UUID entityId = entity.getUniqueId();
if (futureDisguises.containsKey(entity.getEntityId())) {
for (TargetedDisguise disguise : futureDisguises.remove(entity.getEntityId())) {
addDisguise(entityId, disguise);
}
}
if (getDisguises().containsKey(entityId)) {
for (TargetedDisguise disguise : getDisguises().get(entityId)) {
if (disguise.canSee(observer)) {
return disguise;
}
}
}
return null;
}
public static HashMap<UUID, HashSet<TargetedDisguise>> getDisguises() {
return disguisesInUse;
}
public static TargetedDisguise[] getDisguises(UUID entityId) {
if (getDisguises().containsKey(entityId)) {
HashSet<TargetedDisguise> disguises = getDisguises().get(entityId);
return disguises.toArray(new TargetedDisguise[disguises.size()]);
}
return new TargetedDisguise[0];
}
public static HashMap<Integer, HashSet<TargetedDisguise>> getFutureDisguises() {
return futureDisguises;
}
public static WrappedGameProfile getGameProfile(String playerName) {
return gameProfiles.get(playerName.toLowerCase());
}
public static HashMap<String, WrappedGameProfile> getGameProfiles() {
return gameProfiles;
}
public static TargetedDisguise getMainDisguise(UUID entityId) {
TargetedDisguise toReturn = null;
if (getDisguises().containsKey(entityId)) {
for (TargetedDisguise disguise : getDisguises().get(entityId)) {
if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) {
return disguise;
}
toReturn = disguise;
}
}
return toReturn;
}
/**
* Get all EntityPlayers who have this entity in their Entity Tracker And they are in the targetted disguise.
*/
public static ArrayList<Player> getPerverts(Disguise disguise) {
ArrayList<Player> players = new ArrayList<Player>();
try {
Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) {
HashSet trackedPlayers = (HashSet) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(
entityTrackerEntry);
for (Object p : trackedPlayers) {
Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (((TargetedDisguise) disguise).canSee(player)) {
players.add(player);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return players;
}
public static WrappedGameProfile getProfileFromMojang(final PlayerDisguise disguise) {
final String nameToFetch = disguise.getSkin() != null ? disguise.getSkin() : disguise.getName();
final boolean remove = getAddedByPlugins().contains(nameToFetch.toLowerCase());
return getProfileFromMojang(nameToFetch, new LibsProfileLookup() {
@Override
public void onLookup(WrappedGameProfile gameProfile) {
if (remove) {
getAddedByPlugins().remove(nameToFetch.toLowerCase());
}
if (DisguiseAPI.isDisguiseInUse(disguise)
&& (!gameProfile.getName().equals(
disguise.getSkin() != null ? disguise.getSkin() : disguise.getName())
|| !gameProfile.getProperties().isEmpty())) {
disguise.setGameProfile(gameProfile);
DisguiseUtilities.refreshTrackers(disguise);
}
}
});
}
/**
* 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 WrappedGameProfile getProfileFromMojang(String playerName, LibsProfileLookup runnableIfCantReturn) {
return getProfileFromMojang(playerName, (Object) runnableIfCantReturn);
}
private static WrappedGameProfile getProfileFromMojang(final String origName, final Object runnable) {
final String playerName = origName.toLowerCase();
if (gameProfiles.containsKey(playerName)) {
if (gameProfiles.get(playerName) != null) {
return gameProfiles.get(playerName);
}
} else if (Pattern.matches("([A-Za-z0-9_]){1,16}", origName)) {
getAddedByPlugins().add(playerName);
Player player = Bukkit.getPlayerExact(playerName);
if (player != null) {
WrappedGameProfile gameProfile = ReflectionManager.getGameProfile(player);
if (!gameProfile.getProperties().isEmpty()) {
gameProfiles.put(playerName, gameProfile);
return gameProfile;
}
}
// Add null so that if this is called again. I already know I'm doing something about it
gameProfiles.put(playerName, null);
Bukkit.getScheduler().runTaskAsynchronously(libsDisguises, new Runnable() {
public void run() {
try {
final WrappedGameProfile gameProfile = lookupGameProfile(origName);
Bukkit.getScheduler().runTask(libsDisguises, new Runnable() {
public void run() {
if (!gameProfile.getProperties().isEmpty()) {
if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) {
gameProfiles.put(playerName, gameProfile);
}
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);
}
}
}
}
}
});
} catch (Exception e) {
if (gameProfiles.containsKey(playerName) && gameProfiles.get(playerName) == null) {
gameProfiles.remove(playerName);
getAddedByPlugins().remove(playerName);
}
System.out.print("[LibsDisguises] Error when fetching " + playerName + "'s uuid from mojang: "
+ e.getMessage());
}
}
});
} else {
return ReflectionManager.getGameProfile(null, origName);
}
if (runnable != null) {
if (!runnables.containsKey(playerName)) {
runnables.put(playerName, new ArrayList<Object>());
}
runnables.get(playerName).add(runnable);
}
return ReflectionManager.getGameProfile(null, origName);
}
/**
* 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 WrappedGameProfile getProfileFromMojang(String playerName, Runnable runnableIfCantReturn) {
return getProfileFromMojang(playerName, (Object) runnableIfCantReturn);
}
public static HashSet<UUID> getSelfDisguised() {
return selfDisguised;
}
public static boolean hasGameProfile(String playerName) {
return getGameProfile(playerName) != null;
}
public static void init(LibsDisguises disguises) {
libsDisguises = disguises;
}
public static boolean isDisguiseInUse(Disguise disguise) {
return disguise.getEntity() != null && getDisguises().containsKey(disguise.getEntity().getUniqueId())
&& getDisguises().get(disguise.getEntity().getUniqueId()).contains(disguise);
}
/**
* This is called on a thread as it is thread blocking
*/
public static WrappedGameProfile lookupGameProfile(String playerName) {
return ReflectionManager.getSkullBlob(ReflectionManager.grabProfileAddUUID(playerName));
}
/**
* Please note that in the future when 'DualInt' and the like are removed. This should break.. However, that should be negated
* in the future as I'd be able to set the watcher index's as per the spigot version. Instead of checking on the player's
* version every single packet..
*/
public static List<WrappedWatchableObject> rebuildForVersion(Player player, FlagWatcher watcher,
List<WrappedWatchableObject> list) {
if (true) // Use for future protocol compatibility
return list;
ArrayList<WrappedWatchableObject> rebuiltList = new ArrayList<WrappedWatchableObject>();
ArrayList<WrappedWatchableObject> backups = new ArrayList<WrappedWatchableObject>();
for (WrappedWatchableObject obj : list) {
if (obj.getValue().getClass().getName().startsWith("org.")) {
backups.add(obj);
continue;
}
switch (obj.getIndex()) {
// TODO: Future version support
}
}
Iterator<WrappedWatchableObject> itel = backups.iterator();
while (itel.hasNext()) {
int index = itel.next().getIndex();
for (WrappedWatchableObject obj2 : rebuiltList) {
if (index == obj2.getIndex()) {
itel.remove();
break;
}
}
}
rebuiltList.addAll(backups);
return rebuiltList;
}
/**
* Resends the entity to this specific player
*/
public static void refreshTracker(final TargetedDisguise disguise, String player) {
if (disguise.getEntity() != null && disguise.getEntity().isValid()) {
try {
PacketContainer destroyPacket = getDestroyPacket(disguise.getEntity().getEntityId());
if (disguise.isDisguiseInUse() && disguise.getEntity() instanceof Player
&& ((Player) disguise.getEntity()).getName().equalsIgnoreCase(player)) {
removeSelfDisguise((Player) disguise.getEntity());
if (disguise.isSelfDisguiseVisible())
selfDisguised.add(disguise.getEntity().getUniqueId());
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) disguise.getEntity(), destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
try {
DisguiseUtilities.sendSelfDisguise((Player) disguise.getEntity(), disguise);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 2);
} else {
final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) {
HashSet trackedPlayers = (HashSet) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers")
.get(entityTrackerEntry);
Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
HashSet cloned = (HashSet) trackedPlayers.clone();
for (final Object p : cloned) {
Player pl = (Player) ReflectionManager.getBukkitEntity(p);
if (player.equalsIgnoreCase((pl).getName())) {
clear.invoke(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(pl, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
try {
updatePlayer.invoke(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 2);
break;
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* A convenience method for me to refresh trackers in other plugins
*/
public static void refreshTrackers(Entity entity) {
if (entity.isValid()) {
try {
PacketContainer destroyPacket = getDestroyPacket(entity.getEntityId());
final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(entity);
if (entityTrackerEntry != null) {
HashSet trackedPlayers = (HashSet) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(
entityTrackerEntry);
Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
HashSet cloned = (HashSet) trackedPlayers.clone();
for (final Object p : cloned) {
Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (player != entity) {
clear.invoke(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
try {
updatePlayer.invoke(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 2);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* Resends the entity to all the watching players, which is where the magic begins
*/
public static void refreshTrackers(final TargetedDisguise disguise) {
if (disguise.getEntity().isValid()) {
PacketContainer destroyPacket = getDestroyPacket(disguise.getEntity().getEntityId());
try {
if (selfDisguised.contains(disguise.getEntity().getUniqueId()) && disguise.isDisguiseInUse()) {
removeSelfDisguise((Player) disguise.getEntity());
selfDisguised.add(disguise.getEntity().getUniqueId());
ProtocolLibrary.getProtocolManager().sendServerPacket((Player) disguise.getEntity(), destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
try {
DisguiseUtilities.sendSelfDisguise((Player) disguise.getEntity(), disguise);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 2);
}
final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity());
if (entityTrackerEntry != null) {
HashSet trackedPlayers = (HashSet) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(
entityTrackerEntry);
Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", "clear",
ReflectionManager.getNmsClass("EntityPlayer"));
final Method updatePlayer = ReflectionManager.getNmsMethod("EntityTrackerEntry", "updatePlayer",
ReflectionManager.getNmsClass("EntityPlayer"));
HashSet cloned = (HashSet) trackedPlayers.clone();
for (final Object p : cloned) {
Player player = (Player) ReflectionManager.getBukkitEntity(p);
if (disguise.getEntity() != player && disguise.canSee(player)) {
clear.invoke(entityTrackerEntry, p);
ProtocolLibrary.getProtocolManager().sendServerPacket(player, destroyPacket);
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
try {
updatePlayer.invoke(entityTrackerEntry, p);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}, 2);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public static boolean removeDisguise(TargetedDisguise disguise) {
UUID entityId = disguise.getEntity().getUniqueId();
if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) {
if (getDisguises().get(entityId).isEmpty()) {
getDisguises().remove(entityId);
}
if (disguise.getDisguiseTarget() == TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS && disguise.isModifyBoundingBox()) {
doBoundingBox(disguise);
}
return true;
}
return false;
}
@Deprecated
public static void removeGameprofile(String string) {
removeGameProfile(string);
}
public static void removeGameProfile(String string) {
gameProfiles.remove(string.toLowerCase());
}
public static void removeSelfDisguise(Player player) {
if (selfDisguised.contains(player.getUniqueId())) {
// Send a packet to destroy the fake entity
PacketContainer packet = getDestroyPacket(DisguiseAPI.getSelfDisguiseId());
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
} catch (Exception ex) {
ex.printStackTrace();
}
// Remove the fake entity ID from the disguise bin
selfDisguised.remove(player.getUniqueId());
// Get the entity tracker
try {
Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(player);
if (entityTrackerEntry != null) {
HashSet trackedPlayers = (HashSet) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(
entityTrackerEntry);
// If the tracker exists. Remove himself from his tracker
trackedPlayers.remove(ReflectionManager.getNmsEntity(player));
}
} catch (Exception ex) {
ex.printStackTrace();
}
// Resend entity metadata else he will be invisible to himself until its resent
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(
player,
ProtocolLibrary
.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(),
WrappedDataWatcher.getEntityWatcher(player), true)
.createPacket(player.getEntityId(), WrappedDataWatcher.getEntityWatcher(player), true));
} catch (Exception ex) {
ex.printStackTrace();
}
player.updateInventory();
}
}
/**
* Sends the self disguise to the player
*/
public static void sendSelfDisguise(final Player player, final TargetedDisguise disguise) {
try {
if (!disguise.isDisguiseInUse() || !player.isValid() || !player.isOnline() || !disguise.isSelfDisguiseVisible()
|| !disguise.canSee(player)) {
return;
}
Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(player);
if (entityTrackerEntry == null) {
// A check incase the tracker is null.
// If it is, then this method will be run again in one tick. Which is when it should be constructed.
// Else its going to run in a infinite loop hue hue hue..
// At least until this disguise is discarded
Bukkit.getScheduler().runTask(libsDisguises, new Runnable() {
public void run() {
if (DisguiseAPI.getDisguise(player, player) == disguise) {
sendSelfDisguise(player, disguise);
}
}
});
return;
}
// Add himself to his own entity tracker
((HashSet<Object>) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry))
.add(ReflectionManager.getNmsEntity(player));
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
// Send the player a packet with himself being spawned
manager.sendServerPacket(player, manager.createPacketConstructor(PacketType.Play.Server.NAMED_ENTITY_SPAWN, player)
.createPacket(player));
WrappedDataWatcher dataWatcher = WrappedDataWatcher.getEntityWatcher(player);
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(), dataWatcher,
true).createPacket(player.getEntityId(), dataWatcher, true));
boolean isMoving = false;
try {
Field field = ReflectionManager.getNmsClass("EntityTrackerEntry").getDeclaredField("isMoving");
field.setAccessible(true);
isMoving = field.getBoolean(entityTrackerEntry);
} catch (Exception ex) {
ex.printStackTrace();
}
// Send the velocity packets
if (isMoving) {
Vector velocity = player.getVelocity();
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_VELOCITY, player.getEntityId(),
velocity.getX(), velocity.getY(), velocity.getZ()).createPacket(player.getEntityId(),
velocity.getX(), velocity.getY(), velocity.getZ()));
}
// Why the hell would he even need this. Meh.
if (player.getVehicle() != null && player.getEntityId() > player.getVehicle().getEntityId()) {
sendSelfPacket(player,
manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player, player.getVehicle())
.createPacket(0, player, player.getVehicle()));
} else if (player.getPassenger() != null && player.getEntityId() > player.getPassenger().getEntityId()) {
sendSelfPacket(player,
manager.createPacketConstructor(PacketType.Play.Server.ATTACH_ENTITY, 0, player.getPassenger(), player)
.createPacket(0, player.getPassenger(), player));
}
// Resend the armor
for (int i = 0; i < 5; i++) {
ItemStack item;
if (i == 0) {
item = player.getItemInHand();
} else {
item = player.getInventory().getArmorContents()[i - 1];
}
if (item != null && item.getType() != Material.AIR) {
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EQUIPMENT, player.getEntityId(), i,
item).createPacket(player.getEntityId(), i, item));
}
}
Location loc = player.getLocation();
// If the disguised is sleeping for w/e reason
if (player.isSleeping()) {
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.BED, player, loc.getBlockX(), loc.getBlockY(),
loc.getBlockZ()).createPacket(player, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
}
// Resend any active potion effects
for (PotionEffect potionEffect : player.getActivePotionEffects()) {
Object mobEffect = ReflectionManager.createMobEffect(potionEffect);
sendSelfPacket(player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EFFECT, player.getEntityId(), mobEffect)
.createPacket(player.getEntityId(), mobEffect));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Method to send a packet to the self disguise, translate his entity ID to the fake id.
*/
private static void sendSelfPacket(final Player player, PacketContainer packet) {
PacketContainer[][] transformed = PacketsManager.transformPacket(packet, player, player);
PacketContainer[] packets = transformed == null ? null : transformed[0];
final PacketContainer[] delayed = transformed == null ? null : transformed[1];
try {
if (packets == null) {
packets = new PacketContainer[] { packet };
}
for (PacketContainer p : packets) {
p = p.deepClone();
p.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
ProtocolLibrary.getProtocolManager().sendServerPacket(player, p, false);
}
if (delayed != null && delayed.length > 0) {
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
try {
for (PacketContainer packet : delayed) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
}
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* Setup it so he can see himself when disguised
*/
public static void setupFakeDisguise(final Disguise disguise) {
Entity e = disguise.getEntity();
// If the disguises entity is null, or the disguised entity isn't a player return
if (e == null || !(e instanceof Player) || !getDisguises().containsKey(e.getUniqueId())
|| !getDisguises().get(e.getUniqueId()).contains(disguise)) {
return;
}
Player player = (Player) e;
// Check if he can even see this..
if (!((TargetedDisguise) disguise).canSee(player)) {
return;
}
// Remove the old disguise, else we have weird disguises around the place
DisguiseUtilities.removeSelfDisguise(player);
// If the disguised player can't see himself. Return
if (!disguise.isSelfDisguiseVisible() || !PacketsManager.isViewDisguisesListenerEnabled() || player.getVehicle() != null) {
return;
}
selfDisguised.add(player.getUniqueId());
sendSelfDisguise(player, (TargetedDisguise) disguise);
if (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf()) {
if (PacketsManager.isInventoryListenerEnabled()) {
player.updateInventory();
}
}
}
}

View File

@@ -0,0 +1,145 @@
package me.libraryaddict.disguise.utilities;
import java.util.HashMap;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
public class DisguiseValues {
private static HashMap<DisguiseType, DisguiseValues> values = new HashMap<DisguiseType, DisguiseValues>();
public static DisguiseValues getDisguiseValues(DisguiseType type) {
switch (type) {
case DONKEY:
case MULE:
case UNDEAD_HORSE:
case SKELETON_HORSE:
type = DisguiseType.HORSE;
break;
case MINECART_CHEST:
case MINECART_COMMAND:
case MINECART_FURNACE:
case MINECART_HOPPER:
case MINECART_TNT:
case MINECART_MOB_SPAWNER:
type = DisguiseType.MINECART;
break;
case WITHER_SKELETON:
type = DisguiseType.SKELETON;
break;
case ZOMBIE_VILLAGER:
type = DisguiseType.ZOMBIE;
break;
default:
break;
}
return values.get(type);
}
public static HashMap<Integer, Object> getMetaValues(DisguiseType type) {
return getDisguiseValues(type).getMetaValues();
}
public static Class getNmsEntityClass(DisguiseType type) {
return getDisguiseValues(type).getNmsEntityClass();
}
private FakeBoundingBox adultBox;
private FakeBoundingBox babyBox;
private float[] entitySize;
private int enumEntitySize;
private double maxHealth;
private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
private Class nmsEntityClass;
public DisguiseValues(DisguiseType type, Class classType, int entitySize, double maxHealth) {
values.put(type, this);
enumEntitySize = entitySize;
nmsEntityClass = classType;
this.maxHealth = maxHealth;
}
public FakeBoundingBox getAdultBox() {
return adultBox;
}
public FakeBoundingBox getBabyBox() {
return babyBox;
}
public float[] getEntitySize() {
return entitySize;
}
public int getEntitySize(double paramDouble) {
double d = paramDouble - (((int) Math.floor(paramDouble)) + 0.5D);
switch (enumEntitySize) {
case 1:
if (d < 0.0D ? d < -0.3125D : d < 0.3125D) {
return (int) Math.ceil(paramDouble * 32.0D);
}
return (int) Math.floor(paramDouble * 32.0D);
case 2:
if (d < 0.0D ? d < -0.3125D : d < 0.3125D) {
return (int) Math.floor(paramDouble * 32.0D);
}
return (int) Math.ceil(paramDouble * 32.0D);
case 3:
if (d > 0.0D) {
return (int) Math.floor(paramDouble * 32.0D);
}
return (int) Math.ceil(paramDouble * 32.0D);
case 4:
if (d < 0.0D ? d < -0.1875D : d < 0.1875D) {
return (int) Math.ceil(paramDouble * 32.0D);
}
return (int) Math.floor(paramDouble * 32.0D);
case 5:
if (d < 0.0D ? d < -0.1875D : d < 0.1875D) {
return (int) Math.floor(paramDouble * 32.0D);
}
return (int) Math.ceil(paramDouble * 32.0D);
default:
break;
}
if (d > 0.0D) {
return (int) Math.ceil(paramDouble * 32.0D);
}
return (int) Math.floor(paramDouble * 32.0D);
}
public double getMaxHealth() {
return maxHealth;
}
public HashMap<Integer, Object> getMetaValues() {
return metaValues;
}
public Class getNmsEntityClass() {
return nmsEntityClass;
}
public void setAdultBox(FakeBoundingBox newBox) {
adultBox = newBox;
}
public void setBabyBox(FakeBoundingBox newBox) {
babyBox = newBox;
}
public void setEntitySize(float[] size) {
this.entitySize = size;
}
public void setMetaValue(int no, Object value) {
metaValues.put(no, value);
}
}

View File

@@ -0,0 +1,26 @@
package me.libraryaddict.disguise.utilities;
public class FakeBoundingBox {
private double xMod;
private double yMod;
private double zMod;
public FakeBoundingBox(double xMod, double yMod, double zMod) {
this.xMod = xMod;
this.yMod = yMod;
this.zMod = zMod;
}
public double getX() {
return xMod / 2;
}
public double getY() {
return yMod;
}
public double getZ() {
return zMod / 2;
}
}

View File

@@ -0,0 +1,8 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
public interface LibsProfileLookup {
public void onLookup(WrappedGameProfile gameProfile);
}

View File

@@ -0,0 +1,24 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.ProfileLookupCallback;
public class LibsProfileLookupCaller implements ProfileLookupCallback {
private WrappedGameProfile gameProfile;
public WrappedGameProfile getGameProfile() {
return gameProfile;
}
@Override
public void onProfileLookupFailed(GameProfile gameProfile, Exception arg1) {
}
@Override
public void onProfileLookupSucceeded(GameProfile profile) {
gameProfile = WrappedGameProfile.fromHandle(profile);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,633 @@
package me.libraryaddict.disguise.utilities;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.collect.ImmutableMap;
import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import org.bukkit.potion.PotionEffect;
public class ReflectionManager {
public enum LibVersion {
V1_8;
private static LibVersion currentVersion;
static {
//String mcVersion = Bukkit.getVersion().split("MC: ")[1].replace(")", "");
currentVersion = V1_8;
}
public static LibVersion getGameVersion() {
return currentVersion;
}
}
private static final String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3];
private static final Class<?> craftItemClass;
private static Method damageAndIdleSoundMethod;
private static final Field entitiesField;
private static final Constructor<?> boundingBoxConstructor;
private static final Method setBoundingBoxMethod;
/**
* Map of mc-dev simple class name to fully qualified Forge class name.
*/
private static Map<String, String> ForgeClassMappings;
/**
* Map of Forge fully qualified class names to a map from mc-dev field names to Forge field names.
*/
private static Map<String, Map<String, String>> ForgeFieldMappings;
/**
* Map of Forge fully qualified class names to a map from mc-dev method names to a map from method signatures to Forge method
* names.
*/
private static Map<String, Map<String, Map<String, String>>> ForgeMethodMappings;
private static final Method ihmGet;
private static final boolean isForge = Bukkit.getServer().getName().contains("Cauldron")
|| Bukkit.getServer().getName().contains("MCPC-Plus");
private static final Field pingField;
private static Map<Class<?>, String> primitiveTypes;
private static final Field trackerField;
/*
* This portion of code is originally Copyright (C) 2014-2014 Kane York.
*
* In addition to the implicit license granted to libraryaddict to redistribuite the code, the
* code is also licensed to the public under the BSD 2-clause license.
*
* The publicly licensed version may be viewed here: https://gist.github.com/riking/2f330f831c30e2276df7
*/
static {
final String nameseg_class = "a-zA-Z0-9$_";
final String fqn_class = nameseg_class + "/";
primitiveTypes = ImmutableMap.<Class<?>, String> builder().put(boolean.class, "Z").put(byte.class, "B")
.put(char.class, "C").put(short.class, "S").put(int.class, "I").put(long.class, "J").put(float.class, "F")
.put(double.class, "D").put(void.class, "V").build();
if (isForge) {
// Initialize the maps by reading the srg file
ForgeClassMappings = new HashMap<String, String>();
ForgeFieldMappings = new HashMap<String, Map<String, String>>();
ForgeMethodMappings = new HashMap<String, Map<String, Map<String, String>>>();
try {
InputStream stream = Class.forName("net.minecraftforge.common.MinecraftForge").getClassLoader()
.getResourceAsStream("mappings/" + getBukkitVersion() + "/cb2numpkg.srg");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
// 1: cb-simpleName
// 2: forge-fullName (Needs dir2fqn())
Pattern classPattern = Pattern.compile("^CL: net/minecraft/server/([" + nameseg_class + "]+) ([" + fqn_class
+ "]+)$");
// 1: cb-simpleName
// 2: cb-fieldName
// 3: forge-fullName (Needs dir2fqn())
// 4: forge-fieldName
Pattern fieldPattern = Pattern.compile("^FD: net/minecraft/server/([" + nameseg_class + "]+)/([" + nameseg_class
+ "]+) ([" + fqn_class + "]+)/([" + nameseg_class + "]+)$");
// 1: cb-simpleName
// 2: cb-methodName
// 3: cb-signature-args
// 4: cb-signature-ret
// 5: forge-fullName (Needs dir2fqn())
// 6: forge-methodName
// 7: forge-signature-args
// 8: forge-signature-ret
Pattern methodPattern = Pattern.compile("^MD: net/minecraft/server/([" + fqn_class + "]+)/([" + nameseg_class
+ "]+) \\(([;\\[" + fqn_class + "]*)\\)([;\\[" + fqn_class + "]+) " + "([" + fqn_class + "]+)/(["
+ nameseg_class + "]+) \\(([;\\[" + fqn_class + "]*)\\)([;\\[" + fqn_class + "]+)$");
String line;
while ((line = reader.readLine()) != null) {
Matcher classMatcher = classPattern.matcher(line);
if (classMatcher.matches()) {
// by CB class name
ForgeClassMappings.put(classMatcher.group(1), dir2fqn(classMatcher.group(2)));
continue;
}
Matcher fieldMatcher = fieldPattern.matcher(line);
if (fieldMatcher.matches()) {
// by CB class name
Map<String, String> innerMap = ForgeFieldMappings.get(dir2fqn(fieldMatcher.group(3)));
if (innerMap == null) {
innerMap = new HashMap<String, String>();
ForgeFieldMappings.put(dir2fqn(fieldMatcher.group(3)), innerMap);
}
// by CB field name to Forge field name
innerMap.put(fieldMatcher.group(2), fieldMatcher.group(4));
continue;
}
Matcher methodMatcher = methodPattern.matcher(line);
if (methodMatcher.matches()) {
// get by CB class name
Map<String, Map<String, String>> middleMap = ForgeMethodMappings.get(dir2fqn(methodMatcher.group(5)));
if (middleMap == null) {
middleMap = new HashMap<String, Map<String, String>>();
ForgeMethodMappings.put(dir2fqn(methodMatcher.group(5)), middleMap);
}
// get by CB method name
Map<String, String> innerMap = middleMap.get(methodMatcher.group(2));
if (innerMap == null) {
innerMap = new HashMap<String, String>();
middleMap.put(methodMatcher.group(2), innerMap);
}
// store the parameter strings
innerMap.put(methodMatcher.group(3), methodMatcher.group(6));
innerMap.put(methodMatcher.group(7), methodMatcher.group(6));
}
}
System.out.println("[LibsDisguises] Loaded in Cauldron/Forge mode");
System.out.println("[LibsDisguises] Loaded " + ForgeClassMappings.size() + " Cauldron class mappings");
System.out.println("[LibsDisguises] Loaded " + ForgeFieldMappings.size() + " Cauldron field mappings");
System.out.println("[LibsDisguises] Loaded " + ForgeMethodMappings.size() + " Cauldron method mappings");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.err
.println("Warning: Running on Cauldron server, but couldn't load mappings file. LibsDisguises will likely crash!");
} catch (IOException e) {
e.printStackTrace();
System.err
.println("Warning: Running on Cauldron server, but couldn't load mappings file. LibsDisguises will likely crash!");
}
}
}
static {
for (Method method : getNmsClass("EntityLiving").getDeclaredMethods()) {
try {
if (method.getReturnType() == float.class && Modifier.isProtected(method.getModifiers())
&& method.getParameterTypes().length == 0) {
Object entity = createEntityInstance("Cow");
method.setAccessible(true);
float value = (Float) method.invoke(entity);
if (value == 0.4F) {
damageAndIdleSoundMethod = method;
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
craftItemClass = getCraftClass("inventory.CraftItemStack");
pingField = getNmsField("EntityPlayer", "ping");
trackerField = getNmsField("WorldServer", "tracker");
entitiesField = getNmsField("EntityTracker", "trackedEntities");
ihmGet = getNmsMethod("IntHashMap", "get", int.class);
boundingBoxConstructor = getNmsConstructor("AxisAlignedBB",double.class, double.class, double.class,
double.class, double.class, double.class);
setBoundingBoxMethod = getNmsMethod("Entity", "a", getNmsClass("AxisAlignedBB"));
}
public static Object createEntityInstance(String entityName) {
try {
Class<?> entityClass = getNmsClass("Entity" + entityName);
Object entityObject;
Object world = getWorld(Bukkit.getWorlds().get(0));
if (entityName.equals("Player")) {
Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null);
Object playerinteractmanager = getNmsClass("PlayerInteractManager").getConstructor(getNmsClass("World"))
.newInstance(world);
WrappedGameProfile gameProfile = getGameProfile(null, "LibsDisguises");
entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"),
gameProfile.getHandleType(), playerinteractmanager.getClass()).newInstance(minecraftServer, world,
gameProfile.getHandle(), playerinteractmanager);
} else if (entityName.equals("EnderPearl")) {
entityObject = entityClass.getConstructor(getNmsClass("World"), getNmsClass("EntityLiving"))
.newInstance(world, createEntityInstance("Cow"));
} else {
entityObject = entityClass.getConstructor(getNmsClass("World")).newInstance(world);
}
return entityObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object createMobEffect(int id, int duration, int amplification, boolean ambient, boolean particles) {
try {
return getNmsClass("MobEffect").getConstructor(int.class, int.class, int.class, boolean.class, boolean.class)
.newInstance(id, duration, amplification, ambient, particles);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object createMobEffect(PotionEffect effect) {
return createMobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles());
}
private static String dir2fqn(String s) {
return s.replaceAll("/", ".");
}
public static FakeBoundingBox getBoundingBox(Entity entity) {
try {
Object boundingBox = getNmsMethod("Entity", "getBoundingBox").invoke(getNmsEntity(entity));
double x = 0, y = 0, z = 0;
int stage = 0;
for (Field field : boundingBox.getClass().getFields()) {
if (field.getType().getSimpleName().equals("double")) {
stage++;
switch (stage) {
case 1:
x -= field.getDouble(boundingBox);
break;
case 2:
y -= field.getDouble(boundingBox);
break;
case 3:
z -= field.getDouble(boundingBox);
break;
case 4:
x += field.getDouble(boundingBox);
break;
case 5:
y += field.getDouble(boundingBox);
break;
case 6:
z += field.getDouble(boundingBox);
break;
default:
throw new Exception("Error while setting the bounding box, more doubles than I thought??");
}
}
}
return new FakeBoundingBox(x, y, z);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Entity getBukkitEntity(Object nmsEntity) {
try {
return (Entity) getNmsMethod("Entity", "getBukkitEntity").invoke(nmsEntity);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static ItemStack getBukkitItem(Object nmsItem) {
try {
return (ItemStack) craftItemClass.getMethod("asBukkitCopy", getNmsClass("ItemStack")).invoke(null, nmsItem);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getBukkitVersion() {
return bukkitVersion;
}
public static Class<?> getCraftClass(String className) {
try {
return Class.forName("org.bukkit.craftbukkit." + getBukkitVersion() + "." + className);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getCraftSound(Sound sound) {
try {
return (String) getCraftClass("CraftSound").getMethod("getSound", Sound.class).invoke(null, sound);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Object getEntityTrackerEntry(Entity target) throws Exception {
Object world = getWorld(target.getWorld());
Object tracker = trackerField.get(world);
Object trackedEntities = entitiesField.get(tracker);
return ihmGet.invoke(trackedEntities, target.getEntityId());
}
public static String getEnumArt(Art art) {
try {
Object enumArt = getCraftClass("CraftArt").getMethod("BukkitToNotch", Art.class).invoke(null, art);
for (Field field : enumArt.getClass().getFields()) {
if (field.getType() == String.class) {
return (String) field.get(enumArt);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Object getBlockPosition(int x, int y, int z) {
try {
return getNmsClass("BlockPosition").getConstructor(int.class, int.class, int.class).newInstance(x, y, z);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Enum getEnumDirection(int direction) {
try {
return (Enum) getNmsMethod("EnumDirection", "fromType2", int.class).invoke(null, direction);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Enum getEnumPlayerInfoAction(int action) {
try {
return (Enum) getNmsClass("PacketPlayOutPlayerInfo$EnumPlayerInfoAction").getEnumConstants()[action];
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Object getPlayerInfoData(Object playerInfoPacket, WrappedGameProfile gameProfile) {
try {
Object playerListName = getNmsClass("ChatComponentText").getConstructor(String.class)
.newInstance(gameProfile.getName());
return getNmsClass("PacketPlayOutPlayerInfo$PlayerInfoData").getConstructor(getNmsClass("PacketPlayOutPlayerInfo"),
gameProfile.getHandleType(), int.class, getNmsClass("WorldSettings$EnumGamemode"), getNmsClass("IChatBaseComponent"))
.newInstance(playerInfoPacket, gameProfile.getHandle(), 0,
getNmsClass("WorldSettings$EnumGamemode").getEnumConstants()[1], playerListName);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static WrappedGameProfile getGameProfile(Player player) {
return WrappedGameProfile.fromPlayer(player);
}
public static WrappedGameProfile getGameProfile(UUID uuid, String playerName) {
try {
return new WrappedGameProfile(uuid != null ? uuid : UUID.randomUUID(), playerName);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static WrappedGameProfile getGameProfileWithThisSkin(UUID uuid, String playerName, WrappedGameProfile profileWithSkin) {
try {
WrappedGameProfile gameProfile = new WrappedGameProfile(uuid != null ? uuid : UUID.randomUUID(), playerName);
gameProfile.getProperties().putAll(profileWithSkin.getProperties());
return gameProfile;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Class getNmsClass(String className) {
if (isForge) {
String forgeName = ForgeClassMappings.get(className);
if (forgeName != null) {
try {
return Class.forName(forgeName);
} catch (ClassNotFoundException ignored) {
}
} else {
// Throw, because the default cannot possibly work
throw new RuntimeException("Missing Forge mapping for " + className);
}
}
try {
return Class.forName("net.minecraft.server." + getBukkitVersion() + "." + className);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Constructor getNmsConstructor(Class clazz, Class<?>... parameters) {
try {
return clazz.getConstructor(parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
public static Constructor getNmsConstructor(String className, Class<?>... parameters) {
return getNmsConstructor(getNmsClass(className), parameters);
}
public static Object getNmsEntity(Entity entity) {
try {
return getCraftClass("entity.CraftEntity").getMethod("getHandle").invoke(entity);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Field getNmsField(Class clazz, String fieldName) {
if (isForge) {
try {
return clazz.getField(ForgeFieldMappings.get(clazz.getName()).get(fieldName));
} catch (NoSuchFieldException ex) {
ex.printStackTrace();
} catch (NullPointerException ignored) {
}
}
try {
return clazz.getField(fieldName);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return null;
}
public static Field getNmsField(String className, String fieldName) {
return getNmsField(getNmsClass(className), fieldName);
}
public static Object getNmsItem(ItemStack itemstack) {
try {
return craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemstack);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Method getNmsMethod(Class<?> clazz, String methodName, Class<?>... parameters) {
if (isForge) {
try {
Map<String, String> innerMap = ForgeMethodMappings.get(clazz.getName()).get(methodName);
StringBuilder sb = new StringBuilder();
for (Class<?> cl : parameters) {
sb.append(methodSignaturePart(cl));
}
return clazz.getMethod(innerMap.get(sb.toString()), parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (NullPointerException ignored) {
}
}
try {
return clazz.getMethod(methodName, parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
public static Method getNmsMethod(String className, String methodName, Class<?>... parameters) {
return getNmsMethod(getNmsClass(className), methodName, parameters);
}
public static double getPing(Player player) {
try {
return (double) pingField.getInt(ReflectionManager.getNmsEntity(player));
} catch (Exception ex) {
ex.printStackTrace();
}
return 0D;
}
public static float[] getSize(Entity entity) {
try {
float length = getNmsField("Entity", "length").getFloat(getNmsEntity(entity));
float width = getNmsField("Entity", "width").getFloat(getNmsEntity(entity));
float height = (Float) getNmsMethod("Entity", "getHeadHeight").invoke(getNmsEntity(entity));
return new float[] { length, width, height };
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static WrappedGameProfile getSkullBlob(WrappedGameProfile gameProfile) {
try {
Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null);
for (Method method : getNmsClass("MinecraftServer").getMethods()) {
if (method.getReturnType().getSimpleName().equals("MinecraftSessionService")) {
Object session = method.invoke(minecraftServer);
return WrappedGameProfile.fromHandle(session.getClass()
.getMethod("fillProfileProperties", gameProfile.getHandleType(), boolean.class)
.invoke(session, gameProfile.getHandle(), true));
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Float getSoundModifier(Object entity) {
try {
damageAndIdleSoundMethod.setAccessible(true);
return (Float) damageAndIdleSoundMethod.invoke(entity);
} catch (Exception ex) {
}
return null;
}
public static Object getWorld(World world) {
try {
return getCraftClass("CraftWorld").getMethod("getHandle").invoke(world);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static WrappedGameProfile grabProfileAddUUID(String playername) {
try {
Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null);
for (Method method : getNmsClass("MinecraftServer").getMethods()) {
if (method.getReturnType().getSimpleName().equals("GameProfileRepository")) {
Object profileRepo = method.invoke(minecraftServer);
Object agent = Class.forName("com.mojang.authlib.Agent").getField("MINECRAFT").get(null);
LibsProfileLookupCaller callback = new LibsProfileLookupCaller();
profileRepo
.getClass()
.getMethod("findProfilesByNames", String[].class, agent.getClass(),
Class.forName("com.mojang.authlib.ProfileLookupCallback"))
.invoke(profileRepo, new String[] { playername }, agent, callback);
if (callback.getGameProfile() != null) {
return callback.getGameProfile();
}
return getGameProfile(null, playername);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static boolean isForge() {
return isForge;
}
private static String methodSignaturePart(Class<?> param) {
if (param.isArray()) {
return "[" + methodSignaturePart(param.getComponentType());
} else if (param.isPrimitive()) {
return primitiveTypes.get(param);
} else {
return "L" + param.getName().replaceAll("\\.", "/") + ";";
}
}
public static void removePlayer(Player player) {
}
public static void setAllowSleep(Player player) {
try {
Object nmsEntity = getNmsEntity(player);
Object connection = getNmsField(nmsEntity.getClass(), "playerConnection").get(nmsEntity);
Field check = getNmsField(connection.getClass(), "checkMovement");
check.setBoolean(connection, true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void setBoundingBox(Entity entity, FakeBoundingBox newBox) {
try {
Location loc = entity.getLocation();
Object boundingBox = boundingBoxConstructor.newInstance(loc.getX() - newBox.getX(), loc.getY() - newBox.getY(),
loc.getZ() - newBox.getZ(), loc.getX() + newBox.getX(), loc.getY() + newBox.getY(), loc.getZ() + newBox.getZ());
setBoundingBoxMethod.invoke(getNmsEntity(entity), boundingBox);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

View File

@@ -0,0 +1,58 @@
package me.libraryaddict.disguise.utilities;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Pattern;
public class UpdateChecker {
private String latestVersion;
private boolean checkHigher(String currentVersion, String newVersion) {
String current = toReadable(currentVersion);
String newVers = toReadable(newVersion);
return current.compareTo(newVers) < 0;
}
public void checkUpdate(String currentVersion) {
String version = getSpigotVersion();
if (version != null) {
if (checkHigher(currentVersion, version)) {
latestVersion = version;
}
}
}
public String getLatestVersion() {
return latestVersion;
}
/**
* Asks spigot for the version
*/
private String getSpigotVersion() {
try {
HttpURLConnection con = (HttpURLConnection) new URL("http://www.spigotmc.org/api/general.php").openConnection();
con.setDoOutput(true);
con.setRequestMethod("POST");
con.getOutputStream().write(
("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource=81").getBytes("UTF-8"));
String version = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
if (version.length() <= 7) {
return version;
}
} catch (Exception ex) {
System.out.print("[LibsDisguises] Failed to check for a update on spigot. Now checking bukkit..");
}
return null;
}
private String toReadable(String version) {
String[] split = Pattern.compile(".", Pattern.LITERAL).split(version.replace("v", ""));
version = "";
for (String s : split)
version += String.format("%4s", s);
return version;
}
}