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;
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<String, Disguise> disguises = new ConcurrentHashMap<String, Disguise>();
private static boolean playSounds = true;
private static ConcurrentHashMap<Object, Disguise> disguises = new ConcurrentHashMap<Object, Disguise>();
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
@ -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);
}
}
}
}

View File

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

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.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() {

View File

@ -37,9 +37,12 @@ public abstract class FlagWatcher {
Iterator<WatchableObject> itel = list.iterator();
List<WatchableObject> newList = new ArrayList<WatchableObject>();
List<Integer> sentValues = new ArrayList<Integer>();
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))

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;
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<Object> 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<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);
}
}
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<Object> mods = event.getPacket().getModifier();
try {
Player observer = event.getPlayer();
StructureModifier<Entity> 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<WatchableObject>) 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<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)));
}
} 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<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) {
e.printStackTrace();
}
}
});
getCommand("disguise").setExecutor(new DisguiseCommand());
getCommand("undisguise").setExecutor(new UndisguiseCommand());
}