2013-05-17 23:05:19 +02:00
|
|
|
package me.libraryaddict.disguise;
|
|
|
|
|
2013-06-01 08:35:31 +02:00
|
|
|
import java.util.HashMap;
|
2013-05-17 23:05:19 +02:00
|
|
|
import me.libraryaddict.disguise.DisguiseTypes.Disguise;
|
2013-05-29 00:29:36 +02:00
|
|
|
import me.libraryaddict.disguise.DisguiseTypes.DisguiseSound;
|
|
|
|
import me.libraryaddict.disguise.DisguiseTypes.DisguiseSound.SoundType;
|
2013-07-09 04:51:35 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.Block;
|
|
|
|
import net.minecraft.server.v1_6_R2.EntityPlayer;
|
|
|
|
import net.minecraft.server.v1_6_R2.EntityTrackerEntry;
|
|
|
|
import net.minecraft.server.v1_6_R2.World;
|
|
|
|
import net.minecraft.server.v1_6_R2.WorldServer;
|
2013-05-29 00:29:36 +02:00
|
|
|
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Sound;
|
2013-07-09 04:51:35 +02:00
|
|
|
import org.bukkit.craftbukkit.v1_6_R2.CraftSound;
|
|
|
|
import org.bukkit.craftbukkit.v1_6_R2.entity.CraftEntity;
|
|
|
|
import org.bukkit.craftbukkit.v1_6_R2.entity.CraftLivingEntity;
|
2013-05-29 00:29:36 +02:00
|
|
|
import org.bukkit.entity.Entity;
|
2013-05-29 19:17:48 +02:00
|
|
|
import org.bukkit.entity.LivingEntity;
|
2013-05-17 23:05:19 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2013-05-29 00:29:36 +02:00
|
|
|
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;
|
2013-05-17 23:05:19 +02:00
|
|
|
|
|
|
|
public class DisguiseAPI {
|
|
|
|
|
2013-06-01 08:35:31 +02:00
|
|
|
private static HashMap<Object, Disguise> disguises = new HashMap<Object, Disguise>();
|
2013-05-29 00:29:36 +02:00
|
|
|
private static PacketListener packetListener;
|
|
|
|
private static JavaPlugin plugin;
|
2013-05-29 00:52:54 +02:00
|
|
|
private static boolean soundsEnabled;
|
|
|
|
|
2013-06-22 22:58:53 +02:00
|
|
|
private synchronized static Disguise access(Object obj, Disguise... object) {
|
|
|
|
if (object.length == 0)
|
|
|
|
return disguises.get(obj);
|
|
|
|
if (object[0] == null)
|
2013-06-01 08:35:31 +02:00
|
|
|
disguises.remove(obj);
|
|
|
|
else
|
2013-06-22 22:58:53 +02:00
|
|
|
disguises.put(obj, object[0]);
|
|
|
|
return null;
|
2013-06-01 08:35:31 +02:00
|
|
|
}
|
|
|
|
|
2013-05-29 00:52:54 +02:00
|
|
|
/**
|
|
|
|
* @param Player
|
|
|
|
* - The player to disguise
|
|
|
|
* @param Disguise
|
|
|
|
* - The disguise to wear
|
|
|
|
*/
|
|
|
|
public static void disguiseToAll(Entity entity, Disguise disguise) {
|
2013-06-01 08:35:31 +02:00
|
|
|
if (disguise == null)
|
|
|
|
return;
|
2013-07-16 07:23:38 +02:00
|
|
|
if (disguise.getWatcher() != null)
|
|
|
|
disguise = disguise.clone();
|
2013-06-01 08:35:31 +02:00
|
|
|
put(entity instanceof Player ? ((Player) entity).getName() : entity.getUniqueId(), disguise);
|
2013-05-29 19:17:48 +02:00
|
|
|
disguise.constructWatcher(entity.getType(), entity.getEntityId());
|
2013-05-29 00:52:54 +02:00
|
|
|
refresh(entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void enableSounds(boolean isSoundsEnabled) {
|
|
|
|
if (soundsEnabled != isSoundsEnabled) {
|
|
|
|
soundsEnabled = isSoundsEnabled;
|
|
|
|
if (soundsEnabled) {
|
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(packetListener);
|
|
|
|
} else {
|
|
|
|
ProtocolLibrary.getProtocolManager().removePacketListener(packetListener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-06 17:43:59 +02:00
|
|
|
private static Disguise get(Object obj) {
|
|
|
|
return access(obj);
|
|
|
|
}
|
|
|
|
|
2013-05-29 00:52:54 +02:00
|
|
|
/**
|
|
|
|
* @param Disguiser
|
|
|
|
* @return Disguise
|
|
|
|
*/
|
|
|
|
public static Disguise getDisguise(Object disguiser) {
|
|
|
|
if (disguiser instanceof Entity) {
|
|
|
|
if (disguiser instanceof Player)
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(((Player) disguiser).getName());
|
2013-05-29 00:52:54 +02:00
|
|
|
else
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(((Entity) disguiser).getUniqueId());
|
2013-05-29 00:52:54 +02:00
|
|
|
}
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(disguiser);
|
2013-05-29 00:52:54 +02:00
|
|
|
}
|
2013-05-29 00:29:36 +02:00
|
|
|
|
|
|
|
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) {
|
2013-05-29 20:20:50 +02:00
|
|
|
if (entity instanceof LivingEntity && ((LivingEntity) entity).getHealth() == 0) {
|
2013-05-29 19:17:48 +02:00
|
|
|
soundType = SoundType.DEATH;
|
|
|
|
} else {
|
|
|
|
boolean hasInvun = false;
|
|
|
|
if (entity instanceof LivingEntity) {
|
2013-07-09 04:51:35 +02:00
|
|
|
net.minecraft.server.v1_6_R2.EntityLiving e = ((CraftLivingEntity) entity)
|
2013-05-29 19:17:48 +02:00
|
|
|
.getHandle();
|
2013-07-02 05:29:12 +02:00
|
|
|
hasInvun = (e.noDamageTicks == e.maxNoDamageTicks);
|
2013-05-29 19:17:48 +02:00
|
|
|
} else {
|
2013-07-09 04:51:35 +02:00
|
|
|
net.minecraft.server.v1_6_R2.Entity e = ((CraftEntity) entity).getHandle();
|
2013-05-29 19:17:48 +02:00
|
|
|
hasInvun = e.isInvulnerable();
|
|
|
|
}
|
|
|
|
soundType = disSound.getType(soundName, !hasInvun);
|
|
|
|
}
|
2013-05-29 00:29:36 +02:00
|
|
|
if (soundType != null) {
|
|
|
|
disguisedEntity = entity;
|
|
|
|
break;
|
|
|
|
}
|
2013-06-23 18:01:57 +02:00
|
|
|
} /*else {
|
2013-05-30 16:31:18 +02:00
|
|
|
soundType = null;
|
2013-05-29 00:29:36 +02:00
|
|
|
disguisedEntity = entity;
|
|
|
|
break;
|
2013-07-02 05:29:12 +02:00
|
|
|
}*/
|
2013-05-29 00:29:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (disguisedEntity != null) {
|
2013-05-29 19:17:48 +02:00
|
|
|
Disguise disguise = DisguiseAPI.getDisguise(disguisedEntity);
|
|
|
|
if (disguise.replaceSounds()) {
|
|
|
|
Sound sound = null;
|
|
|
|
DisguiseSound dSound = DisguiseSound.getType(disguise.getType().name());
|
2013-05-30 16:31:18 +02:00
|
|
|
if (dSound != null && soundType != null)
|
2013-05-29 19:17:48 +02:00
|
|
|
sound = dSound.getSound(soundType);
|
|
|
|
if (sound == null) {
|
|
|
|
event.setCancelled(true);
|
2013-05-29 00:29:36 +02:00
|
|
|
} else {
|
2013-05-29 19:17:48 +02:00
|
|
|
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));
|
|
|
|
}
|
2013-05-29 00:29:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2013-05-17 23:05:19 +02:00
|
|
|
|
|
|
|
/**
|
2013-05-29 00:52:54 +02:00
|
|
|
* @param Disguiser
|
|
|
|
* @return boolean - If the disguiser is disguised
|
2013-05-17 23:05:19 +02:00
|
|
|
*/
|
2013-05-29 00:52:54 +02:00
|
|
|
public static boolean isDisguised(Object disguiser) {
|
|
|
|
if (disguiser instanceof Entity) {
|
|
|
|
if (disguiser instanceof Player)
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(((Player) disguiser).getName()) != null;
|
2013-05-29 00:52:54 +02:00
|
|
|
else
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(((Entity) disguiser).getUniqueId()) != null;
|
2013-05-29 00:52:54 +02:00
|
|
|
}
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(disguiser) != null;
|
2013-05-17 23:05:19 +02:00
|
|
|
}
|
|
|
|
|
2013-07-06 17:43:59 +02:00
|
|
|
private static void put(Object obj, Disguise disguise) {
|
|
|
|
access(obj, disguise);
|
|
|
|
}
|
|
|
|
|
2013-05-30 16:31:18 +02:00
|
|
|
/**
|
|
|
|
* @param Resends
|
|
|
|
* the entity to all the watching players, which is where the magic begins
|
|
|
|
*/
|
2013-05-29 00:29:36 +02:00
|
|
|
private static void refresh(Entity entity) {
|
|
|
|
EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ((CraftEntity) entity).getHandle().world).tracker.trackedEntities
|
|
|
|
.get(entity.getEntityId());
|
|
|
|
if (entry != null) {
|
2013-05-29 19:17:48 +02:00
|
|
|
EntityPlayer[] players = (EntityPlayer[]) entry.trackedPlayers.toArray(new EntityPlayer[entry.trackedPlayers.size()]);
|
2013-05-29 16:25:00 +02:00
|
|
|
for (EntityPlayer player : players) {
|
2013-05-29 01:00:31 +02:00
|
|
|
if (entity instanceof Player && !player.getBukkitEntity().canSee((Player) entity))
|
|
|
|
continue;
|
2013-05-29 00:29:36 +02:00
|
|
|
entry.clear(player);
|
|
|
|
entry.updatePlayer(player);
|
|
|
|
}
|
|
|
|
}
|
2013-05-17 23:05:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Disguiser
|
|
|
|
* - Undisguises him
|
|
|
|
*/
|
2013-05-29 00:29:36 +02:00
|
|
|
public static void undisguiseToAll(Entity entity) {
|
2013-06-01 08:35:31 +02:00
|
|
|
put(entity instanceof Player ? ((Player) entity).getName() : entity.getUniqueId(), null);
|
2013-05-29 00:29:36 +02:00
|
|
|
refresh(entity);
|
2013-05-17 23:05:19 +02:00
|
|
|
}
|
|
|
|
}
|