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