From 09b4955e2395f26225f05ec5bc72ce0107e1f42e Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 29 May 2013 10:29:36 +1200 Subject: [PATCH] Read description Completely redone how the disguising works. Sends packets through protocollib now. Doesn't hide the players anymore. It changes entity trackers. You can now disguise any entity. Added painting disguise. Added disguisesound which stores sounds for each disguise. Any disguise makes a sound? Its replaced with the proper sound. Added ability to turn off and on the sounds Added ItemFrameWatcher and PlayerWatcher --- .../libraryaddict/disguise/DisguiseAPI.java | 212 ++++++++++++------ .../disguise/DisguiseTypes/Disguise.java | 207 +++++++++++++---- .../disguise/DisguiseTypes/DisguiseSound.java | 149 ++++++++++++ .../disguise/DisguiseTypes/DisguiseType.java | 43 ++-- .../disguise/DisguiseTypes/FlagWatcher.java | 5 +- .../Watchers/ItemFrameWatcher.java | 30 +++ .../DisguiseTypes/Watchers/PlayerWatcher.java | 14 ++ .../libraryaddict/disguise/LibsDisguises.java | 209 +++++++---------- 8 files changed, 601 insertions(+), 268 deletions(-) create mode 100644 src/me/libraryaddict/disguise/DisguiseTypes/DisguiseSound.java create mode 100644 src/me/libraryaddict/disguise/DisguiseTypes/Watchers/ItemFrameWatcher.java create mode 100644 src/me/libraryaddict/disguise/DisguiseTypes/Watchers/PlayerWatcher.java diff --git a/src/me/libraryaddict/disguise/DisguiseAPI.java b/src/me/libraryaddict/disguise/DisguiseAPI.java index 08aa57e4..25aaf952 100644 --- a/src/me/libraryaddict/disguise/DisguiseAPI.java +++ b/src/me/libraryaddict/disguise/DisguiseAPI.java @@ -1,18 +1,100 @@ package me.libraryaddict.disguise; +import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import me.libraryaddict.disguise.DisguiseTypes.Disguise; -import net.minecraft.server.v1_5_R3.*; +import me.libraryaddict.disguise.DisguiseTypes.DisguiseSound; +import me.libraryaddict.disguise.DisguiseTypes.DisguiseSound.SoundType; +import net.minecraft.server.v1_5_R3.Block; +import net.minecraft.server.v1_5_R3.EntityPlayer; +import net.minecraft.server.v1_5_R3.EntityTrackerEntry; +import net.minecraft.server.v1_5_R3.World; +import net.minecraft.server.v1_5_R3.WorldServer; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_5_R3.entity.CraftPlayer; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_5_R3.CraftSound; +import org.bukkit.craftbukkit.v1_5_R3.entity.CraftEntity; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import com.comphenix.protocol.Packets; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ConnectionSide; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import com.comphenix.protocol.reflect.StructureModifier; public class DisguiseAPI { - private static ConcurrentHashMap disguises = new ConcurrentHashMap(); - private static boolean playSounds = true; + private static ConcurrentHashMap disguises = new ConcurrentHashMap(); + private static PacketListener packetListener; + private static boolean soundsEnabled; + private static JavaPlugin plugin; + + protected static void init(JavaPlugin mainPlugin) { + plugin = mainPlugin; + packetListener = new PacketAdapter(plugin, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL, + Packets.Server.NAMED_SOUND_EFFECT) { + @Override + public void onPacketSending(PacketEvent event) { + StructureModifier mods = event.getPacket().getModifier(); + try { + Player observer = event.getPlayer(); + String soundName = (String) 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); + Entity disguisedEntity = null; + for (Entity entity : soundLoc.getChunk().getEntities()) { + if (DisguiseAPI.isDisguised(entity)) { + Location loc = entity.getLocation(); + loc = new Location(observer.getWorld(), ((int) (loc.getX() * 8)) / 8D, ((int) (loc.getY() * 8)) / 8D, + ((int) (loc.getZ() * 8)) / 8D); + if (loc.equals(soundLoc)) { + DisguiseSound disSound = DisguiseSound.getType(entity.getType().name()); + if (disSound != null) { + soundType = disSound.ownsSound(soundName); + if (soundType != null) { + disguisedEntity = entity; + break; + } + } else { + disguisedEntity = entity; + break; + } + } + } + } + if (disguisedEntity != null) { + Sound sound = null; + DisguiseSound dSound = DisguiseSound.getType(DisguiseAPI.getDisguise(disguisedEntity).getType().name()); + if (dSound != null) + sound = dSound.getSound(soundType); + if (sound == null) { + event.setCancelled(true); + } else { + if (sound == Sound.STEP_GRASS) { + World world = ((CraftEntity) disguisedEntity).getHandle().world; + Block b = Block.byId[world.getTypeId(soundLoc.getBlockX(), soundLoc.getBlockY() - 1, + soundLoc.getBlockZ())]; + if (b != null) + mods.write(0, b.stepSound.getStepSound()); + } else { + mods.write(0, CraftSound.getSound(sound)); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + } /** * @param Player @@ -20,93 +102,77 @@ public class DisguiseAPI { * @param Disguise * - The disguise to wear */ - public static void disguiseToAll(Player p, Disguise disguise) { - disguises.put(p.getName(), disguise); - disguise.constructPacket(p); - for (Player player : Bukkit.getOnlinePlayers()) { - if (p.getWorld() != player.getWorld() || !player.canSee(p)) - continue; - player.hidePlayer(p); - player.showPlayer(p); + public static void disguiseToAll(Entity entity, Disguise disguise) { + disguises.put(entity instanceof Player ? ((Player) entity).getName() : entity.getUniqueId(), disguise); + refresh(entity); + } + + private static void refresh(Entity entity) { + EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ((CraftEntity) entity).getHandle().world).tracker.trackedEntities + .get(entity.getEntityId()); + if (entry != null) { + Iterator itel = entry.trackedPlayers.iterator(); + while (itel.hasNext()) { + EntityPlayer player = (EntityPlayer) itel.next(); + entry.clear(player); + entry.updatePlayer(player); + } } - } - - /** - * @param Player - * - The player who is being disguised - * @param Player - * - The player who is watching the disguised - * @param Disguise - * - The disguise he is wearing - */ - public static void disguiseToPlayer(Player disguiser, Player observer, Disguise disguise) { - disguises.put(disguiser.getName(), disguise); - Packet29DestroyEntity destroyPacket = new Packet29DestroyEntity(new int[] { disguiser.getEntityId() }); - Packet spawnPacket = disguise.constructPacket(disguiser); - ((CraftPlayer) observer).getHandle().playerConnection.sendPacket(destroyPacket); - ((CraftPlayer) observer).getHandle().playerConnection.sendPacket(spawnPacket); - + /* + // Get the tracker of the people who can see the hider + EntityTracker hidersTracker = ((WorldServer) hider.world).tracker; + // Get the entity tracker entry for the player + EntityTrackerEntry entry = (EntityTrackerEntry) tracker.trackedEntities.get(observer.id); + if (entry != null) { + entry.clear(getHandle()); + }*/ } /** * @param Disguiser * @return Disguise */ - public static Disguise getDisguise(Player p) { - return getDisguise(p.getName()); - } - - /** - * @param Disguiser - * @return Disguise - */ - public static Disguise getDisguise(String name) { - return disguises.get(name); - } - - /** - * @param Disguiser - * @return Boolean - If the disguiser is disguised - */ - public static boolean isDisguised(Player p) { - return isDisguised(p.getName()); + public static Disguise getDisguise(Object disguiser) { + if (disguiser instanceof Entity) { + if (disguiser instanceof Player) + return disguises.get(((Player) disguiser).getName()); + else + return disguises.get(((Entity) disguiser).getUniqueId()); + } + return disguises.get(disguiser); } /** * @param Disguiser * @return boolean - If the disguiser is disguised */ - public static boolean isDisguised(String name) { - return disguises.containsKey(name); - } - - /** - * Does sounds play when the disguiser is hurt - */ - public static boolean playSounds() { - return playSounds; - } - - /** - * @param Boolean - * - Set if sounds play when the disguiser is hurt - */ - public static void setPlaySounds(boolean sounds) { - playSounds = sounds; + public static boolean isDisguised(Object disguiser) { + if (disguiser instanceof Entity) { + if (disguiser instanceof Player) + return disguises.containsKey(((Player) disguiser).getName()); + else + return disguises.containsKey(((Entity) disguiser).getUniqueId()); + } + return disguises.containsKey(disguiser); } /** * @param Disguiser * - Undisguises him */ - public static void undisguiseToAll(Player p) { - disguises.remove(p.getName()); - for (Player player : Bukkit.getOnlinePlayers()) { - if (p.getWorld() != player.getWorld()) - continue; - player.hidePlayer(p); - player.showPlayer(p); - } + public static void undisguiseToAll(Entity entity) { + disguises.remove(entity instanceof Player ? ((Player) entity).getName() : entity.getUniqueId()); + refresh(entity); } + public static void enableSounds(boolean isSoundsEnabled) { + if (soundsEnabled != isSoundsEnabled) { + soundsEnabled = isSoundsEnabled; + if (soundsEnabled) { + ProtocolLibrary.getProtocolManager().addPacketListener(packetListener); + } else { + ProtocolLibrary.getProtocolManager().removePacketListener(packetListener); + } + } + } } \ No newline at end of file diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java b/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java index 7a775039..c8ac14af 100644 --- a/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java +++ b/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java @@ -1,23 +1,32 @@ package me.libraryaddict.disguise.DisguiseTypes; import java.lang.reflect.Constructor; +import java.util.Random; import me.libraryaddict.disguise.DisguiseTypes.Watchers.AgeableWatcher; import net.minecraft.server.v1_5_R3.Entity; import net.minecraft.server.v1_5_R3.EntityAgeable; -import net.minecraft.server.v1_5_R3.EntityExperienceOrb; -import net.minecraft.server.v1_5_R3.EntityHuman; import net.minecraft.server.v1_5_R3.EntityLiving; +import net.minecraft.server.v1_5_R3.EntityPlayer; import net.minecraft.server.v1_5_R3.EntitySkeleton; -import net.minecraft.server.v1_5_R3.Packet; -import net.minecraft.server.v1_5_R3.Packet20NamedEntitySpawn; -import net.minecraft.server.v1_5_R3.Packet23VehicleSpawn; -import net.minecraft.server.v1_5_R3.Packet24MobSpawn; -import net.minecraft.server.v1_5_R3.Packet26AddExpOrb; +import net.minecraft.server.v1_5_R3.EntityTypes; +import net.minecraft.server.v1_5_R3.ItemStack; +import net.minecraft.server.v1_5_R3.MathHelper; +import net.minecraft.server.v1_5_R3.MinecraftServer; +import net.minecraft.server.v1_5_R3.PlayerInteractManager; +import net.minecraft.server.v1_5_R3.EnumArt; import net.minecraft.server.v1_5_R3.World; import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_5_R3.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_5_R3.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_5_R3.inventory.CraftItemStack; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import com.comphenix.protocol.Packets; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; public class Disguise { protected DisguiseType disguiseType; @@ -28,44 +37,151 @@ public class Disguise { disguiseType = newType; } - public Packet constructPacket(Player p) { - Packet spawnPacket = null; + public PacketContainer constructPacket(org.bukkit.entity.Entity e) { + PacketContainer spawnPacket = null; + ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + Entity entity = ((CraftEntity) e).getHandle(); + Location loc = e.getLocation(); + if (getType() == DisguiseType.EXPERIENCE_ORB) { - Entity entity = getEntity(((CraftPlayer) p).getHandle().world, p.getLocation(), p.getEntityId()); - spawnPacket = new Packet26AddExpOrb((EntityExperienceOrb) entity); + spawnPacket = manager.createPacket(Packets.Server.ADD_EXP_ORB); + StructureModifier mods = spawnPacket.getModifier(); + mods.write(0, e.getEntityId()); + mods.write(1, (int) Math.floor(loc.getX() * 32)); + mods.write(2, (int) Math.floor(loc.getY() * 32) + 2); + mods.write(3, (int) Math.floor(loc.getZ() * 32)); + mods.write(4, 1); + + } else if (getType() == DisguiseType.PAINTING) { + + spawnPacket = manager.createPacket(Packets.Server.ENTITY_PAINTING); + StructureModifier mods = spawnPacket.getModifier(); + mods.write(0, e.getEntityId()); + mods.write(1, loc.getBlockX()); + mods.write(2, loc.getBlockY()); + mods.write(3, loc.getBlockZ()); + mods.write(4, ((int) loc.getYaw()) % 4); + int id = ((MiscDisguise) this).getId(); + if (id == -1) + id = new Random().nextInt(EnumArt.values().length); + mods.write(5, EnumArt.values()[id].B); } else if (getType().isMob()) { - EntityLiving entityLiving = ((MobDisguise) this).getEntityLiving(((CraftPlayer) p).getHandle().world, - p.getLocation(), p.getEntityId()); - spawnPacket = new Packet24MobSpawn(entityLiving); + entity = ((MobDisguise) this).getEntityLiving(((CraftEntity) e).getHandle().world, e.getLocation(), e.getEntityId()); + double d1 = 3.9D; + Vector vec = e.getVelocity(); + double d2 = vec.getX(); + double d3 = vec.getY(); + double d4 = vec.getZ(); + if (d2 < -d1) + d2 = -d1; + if (d3 < -d1) + d3 = -d1; + if (d4 < -d1) + d4 = -d1; + if (d2 > d1) + d2 = d1; + if (d3 > d1) + d3 = d1; + if (d4 > d1) + d4 = d1; + spawnPacket = manager.createPacket(Packets.Server.MOB_SPAWN); + StructureModifier mods = spawnPacket.getModifier(); + mods.write(0, e.getEntityId()); + mods.write(1, (byte) EntityTypes.a(entity)); + mods.write(2, entity.at.a(loc.getX())); + mods.write(3, (int) Math.floor(loc.getY() * 32D)); + mods.write(4, entity.at.a(loc.getZ())); + mods.write(5, (int) (d2 * 8000.0D)); + mods.write(6, (int) (d3 * 8000.0D)); + mods.write(7, (int) (d4 * 8000.0D)); + byte yawValue = (byte) (int) (entity.yaw * 256.0F / 360.0F); if (getType() == DisguiseType.ENDER_DRAGON) - ((Packet24MobSpawn) spawnPacket).i -= 128; + yawValue -= 128; + mods.write(8, yawValue); + mods.write(9, (byte) (int) (entity.pitch * 256.0F / 360.0F)); + mods.write(10, (byte) (int) (((EntityLiving) entity).aA * 256.0F / 360.0F)); + mods.write(11, entity.getDataWatcher()); + // TODO May need to do the list } else if (getType().isMisc()) { - Entity entity = getEntity(((CraftPlayer) p).getHandle().world, p.getLocation(), p.getEntityId()); - if (((MiscDisguise) this).getId() >= 0) { - if (((MiscDisguise) this).getData() >= 0) { - spawnPacket = new Packet23VehicleSpawn(entity, getType().getEntityId(), ((MiscDisguise) this).getId() - | ((MiscDisguise) this).getData() << 16); - } else - spawnPacket = new Packet23VehicleSpawn(entity, getType().getEntityId(), ((MiscDisguise) this).getId()); - } else - spawnPacket = new Packet23VehicleSpawn(entity, getType().getEntityId()); - ((Packet23VehicleSpawn) spawnPacket).i += 64; + getEntity(((CraftEntity) e).getHandle().world, e.getLocation(), e.getEntityId()); + int id = getType().getEntityId(); + int data = 0; + if (((MiscDisguise) this).getId() >= 0) + if (((MiscDisguise) this).getData() >= 0) + data = (((MiscDisguise) this).getId() | ((MiscDisguise) this).getData() << 16); + else + data = ((MiscDisguise) this).getId(); + + spawnPacket = manager.createPacket(Packets.Server.VEHICLE_SPAWN); + StructureModifier mods = spawnPacket.getModifier(); + mods.write(0, e.getEntityId()); + mods.write(1, (int) Math.floor(loc.getX() * 32D)); + mods.write(2, (int) Math.floor(loc.getY() * 32D)); + mods.write(3, (int) Math.floor(loc.getZ() * 32D)); + if (data > 0) { + Vector vec = e.getVelocity(); + double d1 = 3.9D; + double d2 = vec.getX(); + double d3 = vec.getY(); + double d4 = vec.getZ(); + if (d2 < -d1) + d2 = -d1; + if (d3 < -d1) + d3 = -d1; + if (d4 < -d1) + d4 = -d1; + if (d2 > d1) + d2 = d1; + if (d3 > d1) + d3 = d1; + if (d4 > d1) + d4 = d1; + mods.write(4, (int) (d1 * 8000.0D)); + mods.write(5, (int) (d2 * 8000.0D)); + mods.write(6, (int) (d3 * 8000.0D)); + } + mods.write(7, MathHelper.d(entity.pitch * 256.0F / 360.0F)); + mods.write(8, MathHelper.d(entity.yaw * 256.0F / 360.0F) + 64); + mods.write(9, id); + mods.write(10, data); } else if (getType().isPlayer()) { - EntityHuman entityHuman = ((CraftPlayer) p).getHandle(); - spawnPacket = new Packet20NamedEntitySpawn(entityHuman); - ((Packet20NamedEntitySpawn) spawnPacket).b = ((PlayerDisguise) this).getName(); + EntityPlayer entityPlayer = (EntityPlayer) getEntity(((CraftEntity) e).getHandle().world, e.getLocation(), + e.getEntityId()); + entityPlayer.name = ((PlayerDisguise) this).getName(); + spawnPacket = manager.createPacket(Packets.Server.NAMED_ENTITY_SPAWN); + StructureModifier mods = spawnPacket.getModifier(); + mods.write(0, e.getEntityId()); + mods.write(1, ((PlayerDisguise) this).getName()); + mods.write(2, (int) Math.floor(loc.getX() * 32)); + mods.write(3, (int) Math.floor(loc.getY() * 32)); + mods.write(4, (int) Math.floor(loc.getZ() * 32)); + mods.write(5, (byte) (int) (entity.yaw * 256F / 360F)); + mods.write(6, (byte) (int) (entity.pitch * 256F / 360F)); + ItemStack item = null; + if (e instanceof Player && ((Player) e).getItemInHand() != null) + item = CraftItemStack.asNMSCopy(((Player) e).getItemInHand()); + mods.write(7, (item == null ? 0 : item.id)); + mods.write(8, entity.getDataWatcher()); } + return spawnPacket; } + public PacketContainer constructDestroyPacket(int entityId) { + PacketContainer destroyPacket = ProtocolLibrary.getProtocolManager().createPacket(Packets.Server.DESTROY_ENTITY); + StructureModifier mods = destroyPacket.getModifier(); + mods.write(0, new int[] { entityId }); + return destroyPacket; + } + public Entity getEntity(World world, Location loc, int entityId) { if (entity != null) { entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); @@ -73,21 +189,24 @@ public class Disguise { return entity; } try { - String name = toReadable(disguiseType.name()); - if (disguiseType == DisguiseType.WITHER_SKELETON) { - name = "Skeleton"; - } - if (disguiseType == DisguiseType.PRIMED_TNT) { - name = "TNTPrimed"; - } - if (disguiseType == DisguiseType.MINECART_TNT) { - name = "MinecartTNT"; - } - Class entityClass = Class.forName("net.minecraft.server.v1_5_R3.Entity" + name); - Constructor contructor = entityClass.getDeclaredConstructor(World.class); - entity = (Entity) contructor.newInstance(world); - if (disguiseType == DisguiseType.WITHER_SKELETON) { - ((EntitySkeleton) entity).setSkeletonType(1); + if (disguiseType == DisguiseType.PLAYER) { + entity = new EntityPlayer(MinecraftServer.getServer(), world, ((PlayerDisguise) this).getName(), + new PlayerInteractManager(world)); + } else { + String name = toReadable(disguiseType.name()); + if (disguiseType == DisguiseType.WITHER_SKELETON) { + name = "Skeleton"; + } else if (disguiseType == DisguiseType.PRIMED_TNT) { + name = "TNTPrimed"; + } else if (disguiseType == DisguiseType.MINECART_TNT) { + name = "MinecartTNT"; + } + Class entityClass = Class.forName("net.minecraft.server.v1_5_R3.Entity" + name); + Constructor contructor = entityClass.getDeclaredConstructor(World.class); + entity = (Entity) contructor.newInstance(world); + if (disguiseType == DisguiseType.WITHER_SKELETON) { + ((EntitySkeleton) entity).setSkeletonType(1); + } } } catch (Exception ex) { ex.printStackTrace(); diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseSound.java b/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseSound.java new file mode 100644 index 00000000..a69275af --- /dev/null +++ b/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseSound.java @@ -0,0 +1,149 @@ +package me.libraryaddict.disguise.DisguiseTypes; + +import java.util.HashMap; +import java.util.HashSet; + +import org.bukkit.Sound; +import org.bukkit.craftbukkit.v1_5_R3.CraftSound; + +public enum DisguiseSound { + + BAT(Sound.BAT_HURT, null, Sound.BAT_DEATH, Sound.BAT_IDLE, Sound.BAT_LOOP, Sound.BAT_TAKEOFF), + + BLAZE(Sound.BLAZE_HIT, null, Sound.BLAZE_DEATH, Sound.BLAZE_BREATH), + + CAVE_SPIDER(Sound.SPIDER_IDLE, Sound.SPIDER_WALK, Sound.SPIDER_DEATH, Sound.SPIDER_IDLE), + + CHICKEN(Sound.CHICKEN_HURT, Sound.CHICKEN_WALK, Sound.CHICKEN_HURT, Sound.CHICKEN_IDLE, Sound.CHICKEN_EGG_POP), + + COW(Sound.COW_HURT, Sound.COW_WALK, Sound.COW_HURT, Sound.COW_IDLE), + + CREEPER(Sound.CREEPER_HISS, Sound.STEP_GRASS, Sound.CREEPER_DEATH, null), + + ENDER_DRAGON(Sound.ENDERDRAGON_HIT, null, Sound.ENDERDRAGON_DEATH, Sound.ENDERDRAGON_GROWL, Sound.ENDERDRAGON_WINGS), + + ENDERMAN(Sound.ENDERMAN_HIT, Sound.STEP_GRASS, Sound.ENDERMAN_DEATH, Sound.ENDERMAN_IDLE, Sound.ENDERMAN_STARE, + Sound.ENDERMAN_TELEPORT, Sound.ENDERMAN_SCREAM), + + GHAST(Sound.GHAST_SCREAM, null, Sound.GHAST_DEATH, Sound.GHAST_MOAN, Sound.GHAST_CHARGE, Sound.GHAST_FIREBALL, + Sound.GHAST_SCREAM2), + + GIANT_ZOMBIE(Sound.HURT_FLESH, Sound.STEP_GRASS), + + IRON_GOLEM(Sound.IRONGOLEM_HIT, Sound.IRONGOLEM_WALK, Sound.IRONGOLEM_DEATH, null, Sound.IRONGOLEM_THROW), + + MAGMA_CUBE(Sound.SLIME_ATTACK, Sound.SLIME_WALK2, null, null, Sound.SLIME_WALK), + + MUSHROOM_COW(Sound.COW_HURT, Sound.COW_WALK, Sound.COW_HURT, Sound.COW_IDLE), + + OCELOT(Sound.CAT_HIT, Sound.STEP_GRASS, Sound.CAT_HIT, Sound.CAT_MEOW, Sound.CAT_PURR, Sound.CAT_PURREOW), + + PIG(Sound.PIG_IDLE, Sound.PIG_WALK, Sound.PIG_DEATH, Sound.PIG_IDLE), + + PIG_ZOMBIE(Sound.ZOMBIE_PIG_HURT, null, Sound.ZOMBIE_PIG_DEATH, Sound.ZOMBIE_PIG_IDLE, Sound.ZOMBIE_PIG_ANGRY), + + PLAYER(Sound.HURT_FLESH, Sound.STEP_GRASS), + + SHEEP(Sound.SHEEP_IDLE, Sound.SHEEP_WALK, Sound.SHEEP_IDLE, null, Sound.SHEEP_SHEAR), + + SILVERFISH(Sound.SILVERFISH_HIT, Sound.SILVERFISH_WALK, Sound.SILVERFISH_KILL, Sound.SILVERFISH_IDLE), + + SKELETON(Sound.SKELETON_HURT, Sound.SKELETON_WALK, Sound.SKELETON_DEATH, Sound.SKELETON_IDLE), + + SLIME(Sound.SLIME_ATTACK, Sound.SLIME_WALK2, null, null, Sound.SLIME_WALK), + + SNOWMAN(), + + SPIDER(Sound.SPIDER_IDLE, Sound.SPIDER_WALK, Sound.SPIDER_DEATH, Sound.SPIDER_IDLE), + + SQUID(), + + VILLAGER(), + + WITCH(), + + WITHER(Sound.WITHER_HURT, null, Sound.WITHER_DEATH, Sound.WITHER_IDLE, Sound.WITHER_SHOOT, Sound.WITHER_SPAWN), + + WITHER_SKELETON(Sound.SKELETON_HURT, Sound.SKELETON_WALK, Sound.SKELETON_DEATH, Sound.SKELETON_IDLE), + + WOLF(Sound.WOLF_HURT, Sound.WOLF_WALK, Sound.WOLF_DEATH, Sound.WOLF_BARK, Sound.WOLF_WHINE, Sound.WOLF_GROWL, + Sound.WOLF_HOWL, Sound.WOLF_PANT, Sound.WOLF_SHAKE), + + ZOMBIE(Sound.ZOMBIE_HURT, Sound.STEP_GRASS, Sound.ZOMBIE_DEATH, Sound.ZOMBIE_IDLE, Sound.ZOMBIE_INFECT, Sound.ZOMBIE_METAL, + Sound.ZOMBIE_WOODBREAK, Sound.ZOMBIE_WOOD); + public enum SoundType { + HURT, STEP, IDLE, DEATH, CANCEL; + } + + private HashSet cancelSounds = new HashSet(); + private HashMap disguiseSounds = new HashMap(); + + DisguiseSound(Sound... sounds) { + for (int i = 0; i < sounds.length; i++) { + Sound s = sounds[i]; + if (i == 0) + disguiseSounds.put(SoundType.HURT, s); + else if (i == 1) + disguiseSounds.put(SoundType.STEP, s); + else if (i == 2) + disguiseSounds.put(SoundType.DEATH, s); + else if (i == 3) + disguiseSounds.put(SoundType.IDLE, s); + else + cancelSounds.add(s); + } + } + + public boolean isCancelled(String soundName) { + return cancelSounds.contains(soundName); + } + + public Sound getSound(SoundType type) { + if (type == null) + return null; + return disguiseSounds.get(type); + } + + public HashSet getSoundsToCancel() { + return cancelSounds; + } + + public static String getSoundName(Sound sound) { + return CraftSound.getSound(sound); + } + + public boolean isCancelSound(String sound) { + for (Sound s : cancelSounds) + if (getSoundName(s).equals(sound)) + return true; + return false; + } + + /** + * Used to check if the original sound is owned by this disguise sound Ofc it won't be correct for commonly shared names. But + * its the best I can possibly do + */ + public SoundType ownsSound(String name) { + if (isCancelSound(name)) + return SoundType.CANCEL; + if (disguiseSounds.get(SoundType.STEP) == Sound.STEP_GRASS && name.startsWith("step.")) + return SoundType.STEP; + for (SoundType type : disguiseSounds.keySet()) { + Sound s = disguiseSounds.get(type); + if (s != null) + if (CraftSound.getSound(s).equals(name)) + return type; + } + return null; + } + + public static DisguiseSound getType(String name) { + try { + if (name.equals("GIANT")) + return DisguiseSound.GIANT_ZOMBIE; + return valueOf(name); + } catch (Exception ex) { + return null; + } + } +} diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseType.java b/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseType.java index 69257ba3..5e21dd4a 100644 --- a/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseType.java +++ b/src/me/libraryaddict/disguise/DisguiseTypes/DisguiseType.java @@ -15,13 +15,23 @@ public enum DisguiseType { EntityType.MISC, 64, 0), SNOWBALL(EntityType.MISC, 61), SNOWMAN(EntityType.MOB), SPIDER(EntityType.MOB), SQUID( EntityType.MOB), THROWN_EXP_BOTTLE(EntityType.MISC, 75), VILLAGER(EntityType.MOB), WITCH(EntityType.MOB), WITHER( EntityType.MOB), WITHER_SKELETON(EntityType.MOB), WITHER_SKULL(EntityType.MISC, 66), WOLF(EntityType.MOB), ZOMBIE( - EntityType.MOB); + EntityType.MOB), PAINTING(EntityType.MISC); public static enum EntityType { MISC, MOB, PLAYER; } public static DisguiseType getType(org.bukkit.entity.EntityType entityType) { + if (entityType == org.bukkit.entity.EntityType.SPLASH_POTION) + return DisguiseType.POTION; + else if (entityType == org.bukkit.entity.EntityType.GIANT) + return DisguiseType.GIANT_ZOMBIE; + else if (entityType == org.bukkit.entity.EntityType.DROPPED_ITEM) + return DisguiseType.ITEM; + else if (entityType == org.bukkit.entity.EntityType.FIREBALL) + return DisguiseType.LARGE_FIREBALL; + else if (entityType == org.bukkit.entity.EntityType.SMALL_FIREBALL) + return DisguiseType.LARGE_FIREBALL; return DisguiseType.valueOf(entityType.name()); } @@ -30,26 +40,19 @@ public enum DisguiseType { private int entityId; private EntityType entityType; - private DisguiseType(EntityType newType) { + private DisguiseType(EntityType newType, int... obj) { entityType = newType; - } - - private DisguiseType(EntityType newType, int entityId) { - entityType = newType; - this.entityId = entityId; - } - - private DisguiseType(EntityType newType, int entityId, int defaultId) { - entityType = newType; - this.entityId = entityId; - this.defaultId = defaultId; - } - - private DisguiseType(EntityType newType, int entityId, int defaultId, int defaultData) { - entityType = newType; - this.entityId = entityId; - this.defaultId = defaultId; - this.defaultData = defaultData; + int a = 0; + for (int i = 0; i < obj.length; i++) { + int value = obj[i]; + if (a == 0) + entityId = value; + else if (a == 1) + defaultId = value; + else if (a == 2) + defaultData = value; + a++; + } } public int getDefaultData() { diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java b/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java index b0a31f4b..c530aea3 100644 --- a/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java +++ b/src/me/libraryaddict/disguise/DisguiseTypes/FlagWatcher.java @@ -37,9 +37,12 @@ public abstract class FlagWatcher { Iterator itel = list.iterator(); List newList = new ArrayList(); List sentValues = new ArrayList(); + boolean sendAllCustom = false; while (itel.hasNext()) { WatchableObject watch = itel.next(); sentValues.add(watch.a()); + if (watch.a() == 1) + sendAllCustom = true; if (entityValues.containsKey(watch.a())) { boolean doD = watch.d(); watch = new WatchableObject(watch.c(), watch.a(), watch.b()); @@ -65,7 +68,7 @@ public abstract class FlagWatcher { } newList.add(watch); } - if (list.size() == 10) { + if (sendAllCustom) { // Its sending the entire meta data. Better add the custom meta for (int value : entityValues.keySet()) { if (sentValues.contains(value)) diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/Watchers/ItemFrameWatcher.java b/src/me/libraryaddict/disguise/DisguiseTypes/Watchers/ItemFrameWatcher.java new file mode 100644 index 00000000..08f3ad2f --- /dev/null +++ b/src/me/libraryaddict/disguise/DisguiseTypes/Watchers/ItemFrameWatcher.java @@ -0,0 +1,30 @@ +package me.libraryaddict.disguise.DisguiseTypes.Watchers; + +import org.bukkit.craftbukkit.v1_5_R3.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +import me.libraryaddict.disguise.DisguiseTypes.FlagWatcher; + +public class ItemFrameWatcher extends FlagWatcher { + + protected ItemFrameWatcher(int entityId) { + super(entityId); + setValue(2, 5); + setValue(3, (byte) 0); + } + + public ItemStack getItemStack() { + if (getValue(3) instanceof Integer) + return new ItemStack(0); + return CraftItemStack.asBukkitCopy((net.minecraft.server.v1_5_R3.ItemStack) getValue(3)); + } + + public void setItemStack(ItemStack newItem) { + if (newItem.getTypeId() == 0) + setValue(3, (byte) 0); + else { + setValue(3, CraftItemStack.asCraftCopy(newItem)); + } + } + +} diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/Watchers/PlayerWatcher.java b/src/me/libraryaddict/disguise/DisguiseTypes/Watchers/PlayerWatcher.java new file mode 100644 index 00000000..97406e46 --- /dev/null +++ b/src/me/libraryaddict/disguise/DisguiseTypes/Watchers/PlayerWatcher.java @@ -0,0 +1,14 @@ +package me.libraryaddict.disguise.DisguiseTypes.Watchers; + +import me.libraryaddict.disguise.DisguiseTypes.FlagWatcher; + +public class PlayerWatcher extends FlagWatcher { + + protected PlayerWatcher(int entityId) { + super(entityId); + setValue(8, 0); + setValue(9, (byte) 0); + setValue(10, (byte) 0); + } + +} diff --git a/src/me/libraryaddict/disguise/LibsDisguises.java b/src/me/libraryaddict/disguise/LibsDisguises.java index 19417bdf..19d7f7dd 100644 --- a/src/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/me/libraryaddict/disguise/LibsDisguises.java @@ -1,23 +1,21 @@ package me.libraryaddict.disguise; -import java.lang.reflect.Field; -import java.util.Arrays; import java.util.List; import me.libraryaddict.disguise.DisguiseTypes.Disguise; import me.libraryaddict.disguise.DisguiseTypes.DisguiseType; import me.libraryaddict.disguise.DisguiseTypes.PlayerDisguise; import net.minecraft.server.v1_5_R3.WatchableObject; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.craftbukkit.v1_5_R3.CraftSound; +import org.bukkit.entity.Arrow; import org.bukkit.entity.Entity; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import com.comphenix.protocol.Packets; import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.ConnectionSide; import com.comphenix.protocol.events.ListenerPriority; import com.comphenix.protocol.events.PacketAdapter; @@ -27,135 +25,86 @@ import com.comphenix.protocol.reflect.StructureModifier; public class LibsDisguises extends JavaPlugin { public void onEnable() { - ProtocolLibrary.getProtocolManager().addPacketListener( - new PacketAdapter(this, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL, Packets.Server.NAMED_ENTITY_SPAWN, - Packets.Server.ENTITY_METADATA, Packets.Server.NAMED_SOUND_EFFECT, Packets.Server.ARM_ANIMATION, - Packets.Server.REL_ENTITY_MOVE_LOOK, Packets.Server.ENTITY_LOOK, Packets.Server.ENTITY_TELEPORT) { - @Override - public void onPacketSending(PacketEvent event) { - StructureModifier mods = event.getPacket().getModifier(); - try { - Player observer = event.getPlayer(); - if (event.getPacketID() == Packets.Server.NAMED_SOUND_EFFECT) { - if (!DisguiseAPI.playSounds()) - return; - String soundName = (String) mods.read(0); - if (soundName.startsWith("step.") || soundName.equals("damage.hit")) { - Disguise dis = null; - Location soundLoc = new Location(observer.getWorld(), (Integer) mods.read(1), (Integer) mods - .read(2), (Integer) mods.read(3)); - for (Player player : Bukkit.getOnlinePlayers()) { - if (DisguiseAPI.isDisguised(player)) { - Location loc = player.getLocation(); - Location dLoc = new Location(observer.getWorld(), (int) (loc.getX() * 8), (int) (loc - .getY() * 8), (int) (loc.getZ() * 8)); - if (dLoc.equals(soundLoc)) { - dis = DisguiseAPI.getDisguise(player); - break; - } - } - } - if (dis != null) { - if (dis.getType().isPlayer()) - return; - if (dis.getType().isMisc()) { - event.setCancelled(true); - return; - } - String sound = null; - try { - Field field = CraftSound.class.getDeclaredField("sounds"); - field.setAccessible(true); - List sounds = Arrays.asList((String[]) field.get(null)); - String mobName = dis.getType().name().toLowerCase().replace("_", ""); - if (dis.getType() == DisguiseType.WITHER_SKELETON) - mobName = "skeleton"; - else if (dis.getType() == DisguiseType.CAVE_SPIDER) - mobName = "spider"; - else if (dis.getType() == DisguiseType.ENDERMAN) - mobName = "endermen"; - else if (dis.getType() == DisguiseType.MUSHROOM_COW) - mobName = "cow"; - if (soundName.startsWith("step.")) { - if (sounds.contains("mob." + mobName + ".walk")) - sound = "mob." + mobName + ".walk"; - else if (sounds.contains("mob." + mobName + ".step")) - sound = "mob." + mobName + ".step"; - } else if (soundName.equals("damage.hit")) { - if (dis.getType() == DisguiseType.SNOWMAN - || dis.getType() == DisguiseType.VILLAGER - || dis.getType() == DisguiseType.WITCH) { - event.setCancelled(true); - return; - } - if (dis.getType() == DisguiseType.PIG_ZOMBIE) - sound = "mob.zombiepig.zpighurt"; - else if (dis.getType() == DisguiseType.GHAST) - sound = "mob.ghast.scream"; - else if (dis.getType() == DisguiseType.OCELOT) - sound = "mob.cat.hitt"; - else if (mobName.equals("slime")) - sound = "mob.slime.attack"; - else if (sounds.contains("mob." + mobName + ".hit")) - sound = "mob." + mobName + ".hit"; - else if (sounds.contains("mob." + mobName + ".hurt")) - sound = "mob." + mobName + ".hurt"; - else if (sounds.contains("mob." + mobName + ".say")) - sound = "mob." + mobName + ".say"; - } - } catch (Exception ex) { - ex.printStackTrace(); - } - if (sound != null) { - mods.write(0, sound); - } - } + DisguiseAPI.init(this); + DisguiseAPI.enableSounds(true); + final ProtocolManager manager = ProtocolLibrary.getProtocolManager(); + manager.addPacketListener(new PacketAdapter(this, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL, + Packets.Server.NAMED_ENTITY_SPAWN, Packets.Server.ENTITY_METADATA, Packets.Server.ARM_ANIMATION, + Packets.Server.REL_ENTITY_MOVE_LOOK, Packets.Server.ENTITY_LOOK, Packets.Server.ENTITY_TELEPORT, + Packets.Server.ADD_EXP_ORB, Packets.Server.VEHICLE_SPAWN, Packets.Server.MOB_SPAWN, + Packets.Server.ENTITY_PAINTING, Packets.Server.COLLECT) { + @Override + public void onPacketSending(PacketEvent event) { + StructureModifier mods = event.getPacket().getModifier(); + try { + Player observer = event.getPlayer(); + StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); + org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == event.getPacketID() ? 1 : 0)); + if (DisguiseAPI.isDisguised(entity)) { + Disguise disguise = DisguiseAPI.getDisguise(entity); + if (event.getPacketID() == Packets.Server.ENTITY_METADATA) { + if (!(entity instanceof Player && disguise.getType().isPlayer())) + if (disguise.hasWatcher()) + mods.write(1, disguise.getWatcher().convert((List) mods.read(1))); + } else if (event.getPacketID() == Packets.Server.NAMED_ENTITY_SPAWN) { + if (disguise.getType().isPlayer()) { + String name = (String) mods.read(1); + if (!name.equals(((PlayerDisguise) disguise).getName())) { + // manager.sendServerPacket(observer, disguise.constructDestroyPacket(entity.getEntityId())); + event.setPacket(disguise.constructPacket(entity)); } } else { - StructureModifier entityModifer = event.getPacket() - .getEntityModifier(observer.getWorld()); - org.bukkit.entity.Entity entity = entityModifer.read(0); - if (entity instanceof Player) { - Player watched = (Player) entity; - if (DisguiseAPI.isDisguised(watched.getName())) { - Disguise disguise = DisguiseAPI.getDisguise(watched); - if (event.getPacketID() == Packets.Server.ENTITY_METADATA - && !disguise.getType().isPlayer()) { - if (disguise.hasWatcher()) { - mods.write(1, disguise.getWatcher().convert((List) mods.read(1))); - } - } else if (event.getPacketID() == Packets.Server.NAMED_ENTITY_SPAWN) { - if (disguise.getType().isPlayer()) { - String name = (String) mods.read(1); - if (!name.equals(((PlayerDisguise) disguise).getName())) { - event.setCancelled(true); - DisguiseAPI.disguiseToPlayer(watched, observer, disguise); - } - } else { - event.setCancelled(true); - DisguiseAPI.disguiseToPlayer(watched, observer, disguise); - } - } else if (event.getPacketID() == Packets.Server.ARM_ANIMATION) { - if (disguise.getType().isMisc()) { - event.setCancelled(true); - } - } else { - if (disguise.getType() == DisguiseType.ENDER_DRAGON) { - byte value = (Byte) mods.read(4); - mods.write(4, (byte) (value - 128)); - } else if (disguise.getType().isMisc()) { - byte value = (Byte) mods.read(4); - mods.write(4, (byte) (value + 64)); - } - } - } - } + // manager.sendServerPacket(observer, disguise.constructDestroyPacket(entity.getEntityId())); + event.setPacket(disguise.constructPacket(entity)); + } + } else if (event.getPacketID() == Packets.Server.MOB_SPAWN + || event.getPacketID() == Packets.Server.ADD_EXP_ORB + || event.getPacketID() == Packets.Server.VEHICLE_SPAWN + || event.getPacketID() == Packets.Server.ENTITY_PAINTING) { + // manager.sendServerPacket(observer, disguise.constructDestroyPacket(entity.getEntityId())); + event.setPacket(disguise.constructPacket(entity)); + } else if (event.getPacketID() == Packets.Server.ARM_ANIMATION + || event.getPacketID() == Packets.Server.COLLECT) { + if (disguise.getType().isMisc()) { + event.setCancelled(true); + } + } else if (Packets.Server.REL_ENTITY_MOVE_LOOK == event.getPacketID() + || Packets.Server.ENTITY_LOOK == event.getPacketID() + || Packets.Server.ENTITY_TELEPORT == event.getPacketID()) { + if (disguise.getType() == DisguiseType.ENDER_DRAGON) { + byte value = (Byte) mods.read(4); + mods.write(4, (byte) (value - 128)); + } else if (disguise.getType().isMisc()) { + byte value = (Byte) mods.read(4); + if (disguise.getType() != DisguiseType.PAINTING) + mods.write(4, (byte) (value + 64)); + else + mods.write(4, (byte) -(value += 128)); } - } catch (Exception e) { - e.printStackTrace(); } } - }); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + manager.addPacketListener(new PacketAdapter(this, ConnectionSide.CLIENT_SIDE, ListenerPriority.NORMAL, + Packets.Client.USE_ENTITY) { + @Override + public void onPacketReceiving(PacketEvent event) { + try { + Player observer = event.getPlayer(); + StructureModifier entityModifer = event.getPacket().getEntityModifier(observer.getWorld()); + org.bukkit.entity.Entity entity = entityModifer.read(1); + if (DisguiseAPI.isDisguised(entity) + && (entity instanceof ExperienceOrb || entity instanceof Item || entity instanceof Arrow)) { + event.setCancelled(true); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); getCommand("disguise").setExecutor(new DisguiseCommand()); getCommand("undisguise").setExecutor(new UndisguiseCommand()); }