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:
libraryaddict
2013-11-23 09:10:20 +13:00
parent a502792df2
commit 0a98e90afc
20 changed files with 53 additions and 54 deletions

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

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

View 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();
}
}
}
}

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

File diff suppressed because it is too large Load Diff

View 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;
}
}

View 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;
}
}