Read desc
Renamed the package utils to utilities Moved Values and DisguiseSounds into it. Renamed Values to DisguiseValues Renamed another method in DisguiseValues
This commit is contained in:
391
src/me/libraryaddict/disguise/utilities/BaseDisguiseCommand.java
Normal file
391
src/me/libraryaddict/disguise/utilities/BaseDisguiseCommand.java
Normal file
@@ -0,0 +1,391 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import me.libraryaddict.disguise.disguisetypes.AnimalColor;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public abstract class BaseDisguiseCommand implements CommandExecutor {
|
||||
protected ArrayList<String> getAllowedDisguises(CommandSender sender) {
|
||||
String permissionNode = "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + ".";
|
||||
return getAllowedDisguises(sender, permissionNode);
|
||||
}
|
||||
|
||||
protected ArrayList<String> getAllowedDisguises(CommandSender sender, String permissionNode) {
|
||||
ArrayList<String> names = new ArrayList<String>();
|
||||
ArrayList<String> forbiddenDisguises = new ArrayList<String>();
|
||||
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
|
||||
String perm = permission.getPermission().toLowerCase();
|
||||
if (perm.startsWith(permissionNode)) {
|
||||
perm = perm.substring(permissionNode.length());
|
||||
for (DisguiseType type : DisguiseType.values()) {
|
||||
if (type.getEntityType() == null) {
|
||||
continue;
|
||||
}
|
||||
String name = type.name().toLowerCase();
|
||||
if (perm.split("\\.")[0].equals("*") && permission.getValue()) {
|
||||
if (!names.contains(name))
|
||||
names.add(name);
|
||||
} else if (perm.split("\\.")[0].equals(name)) {
|
||||
if (permission.getValue()) {
|
||||
if (!names.contains(name))
|
||||
names.add(name);
|
||||
} else {
|
||||
forbiddenDisguises.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// This does the disguises for OP's.
|
||||
for (DisguiseType type : DisguiseType.values()) {
|
||||
if (type.getEntityType() == null) {
|
||||
continue;
|
||||
}
|
||||
if (!names.contains(type.name().toLowerCase())) {
|
||||
if (sender.hasPermission(permissionNode + "*")
|
||||
|| sender.hasPermission(permissionNode + type.name().toLowerCase())) {
|
||||
names.add(type.name().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
names.removeAll(forbiddenDisguises);
|
||||
Collections.sort(names, String.CASE_INSENSITIVE_ORDER);
|
||||
return names;
|
||||
}
|
||||
|
||||
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 null if they have all perms. Else they can only use the options in the returned
|
||||
*/
|
||||
protected HashSet<HashSet<String>> getPermissions(CommandSender sender, String disguiseType) {
|
||||
HashSet<HashSet<String>> perms = new HashSet<HashSet<String>>();
|
||||
String permNode = "libsdisguises." + getClass().getSimpleName().replace("Command", "").toLowerCase() + ".";
|
||||
for (PermissionAttachmentInfo permission : sender.getEffectivePermissions()) {
|
||||
if (permission.getValue()) {
|
||||
String s = permission.getPermission().toLowerCase();
|
||||
if (s.startsWith(permNode + disguiseType) || s.startsWith(permNode + "*")) {
|
||||
if (s.startsWith(permNode + disguiseType))
|
||||
s = s.substring((permNode + disguiseType).length());
|
||||
else if (s.startsWith(permNode + "*")) {
|
||||
s = s.substring((permNode + "*").length());
|
||||
if (s.length() == 0)
|
||||
continue;
|
||||
}
|
||||
if (s.length() == 0)
|
||||
return new HashSet<HashSet<String>>();
|
||||
HashSet<String> p = new HashSet<String>();
|
||||
for (String str : s.split("\\.")) {
|
||||
if (str.equals("baby"))
|
||||
str = "setbaby";
|
||||
p.add(str);
|
||||
}
|
||||
perms.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return perms;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) throws Exception {
|
||||
ArrayList<String> allowedDisguises = getAllowedDisguises(sender);
|
||||
if (allowedDisguises.isEmpty()) {
|
||||
throw new Exception(ChatColor.RED + "You are forbidden to use this command.");
|
||||
}
|
||||
if (args.length == 0) {
|
||||
sendCommandUsage(sender);
|
||||
throw new Exception();
|
||||
}
|
||||
DisguiseType disguiseType = null;
|
||||
for (DisguiseType type : DisguiseType.values()) {
|
||||
if (type.getEntityType() == null) {
|
||||
continue;
|
||||
}
|
||||
if (args[0].equalsIgnoreCase(type.name()) || type.name().replace("_", "").equalsIgnoreCase(args[0])) {
|
||||
disguiseType = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (disguiseType == null) {
|
||||
throw new Exception(ChatColor.RED + "Error! The disguise " + ChatColor.GREEN + args[0] + ChatColor.RED
|
||||
+ " doesn't exist!");
|
||||
}
|
||||
if (!allowedDisguises.contains(disguiseType.name().toLowerCase())) {
|
||||
throw new Exception(ChatColor.RED + "You are forbidden to use this disguise!");
|
||||
}
|
||||
HashSet<String> usedOptions = new HashSet<String>();
|
||||
Disguise disguise = null;
|
||||
// How many args to skip due to the disugise being constructed
|
||||
int toSkip = 1;
|
||||
// Time to start constructing the disguise.
|
||||
// We will need to check between all 3 kinds of disguises
|
||||
|
||||
HashSet<HashSet<String>> optionPermissions = this.getPermissions(sender, disguiseType.name().toLowerCase());
|
||||
if (disguiseType.isPlayer()) {// If he is doing a player disguise
|
||||
if (args.length == 1) {
|
||||
// He needs to give the player name
|
||||
throw new Exception(ChatColor.RED + "Error! You need to give a player name!");
|
||||
} else {
|
||||
// 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("true") || args[1].equalsIgnoreCase("false")) {
|
||||
usedOptions.add("setbaby");
|
||||
doCheck(optionPermissions, usedOptions);
|
||||
adult = "false".equalsIgnoreCase(args[1]);
|
||||
sender.sendMessage(ChatColor.RED
|
||||
+ "I notice you are using true/false for constructing a mob disguise! This will soon be removed in favor of the simple 'baby'");
|
||||
toSkip++;
|
||||
} else 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;
|
||||
if (args.length > 1) {
|
||||
// They have defined more arguements!
|
||||
// If the first arg is a number
|
||||
if (isNumeric(args[1])) {
|
||||
miscId = Integer.parseInt(args[1]);
|
||||
toSkip++;
|
||||
// If they also defined a data value
|
||||
if (args.length > 2) {
|
||||
if (isNumeric(args[2])) {
|
||||
miscData = Integer.parseInt(args[2]);
|
||||
toSkip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Construct the disguise
|
||||
disguise = new MiscDisguise(disguiseType, miscId, miscData);
|
||||
}
|
||||
}
|
||||
// Copy strings to their new range
|
||||
String[] newArgs = new String[args.length - toSkip];
|
||||
for (int i = toSkip; i < args.length; i++) {
|
||||
newArgs[i - toSkip] = args[i];
|
||||
}
|
||||
args = newArgs;
|
||||
for (int i = 0; i < args.length; i += 2) {
|
||||
String methodName = args[i];
|
||||
if (i + 1 >= args.length) {
|
||||
throw new Exception(ChatColor.RED + "No value was given for the option " + methodName);
|
||||
}
|
||||
String valueString = args[i + 1];
|
||||
Method methodToUse = null;
|
||||
Object value = null;
|
||||
for (Method method : disguise.getWatcher().getClass().getMethods()) {
|
||||
if (!method.getName().startsWith("get") && method.getName().equalsIgnoreCase(methodName)) {
|
||||
methodToUse = method;
|
||||
methodName = method.getName();
|
||||
Class<?>[] types = method.getParameterTypes();
|
||||
if (types.length == 1) {
|
||||
Class param = types[0];
|
||||
// Parse to number
|
||||
if (int.class == param) {
|
||||
if (isNumeric(valueString)) {
|
||||
value = (int) Integer.parseInt(valueString);
|
||||
} else {
|
||||
throw parseToException("number", valueString, methodName);
|
||||
}
|
||||
// Parse to boolean
|
||||
} else if (float.class == param || double.class == param) {
|
||||
if (isDouble(valueString)) {
|
||||
float obj = Float.parseFloat(valueString);
|
||||
if (param == float.class) {
|
||||
value = (float) obj;
|
||||
} else if (param == int.class) {
|
||||
value = (int) obj;
|
||||
} else if (param == double.class) {
|
||||
value = (double) obj;
|
||||
}
|
||||
} else {
|
||||
throw parseToException("number.0", valueString, methodName);
|
||||
}
|
||||
// Parse to boolean
|
||||
} else if (boolean.class == param) {
|
||||
if (!("true".equalsIgnoreCase(valueString) || "false".equalsIgnoreCase(valueString)))
|
||||
throw parseToException("true/false", valueString, methodName);
|
||||
value = (boolean) "true".equalsIgnoreCase(valueString);
|
||||
// Parse to string
|
||||
} else if (param == String.class) {
|
||||
value = ChatColor.translateAlternateColorCodes('&', valueString);
|
||||
// Parse to animal color
|
||||
} else if (param == AnimalColor.class) {
|
||||
try {
|
||||
value = AnimalColor.valueOf(valueString.toUpperCase());
|
||||
} catch (Exception ex) {
|
||||
throw parseToException("animal color", valueString, methodName);
|
||||
}
|
||||
// Parse to itemstack
|
||||
} else if (param == ItemStack.class) {
|
||||
try {
|
||||
value = parseToItemstack(valueString);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception(String.format(ex.getMessage(), methodName));
|
||||
}
|
||||
// Parse to itemstack array
|
||||
} else if (param == ItemStack[].class) {
|
||||
ItemStack[] items = new ItemStack[4];
|
||||
String[] split = valueString.split(",");
|
||||
if (split.length == 4) {
|
||||
for (int a = 0; a < 4; a++) {
|
||||
try {
|
||||
ItemStack item = parseToItemstack(split[a]);
|
||||
items[a] = item;
|
||||
} 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;
|
||||
// Parse to horse color
|
||||
} else if (param.getSimpleName().equals("Color")) {
|
||||
try {
|
||||
|
||||
value = param.getClass().getMethod("valueOf", String.class).invoke(valueString.toUpperCase());
|
||||
} catch (Exception ex) {
|
||||
throw parseToException("horse color", valueString, methodName);
|
||||
}
|
||||
// Parse to horse style
|
||||
} else if (param.getSimpleName().equals("Style")) {
|
||||
try {
|
||||
value = param.getClass().getMethod("valueOf", String.class).invoke(valueString.toUpperCase());
|
||||
} catch (Exception ex) {
|
||||
throw parseToException("horse style", valueString, methodName);
|
||||
}
|
||||
// Parse to villager profession
|
||||
} else if (param.getSimpleName().equals("Profession")) {
|
||||
try {
|
||||
value = param.getClass().getMethod("valueOf", String.class).invoke(valueString.toUpperCase());
|
||||
} catch (Exception ex) {
|
||||
throw parseToException("villager profession", valueString, methodName);
|
||||
}
|
||||
// Parse to ocelot type
|
||||
} else if (param.getSimpleName().equals("Type")) {
|
||||
try {
|
||||
value = param.getClass().getMethod("valueOf", String.class).invoke(valueString.toUpperCase());
|
||||
} catch (Exception ex) {
|
||||
throw parseToException("ocelot type", valueString, methodName);
|
||||
}
|
||||
|
||||
// Parse to potion effect
|
||||
} else if (param == PotionEffectType.class) {
|
||||
try {
|
||||
PotionEffectType potionType = PotionEffectType.getByName(valueString.toUpperCase());
|
||||
if (potionType == null && isNumeric(valueString)) {
|
||||
potionType = PotionEffectType.getById(Integer.parseInt(valueString));
|
||||
}
|
||||
if (potionType == null)
|
||||
throw new Exception();
|
||||
value = potionType;
|
||||
} catch (Exception ex) {
|
||||
throw parseToException("potioneffect type", valueString, methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (methodToUse == null) {
|
||||
throw new Exception(ChatColor.RED + "Cannot find the option " + methodName);
|
||||
}
|
||||
usedOptions.add(methodName.toLowerCase());
|
||||
doCheck(optionPermissions, usedOptions);
|
||||
methodToUse.invoke(disguise.getWatcher(), value);
|
||||
}
|
||||
// Alright. We've constructed our disguise.
|
||||
return disguise;
|
||||
}
|
||||
|
||||
private void doCheck(HashSet<HashSet<String>> optionPermissions, HashSet<String> usedOptions) throws Exception {
|
||||
if (!optionPermissions.isEmpty()) {
|
||||
for (HashSet<String> perms : optionPermissions) {
|
||||
if (!perms.containsAll(usedOptions)) {
|
||||
throw new Exception(ChatColor.RED + "You do not have the permission to use the option "
|
||||
+ usedOptions.toArray(new String[usedOptions.size()])[usedOptions.size() - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Exception parseToException(String expectedValue, String receivedInstead, String methodName) {
|
||||
return new Exception(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);
|
||||
}
|
221
src/me/libraryaddict/disguise/utilities/DisguiseSound.java
Normal file
221
src/me/libraryaddict/disguise/utilities/DisguiseSound.java
Normal file
@@ -0,0 +1,221 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
|
||||
import org.bukkit.Sound;
|
||||
|
||||
/**
|
||||
* Only living disguises go in here!
|
||||
*/
|
||||
public enum DisguiseSound {
|
||||
|
||||
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"),
|
||||
|
||||
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"),
|
||||
|
||||
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),
|
||||
|
||||
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("damage.hit", "step.grass", "damage.hit", null),
|
||||
|
||||
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", "step.grass", "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 getDamageSoundVolume() {
|
||||
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 isCancelled(String soundName) {
|
||||
return cancelSounds.contains(soundName);
|
||||
}
|
||||
|
||||
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 setDamageSoundVolume(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);
|
||||
}
|
||||
}
|
||||
}
|
258
src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java
Normal file
258
src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java
Normal file
@@ -0,0 +1,258 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.comphenix.protocol.Packets;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
|
||||
public class DisguiseUtilities {
|
||||
// Store the entity IDs instead of entitys because then I can disguise entitys even before they exist
|
||||
private static HashMap<Integer, Disguise> disguises = new HashMap<Integer, Disguise>();
|
||||
private static LibsDisguises libsDisguises;
|
||||
// A internal storage of fake entity ID's I can use.
|
||||
// Realistically I could probably use a ID like "4" for everyone, seeing as no one shares the ID
|
||||
private static HashMap<Integer, Integer> selfDisguisesIds = new HashMap<Integer, Integer>();
|
||||
|
||||
public static HashMap<Integer, Disguise> getDisguises() {
|
||||
return disguises;
|
||||
}
|
||||
|
||||
public static HashMap<Integer, Integer> getSelfDisguisesIds() {
|
||||
return selfDisguisesIds;
|
||||
}
|
||||
|
||||
public static void init(LibsDisguises disguises) {
|
||||
libsDisguises = disguises;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Resends
|
||||
* the entity to all the watching players, which is where the magic begins
|
||||
*/
|
||||
public static void refreshTrackers(Entity entity) {
|
||||
try {
|
||||
Object world = ReflectionManager.getWorld(entity.getWorld());
|
||||
Object tracker = world.getClass().getField("tracker").get(world);
|
||||
Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker);
|
||||
Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class)
|
||||
.invoke(trackedEntities, entity.getEntityId());
|
||||
if (entityTrackerEntry != null) {
|
||||
HashSet trackedPlayers = (HashSet) entityTrackerEntry.getClass().getField("trackedPlayers")
|
||||
.get(entityTrackerEntry);
|
||||
Method getBukkitEntity = ReflectionManager.getNmsClass("Entity").getMethod("getBukkitEntity");
|
||||
Method clear = entityTrackerEntry.getClass().getMethod("clear", ReflectionManager.getNmsClass("EntityPlayer"));
|
||||
Method updatePlayer = entityTrackerEntry.getClass().getMethod("updatePlayer",
|
||||
ReflectionManager.getNmsClass("EntityPlayer"));
|
||||
HashSet cloned = (HashSet) trackedPlayers.clone();
|
||||
for (Object player : cloned) {
|
||||
if (entity instanceof Player && !((Player) getBukkitEntity.invoke(player)).canSee((Player) entity))
|
||||
continue;
|
||||
clear.invoke(entityTrackerEntry, player);
|
||||
updatePlayer.invoke(entityTrackerEntry, player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeSelfDisguise(Player player) {
|
||||
if (selfDisguisesIds.containsKey(player.getEntityId())) {
|
||||
// Send a packet to destroy the fake entity
|
||||
PacketContainer packet = new PacketContainer(Packets.Server.DESTROY_ENTITY);
|
||||
packet.getModifier().write(0, new int[] { selfDisguisesIds.get(player.getEntityId()) });
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
// Remove the fake entity ID from the disguise bin
|
||||
selfDisguisesIds.remove(player.getEntityId());
|
||||
// Get the entity tracker
|
||||
try {
|
||||
Object world = ReflectionManager.getWorld(player.getWorld());
|
||||
Object tracker = world.getClass().getField("tracker").get(world);
|
||||
Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker);
|
||||
Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class)
|
||||
.invoke(trackedEntities, player.getEntityId());
|
||||
if (entityTrackerEntry != null) {
|
||||
HashSet trackedPlayers = (HashSet) entityTrackerEntry.getClass().getField("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(Packets.Server.ENTITY_METADATA, player)
|
||||
.createPacket(player));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the self disguise to the player
|
||||
*/
|
||||
public static void sendSelfDisguise(final Player player) {
|
||||
try {
|
||||
Object world = ReflectionManager.getWorld(player.getWorld());
|
||||
Object tracker = world.getClass().getField("tracker").get(world);
|
||||
Object trackedEntities = tracker.getClass().getField("trackedEntities").get(tracker);
|
||||
Object entityTrackerEntry = trackedEntities.getClass().getMethod("get", int.class)
|
||||
.invoke(trackedEntities, player.getEntityId());
|
||||
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..
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
|
||||
public void run() {
|
||||
sendSelfDisguise(player);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Add himself to his own entity tracker
|
||||
((HashSet) entityTrackerEntry.getClass().getField("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(Packets.Server.NAMED_ENTITY_SPAWN, player)
|
||||
.createPacket(player));
|
||||
manager.sendServerPacket(
|
||||
player,
|
||||
manager.createPacketConstructor(Packets.Server.ENTITY_METADATA, player.getEntityId(),
|
||||
WrappedDataWatcher.getEntityWatcher(player), true).createPacket(player.getEntityId(),
|
||||
WrappedDataWatcher.getEntityWatcher(player), 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();
|
||||
manager.sendServerPacket(
|
||||
player,
|
||||
manager.createPacketConstructor(Packets.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()) {
|
||||
manager.sendServerPacket(player,
|
||||
manager.createPacketConstructor(Packets.Server.ATTACH_ENTITY, 0, player, player.getVehicle())
|
||||
.createPacket(0, player, player.getVehicle()));
|
||||
} else if (player.getPassenger() != null && player.getEntityId() > player.getPassenger().getEntityId()) {
|
||||
manager.sendServerPacket(player,
|
||||
manager.createPacketConstructor(Packets.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) {
|
||||
manager.sendServerPacket(player,
|
||||
manager.createPacketConstructor(Packets.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()) {
|
||||
manager.sendServerPacket(
|
||||
player,
|
||||
manager.createPacketConstructor(Packets.Server.ENTITY_LOCATION_ACTION, player, 0, loc.getBlockX(),
|
||||
loc.getBlockY(), loc.getBlockZ()).createPacket(player, 0, loc.getBlockX(), loc.getBlockY(),
|
||||
loc.getBlockZ()));
|
||||
}
|
||||
// TODO Fix this cos it doesn't move the disguise?
|
||||
byte yaw = (byte) (loc.getYaw() * 256.0F / 360.0F);
|
||||
byte pitch = (byte) (loc.getPitch() * 256.0F / 360.0F);
|
||||
manager.sendServerPacket(
|
||||
player,
|
||||
manager.createPacketConstructor(Packets.Server.ENTITY_LOOK, player.getEntityId(), yaw, pitch).createPacket(
|
||||
player.getEntityId(), yaw, pitch));
|
||||
|
||||
// Resend any active potion effects
|
||||
Iterator iterator = player.getActivePotionEffects().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
PotionEffect potionEffect = (PotionEffect) iterator.next();
|
||||
manager.sendServerPacket(player,
|
||||
manager.createPacketConstructor(Packets.Server.MOB_EFFECT, player.getEntityId(), potionEffect)
|
||||
.createPacket(player.getEntityId(), potionEffect));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup it so he can see himself when disguised
|
||||
*/
|
||||
public static void setupFakeDisguise(final Disguise disguise) {
|
||||
// If the disguises entity is null, or the disguised entity isn't a player return
|
||||
if (disguise.getEntity() == null || !(disguise.getEntity() instanceof Player) || !disguises.containsValue(disguise))
|
||||
return;
|
||||
Player player = (Player) disguise.getEntity();
|
||||
// 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;
|
||||
try {
|
||||
// Grab the entity ID the fake disguise will use
|
||||
Field field = ReflectionManager.getNmsClass("Entity").getDeclaredField("entityCount");
|
||||
field.setAccessible(true);
|
||||
int id = field.getInt(null);
|
||||
// Set the entitycount plus one so we don't have the id being reused
|
||||
field.set(null, id + 1);
|
||||
selfDisguisesIds.put(player.getEntityId(), id);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
sendSelfDisguise(player);
|
||||
if (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf()) {
|
||||
if (PacketsManager.isInventoryListenerEnabled()) {
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
110
src/me/libraryaddict/disguise/utilities/DisguiseValues.java
Normal file
110
src/me/libraryaddict/disguise/utilities/DisguiseValues.java
Normal file
@@ -0,0 +1,110 @@
|
||||
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 Class getNmsEntityClass(DisguiseType type) {
|
||||
return getDisguiseValues(type).getNmsEntityClass();
|
||||
}
|
||||
|
||||
public static HashMap<Integer, Object> getMetaValues(DisguiseType type) {
|
||||
return getDisguiseValues(type).getMetaValues();
|
||||
}
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
private Class nmsEntityClass;
|
||||
private int enumEntitySize;
|
||||
private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
|
||||
|
||||
public DisguiseValues(DisguiseType type, Class classType, int entitySize) {
|
||||
values.put(type, this);
|
||||
enumEntitySize = entitySize;
|
||||
nmsEntityClass = classType;
|
||||
}
|
||||
|
||||
public Class getNmsEntityClass() {
|
||||
return nmsEntityClass;
|
||||
}
|
||||
|
||||
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);
|
||||
case 6:
|
||||
}
|
||||
if (d > 0.0D) {
|
||||
return (int) Math.ceil(paramDouble * 32.0D);
|
||||
}
|
||||
|
||||
return (int) Math.floor(paramDouble * 32.0D);
|
||||
}
|
||||
|
||||
public HashMap<Integer, Object> getMetaValues() {
|
||||
return metaValues;
|
||||
}
|
||||
|
||||
public void setMetaValue(int no, Object value) {
|
||||
metaValues.put(no, value);
|
||||
}
|
||||
}
|
1140
src/me/libraryaddict/disguise/utilities/PacketsManager.java
Normal file
1140
src/me/libraryaddict/disguise/utilities/PacketsManager.java
Normal file
File diff suppressed because it is too large
Load Diff
158
src/me/libraryaddict/disguise/utilities/ReflectionManager.java
Normal file
158
src/me/libraryaddict/disguise/utilities/ReflectionManager.java
Normal file
@@ -0,0 +1,158 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ReflectionManager {
|
||||
private static String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3];
|
||||
private static Class itemClass;
|
||||
private static Method soundMethod;
|
||||
static {
|
||||
for (Method method : getNmsClass("EntityLiving").getDeclaredMethods()) {
|
||||
try {
|
||||
if (method.getReturnType() == float.class && Modifier.isProtected(method.getModifiers())
|
||||
&& method.getParameterTypes().length == 0) {
|
||||
Object entity = createEntityInstance("Pig");
|
||||
method.setAccessible(true);
|
||||
method.invoke(entity);
|
||||
Field random = getNmsClass("Entity").getDeclaredField("random");
|
||||
random.setAccessible(true);
|
||||
random.set(entity, null);
|
||||
method.setAccessible(true);
|
||||
try {
|
||||
method.invoke(entity);
|
||||
} catch (Exception ex) {
|
||||
soundMethod = method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
itemClass = getCraftClass("inventory.CraftItemStack");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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 = getNmsClass("MinecraftServer").getMethod("getServer").invoke(null);
|
||||
Object playerinteractmanager = getNmsClass("PlayerInteractManager").getConstructor(getNmsClass("World"))
|
||||
.newInstance(world);
|
||||
entityObject = entityClass.getConstructor(getNmsClass("MinecraftServer"), getNmsClass("World"), String.class,
|
||||
playerinteractmanager.getClass()).newInstance(minecraftServer, world, "LibsDisguises",
|
||||
playerinteractmanager);
|
||||
} else {
|
||||
entityObject = entityClass.getConstructor(getNmsClass("World")).newInstance(world);
|
||||
}
|
||||
return entityObject;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getBukkitItem(Object nmsItem) {
|
||||
try {
|
||||
return (ItemStack) itemClass.getMethod("asBukkitCopy", getNmsClass("ItemStack")).invoke(null, nmsItem);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class getCraftClass(String className) {
|
||||
try {
|
||||
return Class.forName("org.bukkit.craftbukkit." + bukkitVersion + "." + className);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getCraftSound(Sound sound) {
|
||||
try {
|
||||
Class c = getCraftClass("CraftSound");
|
||||
return (String) c.getMethod("getSound", Sound.class).invoke(null, sound);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getEnumArt(Art art) {
|
||||
try {
|
||||
Class craftArt = Class.forName("org.bukkit.craftbukkit." + bukkitVersion + ".CraftArt");
|
||||
Object enumArt = 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 Class getNmsClass(String className) {
|
||||
try {
|
||||
return Class.forName("net.minecraft.server." + bukkitVersion + "." + className);
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getNmsEntity(Entity entity) {
|
||||
try {
|
||||
return getCraftClass("entity.CraftEntity").getMethod("getHandle").invoke(entity);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getNmsItem(ItemStack itemstack) {
|
||||
try {
|
||||
return itemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemstack);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Float getSoundModifier(Object entity) {
|
||||
try {
|
||||
soundMethod.setAccessible(true);
|
||||
return (Float) soundMethod.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;
|
||||
}
|
||||
|
||||
}
|
50
src/me/libraryaddict/disguise/utilities/UpdateChecker.java
Normal file
50
src/me/libraryaddict/disguise/utilities/UpdateChecker.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
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) throws Exception {
|
||||
String version = getVersion("98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4", 81);
|
||||
if (checkHigher(currentVersion, version))
|
||||
latestVersion = version;
|
||||
}
|
||||
|
||||
public String getLatestVersion() {
|
||||
return latestVersion;
|
||||
}
|
||||
|
||||
private String getVersion(String key, int resourceId) {
|
||||
String version = null;
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL("http://www.spigotmc.org/api/general.php").openConnection();
|
||||
con.setDoOutput(true);
|
||||
con.setRequestMethod("POST");
|
||||
con.getOutputStream().write(("key=" + key + "&resource=" + resourceId).getBytes("UTF-8"));
|
||||
version = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public 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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user