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
This commit is contained in:
Andrew 2013-05-29 10:29:36 +12:00
parent 89959fb89e
commit 09b4955e23
8 changed files with 601 additions and 268 deletions

View File

@ -1,18 +1,100 @@
package me.libraryaddict.disguise; package me.libraryaddict.disguise;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import me.libraryaddict.disguise.DisguiseTypes.Disguise; 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.Location;
import org.bukkit.craftbukkit.v1_5_R3.entity.CraftPlayer; 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.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 { public class DisguiseAPI {
private static ConcurrentHashMap<String, Disguise> disguises = new ConcurrentHashMap<String, Disguise>(); private static ConcurrentHashMap<Object, Disguise> disguises = new ConcurrentHashMap<Object, Disguise>();
private static boolean playSounds = true; 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<Object> 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 * @param Player
@ -20,93 +102,77 @@ public class DisguiseAPI {
* @param Disguise * @param Disguise
* - The disguise to wear * - The disguise to wear
*/ */
public static void disguiseToAll(Player p, Disguise disguise) { public static void disguiseToAll(Entity entity, Disguise disguise) {
disguises.put(p.getName(), disguise); disguises.put(entity instanceof Player ? ((Player) entity).getName() : entity.getUniqueId(), disguise);
disguise.constructPacket(p); refresh(entity);
for (Player player : Bukkit.getOnlinePlayers()) {
if (p.getWorld() != player.getWorld() || !player.canSee(p))
continue;
player.hidePlayer(p);
player.showPlayer(p);
}
} }
/** private static void refresh(Entity entity) {
* @param Player EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ((CraftEntity) entity).getHandle().world).tracker.trackedEntities
* - The player who is being disguised .get(entity.getEntityId());
* @param Player if (entry != null) {
* - The player who is watching the disguised Iterator itel = entry.trackedPlayers.iterator();
* @param Disguise while (itel.hasNext()) {
* - The disguise he is wearing EntityPlayer player = (EntityPlayer) itel.next();
*/ entry.clear(player);
public static void disguiseToPlayer(Player disguiser, Player observer, Disguise disguise) { entry.updatePlayer(player);
disguises.put(disguiser.getName(), disguise); }
Packet29DestroyEntity destroyPacket = new Packet29DestroyEntity(new int[] { disguiser.getEntityId() }); }
Packet spawnPacket = disguise.constructPacket(disguiser); /*
((CraftPlayer) observer).getHandle().playerConnection.sendPacket(destroyPacket); // Get the tracker of the people who can see the hider
((CraftPlayer) observer).getHandle().playerConnection.sendPacket(spawnPacket); 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 * @param Disguiser
* @return Disguise * @return Disguise
*/ */
public static Disguise getDisguise(Player p) { public static Disguise getDisguise(Object disguiser) {
return getDisguise(p.getName()); 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 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());
} }
/** /**
* @param Disguiser * @param Disguiser
* @return boolean - If the disguiser is disguised * @return boolean - If the disguiser is disguised
*/ */
public static boolean isDisguised(String name) { public static boolean isDisguised(Object disguiser) {
return disguises.containsKey(name); 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);
/**
* 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;
} }
/** /**
* @param Disguiser * @param Disguiser
* - Undisguises him * - Undisguises him
*/ */
public static void undisguiseToAll(Player p) { public static void undisguiseToAll(Entity entity) {
disguises.remove(p.getName()); disguises.remove(entity instanceof Player ? ((Player) entity).getName() : entity.getUniqueId());
for (Player player : Bukkit.getOnlinePlayers()) { refresh(entity);
if (p.getWorld() != player.getWorld())
continue;
player.hidePlayer(p);
player.showPlayer(p);
}
} }
public static void enableSounds(boolean isSoundsEnabled) {
if (soundsEnabled != isSoundsEnabled) {
soundsEnabled = isSoundsEnabled;
if (soundsEnabled) {
ProtocolLibrary.getProtocolManager().addPacketListener(packetListener);
} else {
ProtocolLibrary.getProtocolManager().removePacketListener(packetListener);
}
}
}
} }

View File

@ -1,23 +1,32 @@
package me.libraryaddict.disguise.DisguiseTypes; package me.libraryaddict.disguise.DisguiseTypes;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Random;
import me.libraryaddict.disguise.DisguiseTypes.Watchers.AgeableWatcher; import me.libraryaddict.disguise.DisguiseTypes.Watchers.AgeableWatcher;
import net.minecraft.server.v1_5_R3.Entity; import net.minecraft.server.v1_5_R3.Entity;
import net.minecraft.server.v1_5_R3.EntityAgeable; 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.EntityLiving;
import net.minecraft.server.v1_5_R3.EntityPlayer;
import net.minecraft.server.v1_5_R3.EntitySkeleton; import net.minecraft.server.v1_5_R3.EntitySkeleton;
import net.minecraft.server.v1_5_R3.Packet; import net.minecraft.server.v1_5_R3.EntityTypes;
import net.minecraft.server.v1_5_R3.Packet20NamedEntitySpawn; import net.minecraft.server.v1_5_R3.ItemStack;
import net.minecraft.server.v1_5_R3.Packet23VehicleSpawn; import net.minecraft.server.v1_5_R3.MathHelper;
import net.minecraft.server.v1_5_R3.Packet24MobSpawn; import net.minecraft.server.v1_5_R3.MinecraftServer;
import net.minecraft.server.v1_5_R3.Packet26AddExpOrb; 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 net.minecraft.server.v1_5_R3.World;
import org.bukkit.Location; 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.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 { public class Disguise {
protected DisguiseType disguiseType; protected DisguiseType disguiseType;
@ -28,44 +37,151 @@ public class Disguise {
disguiseType = newType; disguiseType = newType;
} }
public Packet constructPacket(Player p) { public PacketContainer constructPacket(org.bukkit.entity.Entity e) {
Packet spawnPacket = null; PacketContainer spawnPacket = null;
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
Entity entity = ((CraftEntity) e).getHandle();
Location loc = e.getLocation();
if (getType() == DisguiseType.EXPERIENCE_ORB) { if (getType() == DisguiseType.EXPERIENCE_ORB) {
Entity entity = getEntity(((CraftPlayer) p).getHandle().world, p.getLocation(), p.getEntityId()); spawnPacket = manager.createPacket(Packets.Server.ADD_EXP_ORB);
spawnPacket = new Packet26AddExpOrb((EntityExperienceOrb) entity); StructureModifier<Object> 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<Object> 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()) { } else if (getType().isMob()) {
EntityLiving entityLiving = ((MobDisguise) this).getEntityLiving(((CraftPlayer) p).getHandle().world, entity = ((MobDisguise) this).getEntityLiving(((CraftEntity) e).getHandle().world, e.getLocation(), e.getEntityId());
p.getLocation(), p.getEntityId()); double d1 = 3.9D;
spawnPacket = new Packet24MobSpawn(entityLiving); 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<Object> 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) 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()) { } else if (getType().isMisc()) {
Entity entity = getEntity(((CraftPlayer) p).getHandle().world, p.getLocation(), p.getEntityId()); getEntity(((CraftEntity) e).getHandle().world, e.getLocation(), e.getEntityId());
if (((MiscDisguise) this).getId() >= 0) { int id = getType().getEntityId();
if (((MiscDisguise) this).getData() >= 0) { int data = 0;
spawnPacket = new Packet23VehicleSpawn(entity, getType().getEntityId(), ((MiscDisguise) this).getId() if (((MiscDisguise) this).getId() >= 0)
| ((MiscDisguise) this).getData() << 16); if (((MiscDisguise) this).getData() >= 0)
} else data = (((MiscDisguise) this).getId() | ((MiscDisguise) this).getData() << 16);
spawnPacket = new Packet23VehicleSpawn(entity, getType().getEntityId(), ((MiscDisguise) this).getId()); else
} else data = ((MiscDisguise) this).getId();
spawnPacket = new Packet23VehicleSpawn(entity, getType().getEntityId());
((Packet23VehicleSpawn) spawnPacket).i += 64; spawnPacket = manager.createPacket(Packets.Server.VEHICLE_SPAWN);
StructureModifier<Object> 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()) { } else if (getType().isPlayer()) {
EntityHuman entityHuman = ((CraftPlayer) p).getHandle(); EntityPlayer entityPlayer = (EntityPlayer) getEntity(((CraftEntity) e).getHandle().world, e.getLocation(),
spawnPacket = new Packet20NamedEntitySpawn(entityHuman); e.getEntityId());
((Packet20NamedEntitySpawn) spawnPacket).b = ((PlayerDisguise) this).getName(); entityPlayer.name = ((PlayerDisguise) this).getName();
spawnPacket = manager.createPacket(Packets.Server.NAMED_ENTITY_SPAWN);
StructureModifier<Object> 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; return spawnPacket;
} }
public PacketContainer constructDestroyPacket(int entityId) {
PacketContainer destroyPacket = ProtocolLibrary.getProtocolManager().createPacket(Packets.Server.DESTROY_ENTITY);
StructureModifier<Object> mods = destroyPacket.getModifier();
mods.write(0, new int[] { entityId });
return destroyPacket;
}
public Entity getEntity(World world, Location loc, int entityId) { public Entity getEntity(World world, Location loc, int entityId) {
if (entity != null) { if (entity != null) {
entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); entity.setLocation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
@ -73,14 +189,16 @@ public class Disguise {
return entity; return entity;
} }
try { try {
if (disguiseType == DisguiseType.PLAYER) {
entity = new EntityPlayer(MinecraftServer.getServer(), world, ((PlayerDisguise) this).getName(),
new PlayerInteractManager(world));
} else {
String name = toReadable(disguiseType.name()); String name = toReadable(disguiseType.name());
if (disguiseType == DisguiseType.WITHER_SKELETON) { if (disguiseType == DisguiseType.WITHER_SKELETON) {
name = "Skeleton"; name = "Skeleton";
} } else if (disguiseType == DisguiseType.PRIMED_TNT) {
if (disguiseType == DisguiseType.PRIMED_TNT) {
name = "TNTPrimed"; name = "TNTPrimed";
} } else if (disguiseType == DisguiseType.MINECART_TNT) {
if (disguiseType == DisguiseType.MINECART_TNT) {
name = "MinecartTNT"; name = "MinecartTNT";
} }
Class entityClass = Class.forName("net.minecraft.server.v1_5_R3.Entity" + name); Class entityClass = Class.forName("net.minecraft.server.v1_5_R3.Entity" + name);
@ -89,6 +207,7 @@ public class Disguise {
if (disguiseType == DisguiseType.WITHER_SKELETON) { if (disguiseType == DisguiseType.WITHER_SKELETON) {
((EntitySkeleton) entity).setSkeletonType(1); ((EntitySkeleton) entity).setSkeletonType(1);
} }
}
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }

View File

@ -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<Sound> cancelSounds = new HashSet<Sound>();
private HashMap<SoundType, Sound> disguiseSounds = new HashMap<SoundType, Sound>();
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<Sound> 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;
}
}
}

View File

@ -15,13 +15,23 @@ public enum DisguiseType {
EntityType.MISC, 64, 0), SNOWBALL(EntityType.MISC, 61), SNOWMAN(EntityType.MOB), SPIDER(EntityType.MOB), SQUID( 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), 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), WITHER_SKELETON(EntityType.MOB), WITHER_SKULL(EntityType.MISC, 66), WOLF(EntityType.MOB), ZOMBIE(
EntityType.MOB); EntityType.MOB), PAINTING(EntityType.MISC);
public static enum EntityType { public static enum EntityType {
MISC, MOB, PLAYER; MISC, MOB, PLAYER;
} }
public static DisguiseType getType(org.bukkit.entity.EntityType entityType) { 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()); return DisguiseType.valueOf(entityType.name());
} }
@ -30,26 +40,19 @@ public enum DisguiseType {
private int entityId; private int entityId;
private EntityType entityType; private EntityType entityType;
private DisguiseType(EntityType newType) { private DisguiseType(EntityType newType, int... obj) {
entityType = newType; entityType = newType;
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++;
} }
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;
} }
public int getDefaultData() { public int getDefaultData() {

View File

@ -37,9 +37,12 @@ public abstract class FlagWatcher {
Iterator<WatchableObject> itel = list.iterator(); Iterator<WatchableObject> itel = list.iterator();
List<WatchableObject> newList = new ArrayList<WatchableObject>(); List<WatchableObject> newList = new ArrayList<WatchableObject>();
List<Integer> sentValues = new ArrayList<Integer>(); List<Integer> sentValues = new ArrayList<Integer>();
boolean sendAllCustom = false;
while (itel.hasNext()) { while (itel.hasNext()) {
WatchableObject watch = itel.next(); WatchableObject watch = itel.next();
sentValues.add(watch.a()); sentValues.add(watch.a());
if (watch.a() == 1)
sendAllCustom = true;
if (entityValues.containsKey(watch.a())) { if (entityValues.containsKey(watch.a())) {
boolean doD = watch.d(); boolean doD = watch.d();
watch = new WatchableObject(watch.c(), watch.a(), watch.b()); watch = new WatchableObject(watch.c(), watch.a(), watch.b());
@ -65,7 +68,7 @@ public abstract class FlagWatcher {
} }
newList.add(watch); newList.add(watch);
} }
if (list.size() == 10) { if (sendAllCustom) {
// Its sending the entire meta data. Better add the custom meta // Its sending the entire meta data. Better add the custom meta
for (int value : entityValues.keySet()) { for (int value : entityValues.keySet()) {
if (sentValues.contains(value)) if (sentValues.contains(value))

View File

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

View File

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

View File

@ -1,23 +1,21 @@
package me.libraryaddict.disguise; package me.libraryaddict.disguise;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List; import java.util.List;
import me.libraryaddict.disguise.DisguiseTypes.Disguise; import me.libraryaddict.disguise.DisguiseTypes.Disguise;
import me.libraryaddict.disguise.DisguiseTypes.DisguiseType; import me.libraryaddict.disguise.DisguiseTypes.DisguiseType;
import me.libraryaddict.disguise.DisguiseTypes.PlayerDisguise; import me.libraryaddict.disguise.DisguiseTypes.PlayerDisguise;
import net.minecraft.server.v1_5_R3.WatchableObject; import net.minecraft.server.v1_5_R3.WatchableObject;
import org.bukkit.entity.Arrow;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_5_R3.CraftSound;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import com.comphenix.protocol.Packets; import com.comphenix.protocol.Packets;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ConnectionSide; import com.comphenix.protocol.events.ConnectionSide;
import com.comphenix.protocol.events.ListenerPriority; import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
@ -27,130 +25,81 @@ import com.comphenix.protocol.reflect.StructureModifier;
public class LibsDisguises extends JavaPlugin { public class LibsDisguises extends JavaPlugin {
public void onEnable() { public void onEnable() {
ProtocolLibrary.getProtocolManager().addPacketListener( DisguiseAPI.init(this);
new PacketAdapter(this, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL, Packets.Server.NAMED_ENTITY_SPAWN, DisguiseAPI.enableSounds(true);
Packets.Server.ENTITY_METADATA, Packets.Server.NAMED_SOUND_EFFECT, Packets.Server.ARM_ANIMATION, final ProtocolManager manager = ProtocolLibrary.getProtocolManager();
Packets.Server.REL_ENTITY_MOVE_LOOK, Packets.Server.ENTITY_LOOK, Packets.Server.ENTITY_TELEPORT) { 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 @Override
public void onPacketSending(PacketEvent event) { public void onPacketSending(PacketEvent event) {
StructureModifier<Object> mods = event.getPacket().getModifier(); StructureModifier<Object> mods = event.getPacket().getModifier();
try { try {
Player observer = event.getPlayer(); Player observer = event.getPlayer();
if (event.getPacketID() == Packets.Server.NAMED_SOUND_EFFECT) { StructureModifier<Entity> entityModifer = event.getPacket().getEntityModifier(observer.getWorld());
if (!DisguiseAPI.playSounds()) org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == event.getPacketID() ? 1 : 0));
return; if (DisguiseAPI.isDisguised(entity)) {
String soundName = (String) mods.read(0); Disguise disguise = DisguiseAPI.getDisguise(entity);
if (soundName.startsWith("step.") || soundName.equals("damage.hit")) { if (event.getPacketID() == Packets.Server.ENTITY_METADATA) {
Disguise dis = null; if (!(entity instanceof Player && disguise.getType().isPlayer()))
Location soundLoc = new Location(observer.getWorld(), (Integer) mods.read(1), (Integer) mods if (disguise.hasWatcher())
.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<String> 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);
}
}
}
} else {
StructureModifier<Entity> 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<WatchableObject>) mods.read(1))); mods.write(1, disguise.getWatcher().convert((List<WatchableObject>) mods.read(1)));
}
} else if (event.getPacketID() == Packets.Server.NAMED_ENTITY_SPAWN) { } else if (event.getPacketID() == Packets.Server.NAMED_ENTITY_SPAWN) {
if (disguise.getType().isPlayer()) { if (disguise.getType().isPlayer()) {
String name = (String) mods.read(1); String name = (String) mods.read(1);
if (!name.equals(((PlayerDisguise) disguise).getName())) { if (!name.equals(((PlayerDisguise) disguise).getName())) {
event.setCancelled(true); // manager.sendServerPacket(observer, disguise.constructDestroyPacket(entity.getEntityId()));
DisguiseAPI.disguiseToPlayer(watched, observer, disguise); event.setPacket(disguise.constructPacket(entity));
} }
} else { } else {
event.setCancelled(true); // manager.sendServerPacket(observer, disguise.constructDestroyPacket(entity.getEntityId()));
DisguiseAPI.disguiseToPlayer(watched, observer, disguise); event.setPacket(disguise.constructPacket(entity));
} }
} else if (event.getPacketID() == Packets.Server.ARM_ANIMATION) { } 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()) { if (disguise.getType().isMisc()) {
event.setCancelled(true); event.setCancelled(true);
} }
} else { } 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) { if (disguise.getType() == DisguiseType.ENDER_DRAGON) {
byte value = (Byte) mods.read(4); byte value = (Byte) mods.read(4);
mods.write(4, (byte) (value - 128)); mods.write(4, (byte) (value - 128));
} else if (disguise.getType().isMisc()) { } else if (disguise.getType().isMisc()) {
byte value = (Byte) mods.read(4); byte value = (Byte) mods.read(4);
if (disguise.getType() != DisguiseType.PAINTING)
mods.write(4, (byte) (value + 64)); mods.write(4, (byte) (value + 64));
else
mods.write(4, (byte) -(value += 128));
} }
} }
} }
} 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<Entity> 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) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }