It runs, but it's not at all ready for use. Disguises will now show up yet as packets have not been changed.

This commit is contained in:
NavidK0 2016-03-04 21:02:39 -05:00
parent 40e56621a8
commit 2cf48f7916
22 changed files with 308 additions and 1171 deletions

View File

@ -7,9 +7,9 @@ plugins {
println 'Compiling LibsDisguises via Gradle ver. ' + gradle.gradleVersion
sourceCompatibility = '1.7'
ext.spigotVersion = '1.8.8-R0.1-SNAPSHOT'
ext.spigotVersion = '1.9-R0.1-SNAPSHOT'
ext.disguisesVersion = '9.0.0'
ext.disguisesVersion = '9.0'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
@ -72,6 +72,7 @@ publishing {
}
}
artifactoryPublish.skip = false
artifactory {
@ -93,11 +94,11 @@ artifactory {
file('libs').mkdirs()
ant.get src: 'http://server.o2gaming.com/downloads/spigot.jar', dest: file('libs'), verbose: false, skipexisting: true
ant.get src: 'http://server.o2gaming.com/downloads/spigot-1.9.jar', dest: file('libs'), verbose: false, skipexisting: true
dependencies {
compile "org.spigotmc:spigot-api:$project.ext.spigotVersion"
compile 'com.comphenix.protocol:ProtocolLib:3.6.5'
compile name: 'spigot'
compile 'com.comphenix.protocol:ProtocolLib:3.7-SNAPSHOT'
compile name: 'spigot-1.9'
testCompile group: 'junit', name: 'junit', version: '4.10'
}

View File

@ -105,7 +105,7 @@ public class DisguiseListener implements Listener {
private void chunkMove(Player player, Location newLoc, Location oldLoc) {
try {
for (PacketContainer packet : DisguiseUtilities.getBedChunkPacket(player, newLoc, oldLoc)) {
for (PacketContainer packet : DisguiseUtilities.getBedChunkPacket(newLoc, oldLoc)) {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
}
if (newLoc != null) {

View File

@ -52,6 +52,7 @@ public class LibsDisguises extends JavaPlugin {
@Override
public void onEnable() {
getLogger().info("Discovered MC version: " + ReflectionManager.getBukkitVersion());
saveDefaultConfig();
PacketsManager.init(this);
@ -209,6 +210,7 @@ public class LibsDisguises extends JavaPlugin {
}
Object nmsEntity = ReflectionManager.createEntityInstance(nmsEntityName);
if (nmsEntity == null) {
getLogger().warning("Entity not found! (" + nmsEntityName + ")");
continue;
}
Entity bukkitEntity = ReflectionManager.getBukkitEntity(nmsEntity);
@ -222,10 +224,10 @@ public class LibsDisguises extends JavaPlugin {
}
DisguiseValues disguiseValues = new DisguiseValues(disguiseType, nmsEntity.getClass(), entitySize,
bukkitEntity instanceof Damageable ? ((Damageable) bukkitEntity).getMaxHealth() : 0);
for (WrappedWatchableObject watch : WrappedDataWatcher.getEntityWatcher(bukkitEntity).getWatchableObjects()) {
WrappedDataWatcher watcher = WrappedDataWatcher.getEntityWatcher(bukkitEntity);
for (WrappedWatchableObject watch : watcher.getWatchableObjects()) {
disguiseValues.setMetaValue(watch.getIndex(), watch.getValue());
// Uncomment when I need to find the new datawatcher values for a class..
// System.out.print("Disguise: " + disguiseType + ", ID: " + watch.getIndex() + ", Class: "
// + (watch.getValue() == null ? "null" : watch.getValue().getClass()) + ", Value: " + watch.getValue());
}
@ -252,15 +254,9 @@ public class LibsDisguises extends JavaPlugin {
+ "!");
System.out.print("[LibsDisguises] Before reporting this error, "
+ "please make sure you are using the latest version of LibsDisguises and ProtocolLib.");
if (ReflectionManager.isForge()) {
System.out
.print("[LibsDisguises] Development builds are available at (ProtocolLib) "
+ "http://assets.comphenix.net/job/ProtocolLib%20-%20Cauldron/ and (LibsDisguises) http://ci.md-5.net/job/LibsDisguises/");
} else {
System.out
.print("[LibsDisguises] Development builds are available at (ProtocolLib) "
+ "http://assets.comphenix.net/job/ProtocolLib/ and (LibsDisguises) http://ci.md-5.net/job/LibsDisguises/");
}
System.out
.print("[LibsDisguises] Development builds are available at (ProtocolLib) "
+ "http://ci.dmulloy2.net/job/ProtocolLib/ and (LibsDisguises) http://server.o2gaming.com:8080/job/LibsDisguises%201.9+/");
ex.printStackTrace(System.out);
}
@ -282,6 +278,7 @@ public class LibsDisguises extends JavaPlugin {
/**
* External APIs shouldn't actually need this instance.
* DisguiseAPI should be enough to handle most cases.
*
* @return The instance of this plugin
*/
public static LibsDisguises getInstance() {

View File

@ -3,7 +3,6 @@ package me.libraryaddict.disguise.commands;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.utilities.BaseDisguiseCommand;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;

View File

@ -5,7 +5,6 @@ import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.utilities.BaseDisguiseCommand;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;

View File

@ -4,7 +4,6 @@ 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.utilities.BaseDisguiseCommand;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;

View File

@ -1,18 +1,10 @@
package me.libraryaddict.disguise.commands;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import me.libraryaddict.disguise.disguisetypes.AnimalColor;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.RabbitType;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.utilities.BaseDisguiseCommand;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.block.BlockFace;
@ -21,6 +13,12 @@ import org.bukkit.command.CommandSender;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
public class DisguiseHelpCommand extends BaseDisguiseCommand {
private class EnumHelp {

View File

@ -5,7 +5,6 @@ import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.utilities.BaseDisguiseCommand;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;

View File

@ -5,7 +5,6 @@ import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.utilities.BaseDisguiseCommand;
import me.libraryaddict.disguise.utilities.ClassGetter;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;

View File

@ -1,6 +1,6 @@
package me.libraryaddict.disguise.disguisetypes;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
@ -142,7 +142,8 @@ public abstract class Disguise {
case WITHER_SKULL:
velocitySpeed = 0.000001D;
break;
case ARROW:
case TIPPED_ARROW:
case SPECTRAL_ARROW:
case BOAT:
case ENDER_CRYSTAL:
case ENDER_DRAGON:
@ -246,16 +247,12 @@ public abstract class Disguise {
if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) {
PacketContainer lookPacket = null;
if (getType() == DisguiseType.WITHER_SKULL && DisguiseConfig.isWitherSkullPacketsEnabled()) {
lookPacket = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
lookPacket = new PacketContainer(Server.ENTITY_LOOK);
StructureModifier<Object> mods = lookPacket.getModifier();
lookPacket.getIntegers().write(0, getEntity().getEntityId());
Location loc = getEntity().getLocation();
mods.write(
4,
PacketsManager.getYaw(getType(), getEntity().getType(),
(byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
mods.write(5, PacketsManager.getPitch(getType(), DisguiseType.getType(getEntity().getType()),
(byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
mods.write(4, PacketsManager.getYaw(getType(), getEntity().getType(), (byte) Math.floor(loc.getYaw() * 256.0F / 360.0F)));
mods.write(5, PacketsManager.getPitch(getType(), DisguiseType.getType(getEntity().getType()), (byte) Math.floor(loc.getPitch() * 256.0F / 360.0F)));
if (isSelfDisguiseVisible() && getEntity() instanceof Player) {
PacketContainer selfLookPacket = lookPacket.shallowClone();
selfLookPacket.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
@ -268,7 +265,7 @@ public abstract class Disguise {
}
}
try {
PacketContainer velocityPacket = new PacketContainer(PacketType.Play.Server.ENTITY_VELOCITY);
PacketContainer velocityPacket = new PacketContainer(Server.ENTITY_VELOCITY);
StructureModifier<Integer> mods = velocityPacket.getIntegers();
mods.write(1, (int) (vector.getX() * 8000));
mods.write(3, (int) (vector.getZ() * 8000));
@ -296,7 +293,7 @@ public abstract class Disguise {
// players.
}
if (getType() == DisguiseType.EXPERIENCE_ORB) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
PacketContainer packet = new PacketContainer(Server.REL_ENTITY_MOVE);
packet.getIntegers().write(0, getEntity().getEntityId());
try {
for (Player player : DisguiseUtilities.getPerverts(disguise)) {

View File

@ -12,47 +12,46 @@ import java.lang.reflect.Method;
public enum DisguiseType {
AREA_EFFECT_CLOUD, //Disguising as this would be something else.
ARMOR_STAND(78),
ARROW(60),
AREA_EFFECT_CLOUD,
ARMOR_STAND,
BAT,
BLAZE,
BOAT(1),
BOAT,
CAVE_SPIDER,
CHICKEN,
COW,
CREEPER,
DONKEY,
DRAGON_FIREBALL(26),
DRAGON_FIREBALL,
DROPPED_ITEM(-1, 1),
EGG,
ELDER_GUARDIAN,
ENDER_CRYSTAL(51),
ENDER_CRYSTAL,
ENDER_DRAGON,
ENDER_PEARL(65),
ENDER_SIGNAL(72),
ENDER_PEARL,
ENDER_SIGNAL(15),
ENDERMAN,
ENDERMITE,
EXPERIENCE_ORB,
FALLING_BLOCK(70, 1),
FIREBALL(63, 0),
FIREWORK(76),
FALLING_BLOCK(12, 1),
FIREBALL(26, 0),
FIREWORK(22),
FISHING_HOOK,
GHAST,
GIANT,
GUARDIAN,
HORSE,
IRON_GOLEM,
ITEM_FRAME(71),
LEASH_HITCH(77),
ITEM_FRAME(18),
LEASH_HITCH(8),
MAGMA_CUBE,
MINECART(10, 0),
MINECART_CHEST(10, 1),
MINECART_COMMAND(10, 6),
MINECART_FURNACE(10, 2),
MINECART_HOPPER(10, 5),
MINECART_MOB_SPAWNER(10, 4),
MINECART_TNT(10, 3),
MINECART,
MINECART_CHEST,
MINECART_COMMAND,
MINECART_FURNACE,
MINECART_HOPPER,
MINECART_MOB_SPAWNER,
MINECART_TNT,
MULE,
MUSHROOM_COW,
OCELOT,
@ -60,7 +59,7 @@ public enum DisguiseType {
PIG,
PIG_ZOMBIE,
PLAYER,
PRIMED_TNT(50),
PRIMED_TNT(20),
RABBIT,
SHEEP,
SHULKER,
@ -69,21 +68,21 @@ public enum DisguiseType {
SKELETON,
SKELETON_HORSE,
SLIME,
SMALL_FIREBALL(64, 0),
SNOWBALL(61),
SMALL_FIREBALL(13, 0),
SNOWBALL(11),
SNOWMAN,
SPECTRAL_ARROW(24),
SPIDER,
SPLASH_POTION,
SQUID,
TIPPED_ARROW(23),
THROWN_EXP_BOTTLE(75),
THROWN_EXP_BOTTLE(17),
UNDEAD_HORSE,
VILLAGER,
WITCH,
WITHER,
WITHER_SKELETON,
WITHER_SKULL(66),
WITHER_SKULL(19),
WOLF,
ZOMBIE,
ZOMBIE_VILLAGER,

View File

@ -1,6 +1,6 @@
package me.libraryaddict.disguise.disguisetypes;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
@ -85,37 +85,39 @@ public class FlagWatcher {
HashSet<Integer> sentValues = new HashSet<>();
boolean sendAllCustom = false;
for (WrappedWatchableObject watch : list) {
int dataType = watch.getIndex();
sentValues.add(dataType);
int id = watch.getIndex();
sentValues.add(id);
// Its sending the air metadata. This is the least commonly sent metadata which all entitys still share.
// I send my custom values if I see this!
if (dataType == 1) {
if (id == 1) {
sendAllCustom = true;
}
Object value = null;
if (entityValues.containsKey(dataType)) {
if (entityValues.get(dataType) == null) {
if (entityValues.containsKey(id)) {
if (entityValues.get(id) == null) {
continue;
}
value = entityValues.get(dataType);
} else if (backupEntityValues.containsKey(dataType)) {
if (backupEntityValues.get(dataType) == null) {
value = entityValues.get(id);
} else if (backupEntityValues.containsKey(id)) {
if (backupEntityValues.get(id) == null) {
continue;
}
value = backupEntityValues.get(dataType);
value = backupEntityValues.get(id);
}
if (value != null) {
if (isEntityAnimationsAdded() && dataType == 0) {
if (isEntityAnimationsAdded() && id == 0) {
value = this.addEntityAnimations((byte) value, (byte) watch.getValue());
}
boolean isDirty = watch.getDirtyState();
watch = new WrappedWatchableObject(dataType, value);
watch = new WrappedWatchableObject(id);
watch.setValue(value);
if (!isDirty) {
watch.setDirtyState(false);
}
} else {
boolean isDirty = watch.getDirtyState();
watch = new WrappedWatchableObject(dataType, watch.getValue());
watch = new WrappedWatchableObject(id);
watch.setValue(watch.getValue());
if (!isDirty) {
watch.setDirtyState(false);
}
@ -132,7 +134,8 @@ public class FlagWatcher {
if (obj == null) {
continue;
}
WrappedWatchableObject watch = new WrappedWatchableObject(value, obj);
WrappedWatchableObject watch = new WrappedWatchableObject(value);
watch.setValue(obj);
newList.add(watch);
}
}
@ -243,9 +246,11 @@ public class FlagWatcher {
for (int i = 0; i <= 31; i++) {
WrappedWatchableObject watchable = null;
if (this.entityValues.containsKey(i) && this.entityValues.get(i) != null) {
watchable = new WrappedWatchableObject(i, entityValues.get(i));
watchable = new WrappedWatchableObject(i);
watchable.setValue(entityValues.get(i));
} else if (this.backupEntityValues.containsKey(i) && this.backupEntityValues.get(i) != null) {
watchable = new WrappedWatchableObject(i, backupEntityValues.get(i));
watchable = new WrappedWatchableObject(i);
watchable.setValue(backupEntityValues.get(i));
}
if (watchable != null) {
watchableObjects.add(watchable);
@ -266,10 +271,12 @@ public class FlagWatcher {
if (isEntityAnimationsAdded() && DisguiseConfig.isMetadataPacketsEnabled() && data == 0) {
value = addEntityAnimations((byte) value, WrappedDataWatcher.getEntityWatcher(disguise.getEntity()).getByte(0));
}
list.add(new WrappedWatchableObject(data, value));
WrappedWatchableObject watch = new WrappedWatchableObject(data);
watch.setValue(value);
list.add(watch);
}
if (!list.isEmpty()) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
PacketContainer packet = new PacketContainer(Server.ENTITY_METADATA);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, getDisguise().getEntity().getEntityId());
packet.getWatchableCollectionModifier().write(0, list);
@ -361,7 +368,7 @@ public class FlagWatcher {
if (slot > 4) {
slot = 0;
}
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
PacketContainer packet = new PacketContainer(Server.ENTITY_EQUIPMENT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, getDisguise().getEntity().getEntityId());
mods.write(1, slot);
@ -395,8 +402,8 @@ public class FlagWatcher {
sendData(0);
}
protected void setValue(int no, Object value) {
entityValues.put(no, value);
protected void setValue(int id, Object value) {
entityValues.put(id, value);
if (!DisguiseConfig.isMetadataPacketsEnabled()) {
this.rebuildWatchableObjects();
}

View File

@ -1,18 +1,17 @@
package me.libraryaddict.disguise.disguisetypes;
import java.security.InvalidParameterException;
import me.libraryaddict.disguise.disguisetypes.watchers.DroppedItemWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PaintingWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.SplashPotionWatcher;
import org.bukkit.Art;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.security.InvalidParameterException;
public class MiscDisguise extends TargetedDisguise {
private int id = -1, data = 0;
@ -70,7 +69,8 @@ public class MiscDisguise extends TargetedDisguise {
}
break;
case FISHING_HOOK: // Entity ID of whoever is holding fishing rod
case ARROW: // Entity ID of shooter. Used for "Is he on this scoreboard team and do I render it moving through his body?"
case TIPPED_ARROW: // Entity ID of shooter. Used for "Is he on this scoreboard team and do I render it moving through his body?"
case SPECTRAL_ARROW:
case SMALL_FIREBALL: // Unknown. Uses entity id of shooter. 0 if no shooter
case FIREBALL: // Unknown. Uses entity id of shooter. 0 if no shooter
case WITHER_SKULL: // Unknown. Uses entity id of shooter. 0 if no shooter

View File

@ -1,6 +1,6 @@
package me.libraryaddict.disguise.disguisetypes.watchers;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedAttribute;
@ -17,28 +17,23 @@ import org.bukkit.potion.PotionEffectType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class LivingWatcher extends FlagWatcher {
static Object[] list;
static Method potionNo;
static Map<Integer, Object> list = new HashMap<>();
static Method getId;
static {
try {
list = (Object[]) ReflectionManager.getNmsField("MobEffectList", "byId").get(null);
for (Object obj : list) {
if (obj != null) {
for (Method field : obj.getClass().getMethods()) {
if (field.getReturnType() == int.class) {
if ((Integer) field.invoke(obj) > 10000) {
potionNo = field;
break;
}
}
}
}
getId = ReflectionManager.getNmsMethod("MobEffectList", "getId", ReflectionManager.getNmsClass("MobEffectList"));
Object REGISTRY = ReflectionManager.getNmsField("MobEffectList", "REGISTRY").get(null);
for (Object next: ((Iterable)REGISTRY)) {
int id = (int) getId.invoke(null, next);
list.put(id, next);
}
} catch (Exception ex) {
ex.printStackTrace(System.out);
@ -94,7 +89,7 @@ public class LivingWatcher extends FlagWatcher {
float f4 = 0.0F;
try {
for (int localMobEffect : potionEffects) {
int n = (Integer) potionNo.invoke(list[localMobEffect]);
int n = (Integer) getId.invoke(list.get(localMobEffect));
f1 += (n >> 16 & 0xFF) / 255.0F;
f2 += (n >> 8 & 0xFF) / 255.0F;
f3 += (n & 0xFF) / 255.0F;
@ -145,7 +140,7 @@ public class LivingWatcher extends FlagWatcher {
this.maxHealth = newHealth;
this.maxHealthSet = true;
if (DisguiseAPI.isDisguiseInUse(getDisguise()) && getDisguise().getWatcher() == this) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
PacketContainer packet = new PacketContainer(Server.UPDATE_ATTRIBUTES);
List<WrappedAttribute> attributes = new ArrayList<>();
Builder builder;
builder = WrappedAttribute.newBuilder();

View File

@ -1,6 +1,6 @@
package me.libraryaddict.disguise.disguisetypes.watchers;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
@ -109,7 +109,7 @@ public class PlayerWatcher extends LivingWatcher {
}
}
} else {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ANIMATION);
PacketContainer packet = new PacketContainer(Server.ANIMATION);
StructureModifier<Integer> mods = packet.getIntegers();
mods.write(0, getDisguise().getEntity().getEntityId());
mods.write(1, 3);

View File

@ -1,750 +0,0 @@
package me.libraryaddict.disguise.utilities;
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 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;
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;
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<>();
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 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<>();
}
}
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(System.out);
}
}
return methods;
}
/**
* Get perms for the node. Returns a hashmap of allowed disguisetypes and their options
*
* @param sender
* @param permissionNode
* @return
*/
protected HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> getPermissions(CommandSender sender, String permissionNode) {
HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> singleDisguises = new HashMap<>();
HashMap<DisguiseType, HashMap<ArrayList<String>, Boolean>> rangeDisguises = new HashMap<>();
HashMap<String, Boolean> perms = new HashMap<>();
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<>();
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<>();
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<>();
for (DisguiseType type : DisguiseType.values()) {
HashMap<ArrayList<String>, Boolean> temp = new HashMap<>();
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<>();
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<>();
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.
*
* @param sender
* @param args
* @param map
* @return
* @throws me.libraryaddict.disguise.utilities.BaseDisguiseCommand.DisguiseParseException
* @throws java.lang.IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*/
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<>();
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.isUnknown()) {
throw new DisguiseParseException(ChatColor.RED + "Error! You cannot disguise as " + ChatColor.GREEN + "Unknown!");
}
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!");
}
args[1] = args[1].replace("\\_", " ");
// 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 = 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 = 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(System.out);
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

@ -2,6 +2,7 @@ package me.libraryaddict.disguise.utilities;
import org.bukkit.Sound;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
@ -45,6 +46,9 @@ public enum DisguiseSound {
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"),
SHULKER("entity.shulker.hurt", null, "entity.shulker.death", "entity.shulker.ambient", "entity.shulker.open",
"entity.shulker.hurt_closed", "entity.shulker.close", "entity.shulker.teleport", "entity.shulker_bullet.hit",
"entity.shulker_bullet.hurt"),
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",
@ -71,7 +75,6 @@ public enum DisguiseSound {
"mob.zombie.woodbreak", "mob.zombie.metal", "mob.zombie.wood");
public enum SoundType {
CANCEL, DEATH, HURT, IDLE, STEP
}
@ -121,6 +124,24 @@ public enum DisguiseSound {
}
}
/**
* Necessary for 1.9
* @return
*/
public static String convertSoundEffectToString(Object soundEffect) {
try {
Field f_getMinecraftKey = ReflectionManager.getNmsField("SoundEffect", "b");
f_getMinecraftKey.setAccessible(true);
Object minecraftKey = f_getMinecraftKey.get(soundEffect);
Field f_getValue = ReflectionManager.getNmsField("MinecraftKey", "a");
String sound = (String) f_getValue.get(soundEffect); //Our prize!
return sound;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public float getDamageAndIdleSoundVolume() {
return damageSoundVolume;
}
@ -140,6 +161,7 @@ public enum DisguiseSound {
* Used to check if this sound name is owned by this disguise sound.
*/
public SoundType getType(String sound, boolean ignoreDamage) {
if (sound == null) return SoundType.CANCEL;
if (isCancelSound(sound)) {
return SoundType.CANCEL;
}

View File

@ -1,6 +1,6 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketContainer;
@ -39,7 +39,6 @@ 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;
@ -253,7 +252,7 @@ public class DisguiseUtilities {
Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers").get(entityTrackerEntry);
// If the tracker exists. Remove himself from his tracker
trackedPlayers = new HashSet(trackedPlayers); //Copy before iterating to prevent ConcurrentModificationException
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
PacketContainer destroyPacket = new PacketContainer(Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, new int[]{disguise.getEntity().getEntityId()});
for (Object p : trackedPlayers) {
Player player = (Player) ReflectionManager.getBukkitEntity(p);
@ -300,7 +299,7 @@ public class DisguiseUtilities {
return addedByPlugins;
}
public static PacketContainer[] getBedChunkPacket(Player player, Location newLoc, Location oldLoc) {
public static PacketContainer[] getBedChunkPacket(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}) {
@ -319,19 +318,23 @@ public class DisguiseUtilities {
// Make unload packets
try {
packets[i] = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, bedChunk, true, 0, 40)
.createPacketConstructor(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)
.createPacketConstructor(Server.MAP_CHUNK, bedChunk, true, 0)
.createPacket(bedChunk, true, 0);
}
i++;
// Make load packets
if (oldLoc == null || i > 1) {
//MAP_CHUNK_BULK was replaced in 1.9 with several seperated chunk packets
// packets[i] = ProtocolLibrary.getProtocolManager()
// .createPacketConstructor(Server.MAP_CHUNK_BULK, Arrays.asList(bedChunk))
// .createPacket(Arrays.asList(bedChunk));
packets[i] = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.MAP_CHUNK_BULK, Arrays.asList(bedChunk))
.createPacket(Arrays.asList(bedChunk));
.createPacketConstructor(Server.MAP_CHUNK, bedChunk, true, 0)
.createPacket(bedChunk, true, 0);
i++;
}
}
@ -340,7 +343,7 @@ public class DisguiseUtilities {
public static PacketContainer[] getBedPackets(Player player, Location loc, Location playerLocation, PlayerDisguise disguise) {
Entity entity = disguise.getEntity();
PacketContainer setBed = new PacketContainer(PacketType.Play.Server.BED);
PacketContainer setBed = new PacketContainer(Server.BED);
StructureModifier<Integer> bedInts = setBed.getIntegers();
bedInts.write(0, entity.getEntityId());
PlayerWatcher watcher = disguise.getWatcher();
@ -350,7 +353,7 @@ public class DisguiseUtilities {
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);
PacketContainer teleport = new PacketContainer(Server.ENTITY_TELEPORT);
StructureModifier<Integer> ints = teleport.getIntegers();
ints.write(0, entity.getEntityId());
ints.write(1, (int) Math.floor(loc.getX() * 32));
@ -368,7 +371,7 @@ public class DisguiseUtilities {
}
public static PacketContainer getDestroyPacket(int... ids) {
PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
PacketContainer destroyPacket = new PacketContainer(Server.ENTITY_DESTROY);
destroyPacket.getIntegerArrays().write(0, ids);
return destroyPacket;
}
@ -828,7 +831,7 @@ public class DisguiseUtilities {
player,
ProtocolLibrary
.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(),
.createPacketConstructor(Server.ENTITY_METADATA, player.getEntityId(),
WrappedDataWatcher.getEntityWatcher(player), true)
.createPacket(player.getEntityId(), WrappedDataWatcher.getEntityWatcher(player), true));
} catch (Exception ex) {
@ -874,12 +877,12 @@ public class DisguiseUtilities {
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)
manager.sendServerPacket(player, manager.createPacketConstructor(Server.NAMED_ENTITY_SPAWN, player)
.createPacket(player));
WrappedDataWatcher dataWatcher = WrappedDataWatcher.getEntityWatcher(player);
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, player.getEntityId(), dataWatcher,
manager.createPacketConstructor(Server.ENTITY_METADATA, player.getEntityId(), dataWatcher,
true).createPacket(player.getEntityId(), dataWatcher, true));
boolean isMoving = false;
@ -895,7 +898,7 @@ public class DisguiseUtilities {
Vector velocity = player.getVelocity();
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_VELOCITY, player.getEntityId(),
manager.createPacketConstructor(Server.ENTITY_VELOCITY, player.getEntityId(),
velocity.getX(), velocity.getY(), velocity.getZ()).createPacket(player.getEntityId(),
velocity.getX(), velocity.getY(), velocity.getZ()));
}
@ -903,11 +906,11 @@ public class DisguiseUtilities {
// 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())
manager.createPacketConstructor(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)
manager.createPacketConstructor(Server.ATTACH_ENTITY, 0, player.getPassenger(), player)
.createPacket(0, player.getPassenger(), player));
}
@ -923,7 +926,7 @@ public class DisguiseUtilities {
if (item != null && item.getType() != Material.AIR) {
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EQUIPMENT, player.getEntityId(), i,
manager.createPacketConstructor(Server.ENTITY_EQUIPMENT, player.getEntityId(), i,
item).createPacket(player.getEntityId(), i, item));
}
}
@ -932,7 +935,7 @@ public class DisguiseUtilities {
if (player.isSleeping()) {
sendSelfPacket(
player,
manager.createPacketConstructor(PacketType.Play.Server.BED, player, loc.getBlockX(), loc.getBlockY(),
manager.createPacketConstructor(Server.BED, player, loc.getBlockX(), loc.getBlockY(),
loc.getBlockZ()).createPacket(player, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
}
@ -940,7 +943,7 @@ public class DisguiseUtilities {
for (PotionEffect potionEffect : player.getActivePotionEffects()) {
Object mobEffect = ReflectionManager.createMobEffect(potionEffect);
sendSelfPacket(player,
manager.createPacketConstructor(PacketType.Play.Server.ENTITY_EFFECT, player.getEntityId(), mobEffect)
manager.createPacketConstructor(Server.ENTITY_EFFECT, player.getEntityId(), mobEffect)
.createPacket(player.getEntityId(), mobEffect));
}
} catch (Exception ex) {

View File

@ -1,9 +1,9 @@
package me.libraryaddict.disguise.utilities;
import java.util.HashMap;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import java.util.HashMap;
public class DisguiseValues {
private static HashMap<DisguiseType, DisguiseValues> values = new HashMap<>();
@ -140,7 +140,7 @@ public class DisguiseValues {
this.entitySize = size;
}
public void setMetaValue(int no, Object value) {
metaValues.put(no, value);
public void setMetaValue(int id, Object value) {
metaValues.put(id, value);
}
}

View File

@ -1,6 +1,7 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play.Server;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
@ -138,7 +139,7 @@ public class PacketsManager {
}
}
if (item == null || item.getType() == Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
PacketContainer packet = new PacketContainer(Server.ENTITY_EQUIPMENT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, nmsSlot);
@ -150,7 +151,7 @@ public class PacketsManager {
}
if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) {
if (disguise.getWatcher() instanceof LivingWatcher) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
PacketContainer packet = new PacketContainer(Server.UPDATE_ATTRIBUTES);
List<WrappedAttribute> attributes = new ArrayList<>();
Builder builder = WrappedAttribute.newBuilder().attributeKey("generic.maxHealth");
if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
@ -182,7 +183,7 @@ public class PacketsManager {
if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) {
spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB);
spawnPackets[0] = new PacketContainer(Server.SPAWN_ENTITY_EXPERIENCE_ORB);
StructureModifier<Object> mods = spawnPackets[0].getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, (int) Math.floor(loc.getX() * 32));
@ -191,7 +192,7 @@ public class PacketsManager {
mods.write(4, 1);
} else if (disguise.getType() == DisguiseType.PAINTING) {
spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_PAINTING);
spawnPackets[0] = new PacketContainer(Server.SPAWN_ENTITY_PAINTING);
StructureModifier<Object> mods = spawnPackets[0].getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, ReflectionManager.getBlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
@ -200,7 +201,7 @@ public class PacketsManager {
mods.write(3, ReflectionManager.getEnumArt(Art.values()[id]));
// Make the teleport packet to make it visible..
spawnPackets[1] = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
spawnPackets[1] = new PacketContainer(Server.ENTITY_TELEPORT);
mods = spawnPackets[1].getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, (int) Math.floor(loc.getX() * 32D));
@ -211,7 +212,7 @@ public class PacketsManager {
} else if (disguise.getType().isPlayer()) {
spawnPackets[0] = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
spawnPackets[0] = new PacketContainer(Server.NAMED_ENTITY_SPAWN);
StructureModifier<String> stringMods = spawnPackets[0].getStrings();
WrappedGameProfile gameProfile;
if (stringMods.size() > 0) {
@ -233,19 +234,20 @@ public class PacketsManager {
}
StructureModifier<Integer> intMods = spawnPackets[0].getIntegers();
intMods.write(0, disguisedEntity.getEntityId());
intMods.write(1, (int) Math.floor(loc.getX() * 32));
intMods.write(2, (int) Math.floor(loc.getY() * 32));
intMods.write(3, (int) Math.floor(loc.getZ() * 32));
StructureModifier<Double> doubleMods = spawnPackets[0].getDoubles();
doubleMods.write(0, Math.floor(loc.getX() * 32));
doubleMods.write(1, Math.floor(loc.getY() * 32));
doubleMods.write(2, Math.floor(loc.getZ() * 32));
ItemStack item = null;
if (disguisedEntity instanceof Player && ((Player) disguisedEntity).getItemInHand() != null) {
item = ((Player) disguisedEntity).getItemInHand();
if (disguisedEntity instanceof Player && ((Player) disguisedEntity).getInventory().getItemInMainHand() != null) {
item = ((Player) disguisedEntity).getInventory().getItemInMainHand();
} else if (disguisedEntity instanceof LivingEntity) {
item = ((LivingEntity) disguisedEntity).getEquipment().getItemInHand();
item = ((LivingEntity) disguisedEntity).getEquipment().getItemInMainHand();
}
intMods.write(4, (item == null || item.getType() == Material.AIR ? 0 : item.getTypeId()));
StructureModifier<Byte> byteMods = spawnPackets[0].getBytes();
byteMods.write(0, yaw);
byteMods.write(1, pitch);
byteMods.write(1, yaw);
byteMods.write(0, pitch);
spawnPackets[0].getDataWatcherModifier().write(0,
createDataWatcher(player, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher()));
@ -268,7 +270,7 @@ public class PacketsManager {
}
}
spawnPackets = newPackets.toArray(new PacketContainer[newPackets.size()]);
spawnPackets[0] = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
spawnPackets[0] = new PacketContainer(Server.PLAYER_INFO);
spawnPackets[0].getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0));
List playerList = new ArrayList();
PlayerDisguise playerDisguise = (PlayerDisguise) disguise;
@ -282,7 +284,7 @@ public class PacketsManager {
DisguiseValues values = DisguiseValues.getDisguiseValues(disguise.getType());
Vector vec = disguisedEntity.getVelocity();
spawnPackets[0] = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING);
spawnPackets[0] = new PacketContainer(Server.SPAWN_ENTITY_LIVING);
StructureModifier<Object> mods = spawnPackets[0].getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, disguise.getType().getTypeId());
@ -326,7 +328,7 @@ public class PacketsManager {
data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4;
}
spawnPackets[0] = ProtocolLibrary.getProtocolManager()
.createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, nmsEntity, id, data)
.createPacketConstructor(Server.SPAWN_ENTITY, nmsEntity, id, data)
.createPacket(nmsEntity, id, data);
spawnPackets[0].getModifier().write(2, (int) Math.floor(loc.getY() * 32D));
spawnPackets[0].getModifier().write(7, pitch);
@ -346,7 +348,7 @@ public class PacketsManager {
spawnPackets = Arrays.copyOf(spawnPackets, spawnPackets.length + 1);
}
// Make a packet to turn his head!
spawnPackets[entry] = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
spawnPackets[entry] = new PacketContainer(Server.ENTITY_HEAD_ROTATION);
StructureModifier<Object> mods = spawnPackets[entry].getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, yaw);
@ -419,7 +421,8 @@ public class PacketsManager {
case WITHER_SKULL:
value -= 128;
break;
case ARROW:
case TIPPED_ARROW:
case SPECTRAL_ARROW:
value = (byte) -value;
break;
case PAINTING:
@ -492,7 +495,8 @@ public class PacketsManager {
default:
return yMod + 0.4;
}
case ARROW:
case TIPPED_ARROW:
case SPECTRAL_ARROW:
case BOAT:
case EGG:
case ENDER_PEARL:
@ -523,8 +527,8 @@ public class PacketsManager {
*/
public static void init(LibsDisguises plugin) {
libsDisguises = plugin;
soundsListener = new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, PacketType.Play.Server.NAMED_SOUND_EFFECT,
PacketType.Play.Server.ENTITY_STATUS) {
soundsListener = new PacketAdapter(libsDisguises, ListenerPriority.NORMAL, Server.NAMED_SOUND_EFFECT,
Server.ENTITY_STATUS) {
@Override
public void onPacketSending(PacketEvent event) {
if (event.isCancelled()) {
@ -533,11 +537,11 @@ public class PacketsManager {
event.setPacket(event.getPacket().deepClone());
StructureModifier<Object> mods = event.getPacket().getModifier();
Player observer = event.getPlayer();
if (event.getPacketType() == PacketType.Play.Server.NAMED_SOUND_EFFECT) {
if (event.getPacketType() == Server.NAMED_SOUND_EFFECT) {
if (event.isAsync()) {
return;
}
String soundName = (String) mods.read(0);
Object soundEffect = mods.read(0);
SoundType soundType = null;
Location soundLoc = new Location(observer.getWorld(), ((Integer) mods.read(1)) / 8D,
((Integer) mods.read(2)) / 8D, ((Integer) mods.read(3)) / 8D);
@ -584,7 +588,7 @@ public class PacketsManager {
} catch (Exception ex) {
ex.printStackTrace();
}
soundType = entitySound.getType(soundName, !hasInvun);
soundType = entitySound.getType(DisguiseSound.convertSoundEffectToString(soundEffect), !hasInvun);
}
if (soundType != null) {
disguise = entityDisguise;
@ -677,7 +681,7 @@ public class PacketsManager {
}
}
}
} else if (event.getPacketType() == PacketType.Play.Server.ENTITY_STATUS) {
} else if (event.getPacketType() == Server.ENTITY_STATUS) {
if ((byte) mods.read(1) == 2) {
// It made a damage animation
Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0);
@ -716,7 +720,7 @@ public class PacketsManager {
String sound = disSound.getSound(soundType);
if (sound != null) {
Location loc = entity.getLocation();
PacketContainer packet = new PacketContainer(PacketType.Play.Server.NAMED_SOUND_EFFECT);
PacketContainer packet = new PacketContainer(Server.NAMED_SOUND_EFFECT);
mods = packet.getModifier();
mods.write(0, sound);
mods.write(1, (int) (loc.getX() * 8D));
@ -750,13 +754,13 @@ public class PacketsManager {
}
};
viewDisguisesListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGH,
PacketType.Play.Server.NAMED_ENTITY_SPAWN, PacketType.Play.Server.ATTACH_ENTITY,
PacketType.Play.Server.REL_ENTITY_MOVE, PacketType.Play.Server.ENTITY_MOVE_LOOK,
PacketType.Play.Server.ENTITY_LOOK, PacketType.Play.Server.ENTITY_TELEPORT,
PacketType.Play.Server.ENTITY_HEAD_ROTATION, PacketType.Play.Server.ENTITY_METADATA,
PacketType.Play.Server.ENTITY_EQUIPMENT, PacketType.Play.Server.ANIMATION, PacketType.Play.Server.BED,
PacketType.Play.Server.ENTITY_EFFECT, PacketType.Play.Server.ENTITY_VELOCITY,
PacketType.Play.Server.UPDATE_ATTRIBUTES, PacketType.Play.Server.ENTITY_STATUS) {
Server.NAMED_ENTITY_SPAWN, Server.ATTACH_ENTITY,
Server.REL_ENTITY_MOVE, Server.ENTITY_MOVE_LOOK,
Server.ENTITY_LOOK, Server.ENTITY_TELEPORT,
Server.ENTITY_HEAD_ROTATION, Server.ENTITY_METADATA,
Server.ENTITY_EQUIPMENT, Server.ANIMATION, Server.BED,
Server.ENTITY_EFFECT, Server.ENTITY_VELOCITY,
Server.UPDATE_ATTRIBUTES, Server.ENTITY_STATUS) {
@Override
public void onPacketSending(PacketEvent event) {
if (event.isCancelled())
@ -772,7 +776,7 @@ public class PacketsManager {
packets = new PacketContainer[]{event.getPacket()};
}
for (PacketContainer packet : packets) {
if (packet.getType() != PacketType.Play.Server.PLAYER_INFO) {
if (packet.getType() != Server.PLAYER_INFO) {
if (packet.equals(event.getPacket())) {
packet = packet.shallowClone();
}
@ -797,7 +801,7 @@ public class PacketsManager {
}
}, 2);
}
if (event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) {
if (event.getPacketType() == Server.ENTITY_METADATA) {
event.setPacket(event.getPacket().deepClone());
for (WrappedWatchableObject watch : event.getPacket().getWatchableCollectionModifier().read(0)) {
if (watch.getIndex() == 0) {
@ -808,38 +812,40 @@ public class PacketsManager {
watch.setValue(a);
}
}
} else if (event.getPacketType() == PacketType.Play.Server.NAMED_ENTITY_SPAWN) {
} else if (event.getPacketType() == Server.NAMED_ENTITY_SPAWN) {
event.setCancelled(true);
PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
PacketContainer packet = new PacketContainer(Server.ENTITY_METADATA);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, observer.getEntityId());
List<WrappedWatchableObject> watchableList = new ArrayList<>();
byte b = (byte) 1 << 5;
if (observer.isSprinting())
b = (byte) (b | 1 << 3);
watchableList.add(new WrappedWatchableObject(0, b));
WrappedWatchableObject watch = new WrappedWatchableObject(0);
watch.setValue(b);
watchableList.add(watch);
packet.getWatchableCollectionModifier().write(0, watchableList);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else if (event.getPacketType() == PacketType.Play.Server.ANIMATION) {
} else if (event.getPacketType() == Server.ANIMATION) {
if (event.getPacket().getIntegers().read(1) != 2) {
event.setCancelled(true);
}
} else if (event.getPacketType() == PacketType.Play.Server.ATTACH_ENTITY
|| event.getPacketType() == PacketType.Play.Server.REL_ENTITY_MOVE
|| event.getPacketType() == PacketType.Play.Server.ENTITY_MOVE_LOOK
|| event.getPacketType() == PacketType.Play.Server.ENTITY_LOOK
|| event.getPacketType() == PacketType.Play.Server.ENTITY_TELEPORT
|| event.getPacketType() == PacketType.Play.Server.ENTITY_HEAD_ROTATION
|| event.getPacketType() == PacketType.Play.Server.ENTITY_EFFECT
|| event.getPacketType() == PacketType.Play.Server.ENTITY_EQUIPMENT) {
} else if (event.getPacketType() == Server.ATTACH_ENTITY
|| event.getPacketType() == Server.REL_ENTITY_MOVE
|| event.getPacketType() == Server.ENTITY_MOVE_LOOK
|| event.getPacketType() == Server.ENTITY_LOOK
|| event.getPacketType() == Server.ENTITY_TELEPORT
|| event.getPacketType() == Server.ENTITY_HEAD_ROTATION
|| event.getPacketType() == Server.ENTITY_EFFECT
|| event.getPacketType() == Server.ENTITY_EQUIPMENT) {
event.setCancelled(true);
} else if (event.getPacketType() == PacketType.Play.Server.BED) {
} else if (event.getPacketType() == Server.BED) {
ReflectionManager.setAllowSleep(observer);
} else if (event.getPacketType() == PacketType.Play.Server.ENTITY_STATUS) {
} else if (event.getPacketType() == Server.ENTITY_STATUS) {
Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer(), event.getPlayer());
if (disguise.isSelfDisguiseSoundsReplaced() && !disguise.getType().isPlayer()
&& event.getPacket().getBytes().read(0) == 2) {
@ -850,8 +856,8 @@ public class PacketsManager {
}
}
};
inventoryListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGHEST, PacketType.Play.Server.SET_SLOT,
PacketType.Play.Server.WINDOW_ITEMS, PacketType.Play.Client.HELD_ITEM_SLOT,
inventoryListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGHEST, Server.SET_SLOT,
Server.WINDOW_ITEMS, PacketType.Play.Client.HELD_ITEM_SLOT,
PacketType.Play.Client.SET_CREATIVE_SLOT, PacketType.Play.Client.WINDOW_CLICK) {
@Override
public void onPacketReceiving(final PacketEvent event) {
@ -871,7 +877,7 @@ public class PacketsManager {
int armorSlot = Math.abs((slot - 5) - 3);
org.bukkit.inventory.ItemStack item = event.getPlayer().getInventory().getArmorContents()[armorSlot];
if (item != null && item.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
@ -890,7 +896,7 @@ public class PacketsManager {
if (slot + 36 == currentSlot) {
org.bukkit.inventory.ItemStack item = event.getPlayer().getItemInHand();
if (item != null && item.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
@ -916,7 +922,7 @@ public class PacketsManager {
org.bukkit.inventory.ItemStack currentlyHeld = event.getPlayer().getItemInHand();
// If his old weapon isn't air
if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, event.getPlayer().getInventory().getHeldItemSlot() + 36);
@ -931,7 +937,7 @@ public class PacketsManager {
.getItem(event.getPacket().getIntegers().read(0));
// If his new weapon isn't air either!
if (newHeld != null && newHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, event.getPacket().getIntegers().read(0) + 36);
@ -971,7 +977,7 @@ public class PacketsManager {
// If the slot is a armor slot
if (slot >= 5 && slot <= 8) {
if (disguise.isHidingArmorFromSelf()) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
@ -989,7 +995,7 @@ public class PacketsManager {
int currentSlot = event.getPlayer().getInventory().getHeldItemSlot();
// Check if the player is on the same slot as the slot that its setting
if (slot == currentSlot + 36) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
@ -1024,7 +1030,7 @@ public class PacketsManager {
/**
* Done
*/
if (event.getPacketType() == PacketType.Play.Server.SET_SLOT) {
if (event.getPacketType() == Server.SET_SLOT) {
// The raw slot
// nms code has the start of the hotbar being 36.
int slot = event.getPacket().getIntegers().read(1);
@ -1056,7 +1062,7 @@ public class PacketsManager {
}
}
}
} else if (event.getPacketType() == PacketType.Play.Server.WINDOW_ITEMS) {
} else if (event.getPacketType() == Server.WINDOW_ITEMS) {
event.setPacket(event.getPacket().deepClone());
StructureModifier<ItemStack[]> mods = event.getPacket().getItemArrayModifier();
ItemStack[] items = mods.read(0);
@ -1143,45 +1149,45 @@ public class PacketsManager {
List<PacketType> packetsToListen = new ArrayList<>();
// Add spawn packets
{
packetsToListen.add(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_LIVING);
packetsToListen.add(PacketType.Play.Server.SPAWN_ENTITY_PAINTING);
packetsToListen.add(Server.NAMED_ENTITY_SPAWN);
packetsToListen.add(Server.SPAWN_ENTITY_EXPERIENCE_ORB);
packetsToListen.add(Server.SPAWN_ENTITY);
packetsToListen.add(Server.SPAWN_ENTITY_LIVING);
packetsToListen.add(Server.SPAWN_ENTITY_PAINTING);
}
// Add packets that always need to be enabled to ensure safety
{
packetsToListen.add(PacketType.Play.Server.ENTITY_METADATA);
packetsToListen.add(Server.ENTITY_METADATA);
}
if (DisguiseConfig.isCollectPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.COLLECT);
packetsToListen.add(Server.COLLECT);
}
if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) {
packetsToListen.add(PacketType.Play.Server.UPDATE_ATTRIBUTES);
packetsToListen.add(Server.UPDATE_ATTRIBUTES);
}
// The bed packet.
if (DisguiseConfig.isBedPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.BED);
packetsToListen.add(Server.BED);
}
// Add movement packets
if (DisguiseConfig.isMovementPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ENTITY_LOOK);
packetsToListen.add(PacketType.Play.Server.ENTITY_MOVE_LOOK);
packetsToListen.add(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
packetsToListen.add(PacketType.Play.Server.ENTITY_TELEPORT);
packetsToListen.add(PacketType.Play.Server.REL_ENTITY_MOVE);
packetsToListen.add(Server.ENTITY_LOOK);
packetsToListen.add(Server.ENTITY_MOVE_LOOK);
packetsToListen.add(Server.ENTITY_HEAD_ROTATION);
packetsToListen.add(Server.ENTITY_TELEPORT);
packetsToListen.add(Server.REL_ENTITY_MOVE);
}
// Add equipment packet
if (DisguiseConfig.isEquipmentPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ENTITY_EQUIPMENT);
packetsToListen.add(Server.ENTITY_EQUIPMENT);
}
// Add the packet that ensures if they are sleeping or not
if (DisguiseConfig.isAnimationPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ANIMATION);
packetsToListen.add(Server.ANIMATION);
}
// Add the packet that makes sure that entities with armor do not send unpickupable armor on death
if (DisguiseConfig.isEntityStatusPacketsEnabled()) {
packetsToListen.add(PacketType.Play.Server.ENTITY_STATUS);
packetsToListen.add(Server.ENTITY_STATUS);
}
mainListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGH, packetsToListen) {
@Override
@ -1192,7 +1198,7 @@ public class PacketsManager {
// First get the entity, the one sending this packet
StructureModifier<Entity> entityModifer = event.getPacket().getEntityModifier(observer.getWorld());
org.bukkit.entity.Entity entity = entityModifer
.read((PacketType.Play.Server.COLLECT == event.getPacketType() ? 1 : 0));
.read((Server.COLLECT == event.getPacketType() ? 1 : 0));
// If the entity is the same as the sender. Don't disguise!
// Prevents problems and there is no advantage to be gained.
if (entity == observer)
@ -1268,14 +1274,14 @@ public class PacketsManager {
packets = new PacketContainer[]{sentPacket};
// This packet sends attributes
if (sentPacket.getType() == PacketType.Play.Server.UPDATE_ATTRIBUTES) {
if (sentPacket.getType() == Server.UPDATE_ATTRIBUTES) {
if (disguise.isMiscDisguise()) {
packets = new PacketContainer[0];
} else {
List<WrappedAttribute> attributes = new ArrayList<>();
for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) {
if (attribute.getAttributeKey().equals("generic.maxHealth")) {
packets[0] = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
packets[0] = new PacketContainer(Server.UPDATE_ATTRIBUTES);
Builder builder;
if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
builder = WrappedAttribute.newBuilder();
@ -1303,7 +1309,7 @@ public class PacketsManager {
}
// Else if the packet is sending entity metadata
else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_METADATA) {
else if (sentPacket.getType() == Server.ENTITY_METADATA) {
if (DisguiseConfig.isMetadataPacketsEnabled()) {
List<WrappedWatchableObject> watchableObjects = disguise.getWatcher().convert(
packets[0].getWatchableCollectionModifier().read(0));
@ -1318,30 +1324,30 @@ public class PacketsManager {
}
// Else if the packet is spawning..
else if (sentPacket.getType() == PacketType.Play.Server.NAMED_ENTITY_SPAWN
|| sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_LIVING
|| sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB
|| sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY
|| sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_PAINTING) {
else if (sentPacket.getType() == Server.NAMED_ENTITY_SPAWN
|| sentPacket.getType() == Server.SPAWN_ENTITY_LIVING
|| sentPacket.getType() == Server.SPAWN_ENTITY_EXPERIENCE_ORB
|| sentPacket.getType() == Server.SPAWN_ENTITY
|| sentPacket.getType() == Server.SPAWN_ENTITY_PAINTING) {
PacketContainer[][] spawnPackets = constructSpawnPackets(observer, disguise, entity);
packets = spawnPackets[0];
delayedPackets = spawnPackets[1];
}
// Else if the disguise is attempting to send players a forbidden packet
else if (sentPacket.getType() == PacketType.Play.Server.ANIMATION) {
else if (sentPacket.getType() == Server.ANIMATION) {
if (disguise.getType().isMisc()
|| (packets[0].getIntegers().read(1) == 2 && (!disguise.getType()
.isPlayer() || (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise
.getWatcher()).isSleeping())))) {
packets = new PacketContainer[0];
}
} else if (sentPacket.getType() == PacketType.Play.Server.COLLECT) {
} else if (sentPacket.getType() == Server.COLLECT) {
if (disguise.getType().isMisc()) {
packets = new PacketContainer[0];
} else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer()
&& ((PlayerWatcher) disguise.getWatcher()).isSleeping()) {
PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ANIMATION);
PacketContainer newPacket = new PacketContainer(Server.ANIMATION);
StructureModifier<Integer> mods = newPacket.getIntegers();
mods.write(0, disguise.getEntity().getEntityId());
mods.write(1, 3);
@ -1350,12 +1356,12 @@ public class PacketsManager {
}
// Else if the disguise is moving.
else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_MOVE_LOOK
|| sentPacket.getType() == PacketType.Play.Server.ENTITY_LOOK
|| sentPacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT
|| sentPacket.getType() == PacketType.Play.Server.REL_ENTITY_MOVE) {
else if (sentPacket.getType() == Server.ENTITY_MOVE_LOOK
|| sentPacket.getType() == Server.ENTITY_LOOK
|| sentPacket.getType() == Server.ENTITY_TELEPORT
|| sentPacket.getType() == Server.REL_ENTITY_MOVE) {
if (disguise.getType() == DisguiseType.RABBIT
&& (sentPacket.getType() == PacketType.Play.Server.REL_ENTITY_MOVE || sentPacket.getType() == PacketType.Play.Server.ENTITY_MOVE_LOOK)) {
&& (sentPacket.getType() == Server.REL_ENTITY_MOVE || sentPacket.getType() == Server.ENTITY_MOVE_LOOK)) {
if (entity.getMetadata("LibsRabbitHop").isEmpty()
|| System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() < 100
|| System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) {
@ -1366,43 +1372,41 @@ public class PacketsManager {
new FixedMetadataValue(libsDisguises, System.currentTimeMillis()));
}
packets = Arrays.copyOf(packets, packets.length + 1);
packets[1] = new PacketContainer(PacketType.Play.Server.ENTITY_STATUS);
packets[1] = new PacketContainer(Server.ENTITY_STATUS);
packets[1].getIntegers().write(0, entity.getEntityId());
packets[1].getBytes().write(0, (byte) 1);
}
}
if (sentPacket.getType() == PacketType.Play.Server.ENTITY_LOOK
if (sentPacket.getType() == Server.ENTITY_LOOK
&& disguise.getType() == DisguiseType.WITHER_SKULL) {
packets = new PacketContainer[0];
} else if (sentPacket.getType() != PacketType.Play.Server.REL_ENTITY_MOVE) {
} else if (sentPacket.getType() != Server.REL_ENTITY_MOVE) {
packets[0] = sentPacket.shallowClone();
StructureModifier<Byte> bytes = packets[0].getBytes();
boolean tele = sentPacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT;
byte yawValue = bytes.read(tele ? 0 : 3);
bytes.write(tele ? 0 : 3, getYaw(disguise.getType(), entity.getType(), yawValue));
byte pitchValue = bytes.read(tele ? 1 : 4);
bytes.write(tele ? 1 : 4,
getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue));
if (tele && disguise.getType() == DisguiseType.ITEM_FRAME) {
StructureModifier<Integer> ints = packets[0].getIntegers();
byte yawValue = bytes.read(1);
bytes.write(1, getYaw(disguise.getType(), entity.getType(), yawValue));
byte pitchValue = bytes.read(0);
bytes.write(0, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue));
if (sentPacket.getType() == Server.ENTITY_TELEPORT && disguise.getType() == DisguiseType.ITEM_FRAME) {
StructureModifier<Double> doubles = packets[0].getDoubles();
Location loc = entity.getLocation();
int data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4;
double data = (((loc.getYaw() % 360) + 720 + 45) / 90) % 4;
if (data % 2 == 0) {
if (data % 2 == 0) {
ints.write(3, (int) Math.floor((loc.getZ() + (data == 0 ? -1 : 1)) * 32D));
doubles.write(3, loc.getZ());
} else {
ints.write(1, (int) Math.floor((loc.getX() + (data == 3 ? -1 : 1)) * 32D));
doubles.write(1, loc.getZ());
}
}
double y = getYModifier(entity, disguise);
if (y != 0) {
y *= 32;
ints.write(2, ints.read(2) + (int) Math.floor(y));
doubles.write(2, doubles.read(2) + y);
}
}
}
} else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_EQUIPMENT) {
} else if (sentPacket.getType() == Server.ENTITY_EQUIPMENT) {
int slot = (Integer) packets[0].getModifier().read(1) - 1;
if (slot < 0)
slot = 4;
@ -1418,7 +1422,9 @@ public class PacketsManager {
// Convert the datawatcher
List<WrappedWatchableObject> list = new ArrayList<>();
if (DisguiseConfig.isMetadataPacketsEnabled()) {
list.add(new WrappedWatchableObject(0, WrappedDataWatcher.getEntityWatcher(entity).getByte(0)));
WrappedWatchableObject watch = new WrappedWatchableObject(0);
watch.setValue(WrappedDataWatcher.getEntityWatcher(entity).getByte(0));
list.add(watch);
list = disguise.getWatcher().convert(list);
} else {
for (WrappedWatchableObject obj : disguise.getWatcher().getWatchableObjects()) {
@ -1430,7 +1436,7 @@ public class PacketsManager {
}
list = DisguiseUtilities.rebuildForVersion(observer, disguise.getWatcher(), list);
// Construct the packets to return
PacketContainer packetBlock = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);
PacketContainer packetBlock = new PacketContainer(Server.ENTITY_METADATA);
packetBlock.getModifier().write(0, entity.getEntityId());
packetBlock.getWatchableCollectionModifier().write(0, list);
PacketContainer packetUnblock = packetBlock.deepClone();
@ -1445,25 +1451,25 @@ public class PacketsManager {
// it.
}
}
} else if (sentPacket.getType() == PacketType.Play.Server.BED) {
} else if (sentPacket.getType() == Server.BED) {
if (!disguise.getType().isPlayer()) {
packets = new PacketContainer[0];
}
} else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_STATUS) {
} else if (sentPacket.getType() == Server.ENTITY_STATUS) {
if (packets[0].getBytes().read(0) == (byte) 3) {
packets = new PacketContainer[0];
}
} else if (sentPacket.getType() == PacketType.Play.Server.ENTITY_HEAD_ROTATION) {
} else if (sentPacket.getType() == Server.ENTITY_HEAD_ROTATION) {
if (disguise.getType().isPlayer() && entity.getType() != EntityType.PLAYER) {
Location loc = entity.getLocation();
byte pitch = getPitch(disguise.getType(), DisguiseType.getType(entity.getType()),
(byte) (int) (loc.getPitch() * 256.0F / 360.0F));
byte yaw = getYaw(disguise.getType(), entity.getType(), sentPacket.getBytes().read(0));
PacketContainer rotation = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
PacketContainer rotation = new PacketContainer(Server.ENTITY_HEAD_ROTATION);
StructureModifier<Object> mods = rotation.getModifier();
mods.write(0, entity.getEntityId());
mods.write(1, yaw);
PacketContainer look = new PacketContainer(PacketType.Play.Server.ENTITY_LOOK);
PacketContainer look = new PacketContainer(Server.ENTITY_LOOK);
look.getIntegers().write(0, entity.getEntityId());
look.getBytes().write(3, yaw);
look.getBytes().write(4, pitch);

View File

@ -12,19 +12,12 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
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;
public class ReflectionManager {
@ -34,22 +27,7 @@ public class ReflectionManager {
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;
@ -63,94 +41,9 @@ public class ReflectionManager {
* 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<>();
ForgeFieldMappings = new HashMap<>();
ForgeMethodMappings = new HashMap<>();
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<>();
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<>();
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<>();
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 | IOException e) {
e.printStackTrace(System.out);
System.err
.println("Warning: Running on Cauldron server, but couldn't load mappings file. LibsDisguises will likely crash!");
}
}
}
static {
@ -188,19 +81,17 @@ public class ReflectionManager {
switch (entityName) {
case "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"),
Object playerinteractmanager = getNmsClass("PlayerInteractManager").getDeclaredConstructor(getNmsClass("World")).newInstance(world);
WrappedGameProfile gameProfile = getGameProfile(null, "Steve");
entityObject = entityClass.getDeclaredConstructor(getNmsClass("MinecraftServer"), getNmsClass("WorldServer"),
gameProfile.getHandleType(), playerinteractmanager.getClass()).newInstance(minecraftServer, world,
gameProfile.getHandle(), playerinteractmanager);
break;
case "EnderPearl":
entityObject = entityClass.getConstructor(getNmsClass("World"), getNmsClass("EntityLiving"))
.newInstance(world, createEntityInstance("Cow"));
entityObject = entityClass.getDeclaredConstructor(getNmsClass("World"), getNmsClass("EntityLiving")).newInstance(world, createEntityInstance("Cow"));
break;
default:
entityObject = entityClass.getConstructor(getNmsClass("World")).newInstance(world);
entityObject = entityClass.getDeclaredConstructor(getNmsClass("World")).newInstance(world);
break;
}
return entityObject;
@ -212,7 +103,7 @@ public class ReflectionManager {
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)
return getNmsClass("MobEffect").getDeclaredConstructor(int.class, int.class, int.class, boolean.class, boolean.class)
.newInstance(id, duration, amplification, ambient, particles);
} catch (Exception e) {
e.printStackTrace(System.out);
@ -233,7 +124,7 @@ public class ReflectionManager {
Object boundingBox = getNmsMethod("Entity", "getBoundingBox").invoke(getNmsEntity(entity));
double x = 0, y = 0, z = 0;
int stage = 0;
for (Field field : boundingBox.getClass().getFields()) {
for (Field field : boundingBox.getClass().getDeclaredFields()) {
if (field.getType().getSimpleName().equals("double")) {
stage++;
switch (stage) {
@ -318,7 +209,7 @@ public class ReflectionManager {
public static String getEnumArt(Art art) {
try {
Object enumArt = getCraftClass("CraftArt").getMethod("BukkitToNotch", Art.class).invoke(null, art);
for (Field field : enumArt.getClass().getFields()) {
for (Field field : enumArt.getClass().getDeclaredFields()) {
if (field.getType() == String.class) {
return (String) field.get(enumArt);
}
@ -331,7 +222,7 @@ public class ReflectionManager {
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);
return getNmsClass("BlockPosition").getDeclaredConstructor(int.class, int.class, int.class).newInstance(x, y, z);
} catch (Exception ex) {
ex.printStackTrace(System.out);
}
@ -358,9 +249,9 @@ public class ReflectionManager {
public static Object getPlayerInfoData(Object playerInfoPacket, WrappedGameProfile gameProfile) {
try {
Object playerListName = getNmsClass("ChatComponentText").getConstructor(String.class)
Object playerListName = getNmsClass("ChatComponentText").getDeclaredConstructor(String.class)
.newInstance(gameProfile.getName());
return getNmsClass("PacketPlayOutPlayerInfo$PlayerInfoData").getConstructor(getNmsClass("PacketPlayOutPlayerInfo"),
return getNmsClass("PacketPlayOutPlayerInfo$PlayerInfoData").getDeclaredConstructor(getNmsClass("PacketPlayOutPlayerInfo"),
gameProfile.getHandleType(), int.class, getNmsClass("WorldSettings$EnumGamemode"), getNmsClass("IChatBaseComponent"))
.newInstance(playerInfoPacket, gameProfile.getHandle(), 0,
getNmsClass("WorldSettings$EnumGamemode").getEnumConstants()[1], playerListName);
@ -396,18 +287,6 @@ public class ReflectionManager {
}
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) {
@ -418,7 +297,7 @@ public class ReflectionManager {
public static Constructor getNmsConstructor(Class clazz, Class<?>... parameters) {
try {
return clazz.getConstructor(parameters);
return clazz.getDeclaredConstructor(parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace(System.out);
}
@ -439,16 +318,8 @@ public class ReflectionManager {
}
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(System.out);
} catch (NullPointerException ignored) {
}
}
try {
return clazz.getField(fieldName);
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
e.printStackTrace(System.out);
}
@ -461,29 +332,29 @@ public class ReflectionManager {
public static Object getNmsItem(ItemStack itemstack) {
try {
return craftItemClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, itemstack);
return craftItemClass.getDeclaredMethod("asNMSCopy", ItemStack.class).invoke(null, itemstack);
} catch (Exception e) {
e.printStackTrace(System.out);
}
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(System.out);
} catch (NullPointerException ignored) {
}
}
public static Method getCraftMethod(String className, String methodName, Class<?>... parameters) {
return getCraftMethod(getCraftClass(className), methodName, parameters);
}
public static Method getCraftMethod(Class<?> clazz, String methodName, Class<?>... parameters) {
try {
return clazz.getMethod(methodName, parameters);
return clazz.getDeclaredMethod(methodName, parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace(System.out);
}
return null;
}
public static Method getNmsMethod(Class<?> clazz, String methodName, Class<?>... parameters) {
try {
return clazz.getDeclaredMethod(methodName, parameters);
} catch (NoSuchMethodException e) {
e.printStackTrace(System.out);
}
@ -518,11 +389,11 @@ public class ReflectionManager {
public static WrappedGameProfile getSkullBlob(WrappedGameProfile gameProfile) {
try {
Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null);
for (Method method : getNmsClass("MinecraftServer").getMethods()) {
for (Method method : getNmsClass("MinecraftServer").getDeclaredMethods()) {
if (method.getReturnType().getSimpleName().equals("MinecraftSessionService")) {
Object session = method.invoke(minecraftServer);
return WrappedGameProfile.fromHandle(session.getClass()
.getMethod("fillProfileProperties", gameProfile.getHandleType(), boolean.class)
.getDeclaredMethod("fillProfileProperties", gameProfile.getHandleType(), boolean.class)
.invoke(session, gameProfile.getHandle(), true));
}
}
@ -543,7 +414,7 @@ public class ReflectionManager {
public static Object getWorld(World world) {
try {
return getCraftClass("CraftWorld").getMethod("getHandle").invoke(world);
return getCraftClass("CraftWorld").getDeclaredMethod("getHandle").invoke(world);
} catch (Exception e) {
e.printStackTrace(System.out);
}
@ -553,14 +424,14 @@ public class ReflectionManager {
public static WrappedGameProfile grabProfileAddUUID(String playername) {
try {
Object minecraftServer = getNmsMethod("MinecraftServer", "getServer").invoke(null);
for (Method method : getNmsClass("MinecraftServer").getMethods()) {
for (Method method : getNmsClass("MinecraftServer").getDeclaredMethods()) {
if (method.getReturnType().getSimpleName().equals("GameProfileRepository")) {
Object profileRepo = method.invoke(minecraftServer);
Object agent = Class.forName("com.mojang.authlib.Agent").getField("MINECRAFT").get(null);
Object agent = Class.forName("com.mojang.authlib.Agent").getDeclaredField("MINECRAFT").get(null);
LibsProfileLookupCaller callback = new LibsProfileLookupCaller();
profileRepo
.getClass()
.getMethod("findProfilesByNames", String[].class, agent.getClass(),
.getDeclaredMethod("findProfilesByNames", String[].class, agent.getClass(),
Class.forName("com.mojang.authlib.ProfileLookupCallback"))
.invoke(profileRepo, new String[]{playername}, agent, callback);
if (callback.getGameProfile() != null) {
@ -575,10 +446,6 @@ public class ReflectionManager {
return null;
}
public static boolean isForge() {
return isForge;
}
private static String methodSignaturePart(Class<?> param) {
if (param.isArray()) {
return "[" + methodSignaturePart(param.getComponentType());

View File

@ -1,6 +1,6 @@
name: LibsDisguises
main: me.libraryaddict.disguise.LibsDisguises
version: 9.0.0
version: 9.0
author: libraryaddict
authors: [Byteflux, Navid K.]
softdepend: [ProtocolLib]