2013-05-17 23:05:19 +02:00
|
|
|
package me.libraryaddict.disguise;
|
|
|
|
|
2013-07-30 02:44:00 +02:00
|
|
|
import java.lang.reflect.Field;
|
2013-07-22 15:33:58 +02:00
|
|
|
import java.lang.reflect.InvocationTargetException;
|
2013-07-30 02:44:00 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
2013-06-01 08:35:31 +02:00
|
|
|
import java.util.HashMap;
|
2013-07-30 02:44:00 +02:00
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
2013-07-22 15:33:58 +02:00
|
|
|
import java.util.Random;
|
|
|
|
|
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-30 02:44:00 +02:00
|
|
|
import me.libraryaddict.disguise.DisguiseTypes.DisguiseType;
|
2013-07-22 15:33:58 +02:00
|
|
|
import me.libraryaddict.disguise.DisguiseTypes.MobDisguise;
|
2013-07-24 02:16:54 +02:00
|
|
|
import me.libraryaddict.disguise.Events.DisguisedEvent;
|
|
|
|
import me.libraryaddict.disguise.Events.RedisguisedEvent;
|
|
|
|
import me.libraryaddict.disguise.Events.UndisguisedEvent;
|
2013-07-30 02:44:00 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.AttributeMapServer;
|
2013-07-09 04:51:35 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.Block;
|
2013-07-30 02:44:00 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.EntityHuman;
|
|
|
|
import net.minecraft.server.v1_6_R2.EntityInsentient;
|
|
|
|
import net.minecraft.server.v1_6_R2.EntityLiving;
|
2013-07-09 04:51:35 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.EntityPlayer;
|
|
|
|
import net.minecraft.server.v1_6_R2.EntityTrackerEntry;
|
2013-07-30 02:44:00 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.ItemStack;
|
|
|
|
import net.minecraft.server.v1_6_R2.MobEffect;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet17EntityLocationAction;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet20NamedEntitySpawn;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet28EntityVelocity;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet35EntityHeadRotation;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet39AttachEntity;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet40EntityMetadata;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet41MobEffect;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet44UpdateAttributes;
|
|
|
|
import net.minecraft.server.v1_6_R2.Packet5EntityEquipment;
|
|
|
|
import net.minecraft.server.v1_6_R2.WatchableObject;
|
2013-07-09 04:51:35 +02:00
|
|
|
import net.minecraft.server.v1_6_R2.World;
|
|
|
|
import net.minecraft.server.v1_6_R2.WorldServer;
|
2013-05-29 00:29:36 +02:00
|
|
|
|
2013-07-31 07:12:39 +02:00
|
|
|
import org.apache.commons.lang.Validate;
|
2013-07-24 02:16:54 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2013-05-29 00:29:36 +02:00
|
|
|
import org.bukkit.Location;
|
2013-07-09 04:51:35 +02:00
|
|
|
import org.bukkit.craftbukkit.v1_6_R2.entity.CraftEntity;
|
|
|
|
import org.bukkit.craftbukkit.v1_6_R2.entity.CraftLivingEntity;
|
2013-07-30 02:44:00 +02:00
|
|
|
import org.bukkit.craftbukkit.v1_6_R2.entity.CraftPlayer;
|
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 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;
|
2013-07-22 15:33:58 +02:00
|
|
|
import com.comphenix.protocol.events.PacketContainer;
|
2013-05-29 00:29:36 +02:00
|
|
|
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-07-21 05:17:21 +02:00
|
|
|
private static HashMap<Entity, Disguise> disguises = new HashMap<Entity, Disguise>();
|
2013-07-30 02:44:00 +02:00
|
|
|
private static LibsDisguises libsDisguises;
|
2013-05-29 00:29:36 +02:00
|
|
|
private static PacketListener packetListener;
|
2013-07-21 05:17:21 +02:00
|
|
|
private static boolean sendVelocity;
|
2013-05-29 00:52:54 +02:00
|
|
|
private static boolean soundsEnabled;
|
2013-07-31 07:12:39 +02:00
|
|
|
private static HashMap<Integer, Integer> selfDisguisesIds = new HashMap<Integer, Integer>();
|
2013-07-30 02:44:00 +02:00
|
|
|
private static boolean viewDisguises;
|
2013-07-31 07:46:24 +02:00
|
|
|
private static boolean hearSelfDisguise;
|
2013-07-30 02:44:00 +02:00
|
|
|
private static PacketListener viewDisguisesListener;
|
2013-05-29 00:52:54 +02:00
|
|
|
|
2013-07-21 05:17:21 +02:00
|
|
|
private synchronized static Disguise access(Entity entity, Disguise... args) {
|
2013-07-30 02:44:00 +02:00
|
|
|
if (args.length == 0) {
|
|
|
|
if (disguises.containsKey(entity))
|
|
|
|
return disguises.get(entity);
|
|
|
|
return null;
|
|
|
|
}
|
2013-07-21 05:17:21 +02:00
|
|
|
if (args[0] == null)
|
|
|
|
disguises.remove(entity);
|
2013-06-01 08:35:31 +02:00
|
|
|
else
|
2013-07-21 05:17:21 +02:00
|
|
|
disguises.put(entity, args[0]);
|
2013-06-22 22:58:53 +02:00
|
|
|
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-21 05:17:21 +02:00
|
|
|
Disguise oldDisguise = getDisguise(entity);
|
2013-07-24 02:16:54 +02:00
|
|
|
if (oldDisguise != null) {
|
|
|
|
RedisguisedEvent event = new RedisguisedEvent(entity, oldDisguise, disguise);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled())
|
|
|
|
return;
|
2013-07-21 05:17:21 +02:00
|
|
|
oldDisguise.getScheduler().cancel();
|
2013-07-24 02:16:54 +02:00
|
|
|
} else {
|
|
|
|
DisguisedEvent event = new DisguisedEvent(entity, disguise);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled())
|
|
|
|
return;
|
|
|
|
}
|
2013-07-28 00:58:21 +02:00
|
|
|
|
|
|
|
if (disguise.getEntity() != entity) {
|
|
|
|
if (disguise.getWatcher() != null) {
|
|
|
|
disguise = disguise.clone();
|
|
|
|
}
|
2013-07-29 01:21:42 +02:00
|
|
|
disguise.constructWatcher(entity);
|
2013-07-28 00:58:21 +02:00
|
|
|
}
|
2013-07-21 05:17:21 +02:00
|
|
|
put(entity, disguise);
|
2013-05-29 00:52:54 +02:00
|
|
|
refresh(entity);
|
2013-07-30 02:44:00 +02:00
|
|
|
if (entity instanceof Player)
|
|
|
|
setupPlayer((Player) entity);
|
2013-05-29 00:52:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void enableSounds(boolean isSoundsEnabled) {
|
|
|
|
if (soundsEnabled != isSoundsEnabled) {
|
|
|
|
soundsEnabled = isSoundsEnabled;
|
|
|
|
if (soundsEnabled) {
|
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(packetListener);
|
|
|
|
} else {
|
|
|
|
ProtocolLibrary.getProtocolManager().removePacketListener(packetListener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-31 07:46:24 +02:00
|
|
|
public static void setHearSelfDisguise(boolean replaceSound) {
|
|
|
|
if (hearSelfDisguise != replaceSound) {
|
|
|
|
hearSelfDisguise = replaceSound;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean canHearSelfDisguise() {
|
|
|
|
return hearSelfDisguise;
|
|
|
|
}
|
|
|
|
|
2013-07-21 05:17:21 +02:00
|
|
|
private static Disguise get(Entity obj) {
|
2013-07-06 17:43:59 +02:00
|
|
|
return access(obj);
|
|
|
|
}
|
|
|
|
|
2013-05-29 00:52:54 +02:00
|
|
|
/**
|
|
|
|
* @param Disguiser
|
|
|
|
* @return Disguise
|
|
|
|
*/
|
2013-07-21 05:17:21 +02:00
|
|
|
public static Disguise getDisguise(Entity disguiser) {
|
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
|
|
|
|
2013-07-21 05:17:21 +02:00
|
|
|
@Deprecated
|
|
|
|
public static Disguise getDisguise(Object disguiser) {
|
|
|
|
return get((Entity) disguiser);
|
|
|
|
}
|
|
|
|
|
2013-07-30 02:44:00 +02:00
|
|
|
public static int getFakeDisguise(int id) {
|
2013-07-31 07:12:39 +02:00
|
|
|
if (selfDisguisesIds.containsKey(id))
|
|
|
|
return selfDisguisesIds.get(id);
|
2013-07-30 02:44:00 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static void init(LibsDisguises mainPlugin) {
|
|
|
|
libsDisguises = mainPlugin;
|
|
|
|
packetListener = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL,
|
2013-07-22 15:33:58 +02:00
|
|
|
Packets.Server.NAMED_SOUND_EFFECT, Packets.Server.ENTITY_STATUS) {
|
2013-05-29 00:29:36 +02:00
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent event) {
|
|
|
|
StructureModifier<Object> mods = event.getPacket().getModifier();
|
2013-07-22 15:33:58 +02:00
|
|
|
Player observer = event.getPlayer();
|
|
|
|
if (event.getPacketID() == Packets.Server.NAMED_SOUND_EFFECT) {
|
2013-05-29 00:29:36 +02:00
|
|
|
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;
|
2013-07-22 15:33:58 +02:00
|
|
|
DisguiseSound entitySound = null;
|
2013-05-29 00:29:36 +02:00
|
|
|
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)) {
|
2013-07-22 15:33:58 +02:00
|
|
|
entitySound = DisguiseSound.getType(entity.getType().name());
|
|
|
|
if (entitySound != 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();
|
|
|
|
}
|
2013-07-22 15:33:58 +02:00
|
|
|
soundType = entitySound.getType(soundName, !hasInvun);
|
2013-05-29 19:17:48 +02:00
|
|
|
}
|
2013-05-29 00:29:36 +02:00
|
|
|
if (soundType != null) {
|
|
|
|
disguisedEntity = entity;
|
|
|
|
break;
|
|
|
|
}
|
2013-07-22 15:33:58 +02:00
|
|
|
}
|
2013-05-29 00:29:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-07-31 07:46:24 +02:00
|
|
|
if (disguisedEntity != null && (hearSelfDisguise || disguisedEntity != event.getPlayer())) {
|
2013-05-29 19:17:48 +02:00
|
|
|
Disguise disguise = DisguiseAPI.getDisguise(disguisedEntity);
|
|
|
|
if (disguise.replaceSounds()) {
|
2013-07-22 15:33:58 +02:00
|
|
|
String sound = null;
|
2013-05-29 19:17:48 +02:00
|
|
|
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-07-22 15:33:58 +02:00
|
|
|
if (sound.equals("step.grass")) {
|
2013-05-29 19:17:48 +02:00
|
|
|
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 {
|
2013-07-22 15:33:58 +02:00
|
|
|
mods.write(0, sound);
|
|
|
|
// Time to change the pitch and volume
|
|
|
|
if (soundType == SoundType.HURT || soundType == SoundType.DEATH
|
|
|
|
|| soundType == SoundType.IDLE) {
|
|
|
|
// If the volume is the default
|
|
|
|
if (soundType != SoundType.IDLE
|
|
|
|
&& ((Float) mods.read(4)).equals(entitySound.getDamageSoundVolume())) {
|
2013-07-22 20:38:54 +02:00
|
|
|
mods.write(4, dSound.getDamageSoundVolume());
|
2013-07-22 15:33:58 +02:00
|
|
|
}
|
|
|
|
// Here I assume its the default pitch as I can't calculate if its real.
|
2013-07-22 20:38:54 +02:00
|
|
|
if (disguise instanceof MobDisguise && disguisedEntity instanceof LivingEntity
|
|
|
|
&& ((MobDisguise) disguise).doesDisguiseAge()) {
|
2013-07-22 19:15:45 +02:00
|
|
|
boolean baby = ((CraftLivingEntity) disguisedEntity).getHandle().isBaby();
|
|
|
|
if (((MobDisguise) disguise).isAdult() == baby) {
|
|
|
|
|
|
|
|
float pitch = (Integer) mods.read(5);
|
|
|
|
if (baby) {
|
|
|
|
// If the pitch is not the expected
|
|
|
|
if (pitch > 97 || pitch < 111)
|
|
|
|
return;
|
|
|
|
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.5F;
|
|
|
|
// Min = 1.5
|
|
|
|
// Cap = 97.5
|
|
|
|
// Max = 1.7
|
|
|
|
// Cap = 110.5
|
|
|
|
} else {
|
|
|
|
// If the pitch is not the expected
|
|
|
|
if (pitch >= 63 || pitch <= 76)
|
|
|
|
return;
|
|
|
|
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.0F;
|
|
|
|
// Min = 1
|
|
|
|
// Cap = 63
|
|
|
|
// Max = 1.2
|
|
|
|
// Cap = 75.6
|
|
|
|
}
|
|
|
|
pitch *= 63;
|
|
|
|
if (pitch < 0)
|
|
|
|
pitch = 0;
|
|
|
|
if (pitch > 255)
|
|
|
|
pitch = 255;
|
|
|
|
mods.write(5, (int) pitch);
|
|
|
|
}
|
2013-07-22 15:33:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (event.getPacketID() == Packets.Server.ENTITY_STATUS) {
|
|
|
|
if ((Byte) mods.read(1) == 2) {
|
|
|
|
// It made a damage animation
|
|
|
|
Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0);
|
|
|
|
Disguise disguise = getDisguise(entity);
|
2013-07-31 07:46:24 +02:00
|
|
|
if (hearSelfDisguise || entity != event.getPlayer()) {
|
|
|
|
if (disguise != null) {
|
|
|
|
DisguiseSound disSound = DisguiseSound.getType(entity.getType().name());
|
|
|
|
if (disSound == null)
|
|
|
|
return;
|
|
|
|
SoundType soundType = null;
|
|
|
|
if (entity instanceof LivingEntity && ((LivingEntity) entity).getHealth() == 0) {
|
|
|
|
soundType = SoundType.DEATH;
|
|
|
|
} else {
|
|
|
|
soundType = SoundType.HURT;
|
|
|
|
}
|
|
|
|
if (disSound.getSound(soundType) == null
|
|
|
|
|| (hearSelfDisguise && entity == event.getPlayer() && (soundType == SoundType.HURT || soundType == SoundType.DEATH))) {
|
|
|
|
disSound = DisguiseSound.getType(disguise.getType().name());
|
|
|
|
if (disSound != null) {
|
|
|
|
String sound = disSound.getSound(soundType);
|
|
|
|
if (sound != null) {
|
|
|
|
Location loc = entity.getLocation();
|
|
|
|
PacketContainer packet = new PacketContainer(Packets.Server.NAMED_SOUND_EFFECT);
|
|
|
|
mods = packet.getModifier();
|
|
|
|
mods.write(0, sound);
|
|
|
|
mods.write(1, (int) (loc.getX() * 8D));
|
|
|
|
mods.write(2, (int) (loc.getY() * 8D));
|
|
|
|
mods.write(3, (int) (loc.getZ() * 8D));
|
|
|
|
mods.write(4, disSound.getDamageSoundVolume());
|
|
|
|
float pitch;
|
|
|
|
if (disguise instanceof MobDisguise && !((MobDisguise) disguise).isAdult()) {
|
|
|
|
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.5F;
|
|
|
|
} else
|
|
|
|
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.0F;
|
|
|
|
if (disguise.getType() == DisguiseType.BAT)
|
|
|
|
pitch *= 95F;
|
|
|
|
pitch *= 63;
|
|
|
|
if (pitch < 0)
|
|
|
|
pitch = 0;
|
|
|
|
if (pitch > 255)
|
|
|
|
pitch = 255;
|
|
|
|
mods.write(5, (int) pitch);
|
|
|
|
try {
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet);
|
|
|
|
} catch (InvocationTargetException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2013-07-22 15:33:58 +02:00
|
|
|
}
|
|
|
|
}
|
2013-05-29 19:17:48 +02:00
|
|
|
}
|
2013-05-29 00:29:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2013-07-30 02:44:00 +02:00
|
|
|
viewDisguisesListener = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.HIGHEST,
|
|
|
|
Packets.Server.NAMED_ENTITY_SPAWN, Packets.Server.ATTACH_ENTITY, Packets.Server.REL_ENTITY_MOVE,
|
|
|
|
Packets.Server.REL_ENTITY_MOVE_LOOK, Packets.Server.ENTITY_LOOK, Packets.Server.ENTITY_TELEPORT,
|
|
|
|
Packets.Server.ENTITY_HEAD_ROTATION, Packets.Server.ENTITY_METADATA, Packets.Server.ENTITY_EQUIPMENT,
|
|
|
|
Packets.Server.ARM_ANIMATION, Packets.Server.ENTITY_LOCATION_ACTION, Packets.Server.MOB_EFFECT,
|
2013-07-31 07:12:39 +02:00
|
|
|
Packets.Server.ENTITY_STATUS, Packets.Server.ENTITY_VELOCITY, Packets.Server.UPDATE_ATTRIBUTES) {
|
2013-07-30 02:44:00 +02:00
|
|
|
@Override
|
|
|
|
public void onPacketSending(PacketEvent event) {
|
|
|
|
StructureModifier<Entity> entityModifer = event.getPacket().getEntityModifier(event.getPlayer().getWorld());
|
|
|
|
org.bukkit.entity.Entity entity = entityModifer.read(0);
|
2013-07-31 07:12:39 +02:00
|
|
|
if (entity == event.getPlayer() && selfDisguisesIds.containsKey(entity.getEntityId())) {
|
2013-07-30 05:31:07 +02:00
|
|
|
PacketContainer[] packets = libsDisguises.transformPacket(event.getPacket(), event.getPlayer());
|
2013-07-30 02:44:00 +02:00
|
|
|
try {
|
|
|
|
for (PacketContainer packet : packets) {
|
|
|
|
if (packet.equals(event.getPacket()))
|
|
|
|
packet = packet.deepClone();
|
2013-07-31 07:12:39 +02:00
|
|
|
packet.getModifier().write(0, selfDisguisesIds.get(entity.getEntityId()));
|
2013-07-30 02:44:00 +02:00
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false);
|
|
|
|
}
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.getPacketID() == Packets.Server.ENTITY_METADATA) {
|
|
|
|
event.setPacket(event.getPacket().deepClone());
|
|
|
|
StructureModifier<Object> mods = event.getPacket().getModifier();
|
|
|
|
Iterator<WatchableObject> itel = ((List<WatchableObject>) mods.read(1)).iterator();
|
|
|
|
while (itel.hasNext()) {
|
|
|
|
WatchableObject watch = itel.next();
|
|
|
|
if (watch.a() == 0) {
|
|
|
|
byte b = (Byte) watch.b();
|
|
|
|
byte a = (byte) (b | 1 << 5);
|
|
|
|
if ((b & 1 << 3) != 0)
|
|
|
|
a = (byte) (a | 1 << 3);
|
|
|
|
watch.a(a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (event.getPacketID()) {
|
|
|
|
case Packets.Server.NAMED_ENTITY_SPAWN:
|
|
|
|
case Packets.Server.ATTACH_ENTITY:
|
|
|
|
case Packets.Server.REL_ENTITY_MOVE:
|
|
|
|
case Packets.Server.REL_ENTITY_MOVE_LOOK:
|
|
|
|
case Packets.Server.ENTITY_LOOK:
|
|
|
|
case Packets.Server.ENTITY_TELEPORT:
|
|
|
|
case Packets.Server.ENTITY_HEAD_ROTATION:
|
|
|
|
case Packets.Server.MOB_EFFECT:
|
2013-07-30 05:31:07 +02:00
|
|
|
case Packets.Server.ENTITY_EQUIPMENT:
|
2013-07-30 02:44:00 +02:00
|
|
|
if (event.getPacketID() == Packets.Server.NAMED_ENTITY_SPAWN) {
|
|
|
|
PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_METADATA);
|
|
|
|
StructureModifier<Object> mods = packet.getModifier();
|
|
|
|
mods.write(0, entity.getEntityId());
|
|
|
|
List watchableList = new ArrayList();
|
|
|
|
byte b = (byte) (0 | 1 << 5);
|
|
|
|
if (event.getPlayer().isSprinting())
|
|
|
|
b = (byte) (b | 1 << 3);
|
|
|
|
watchableList.add(new WatchableObject(0, 0, b));
|
|
|
|
mods.write(1, watchableList);
|
|
|
|
try {
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
event.setCancelled(true);
|
|
|
|
break;
|
2013-07-31 07:46:24 +02:00
|
|
|
case Packets.Server.ENTITY_STATUS:
|
|
|
|
if (hearSelfDisguise && (Byte) event.getPacket().getModifier().read(1) == 2)
|
|
|
|
event.setCancelled(true);
|
|
|
|
break;
|
2013-07-30 02:44:00 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2013-05-29 00:29:36 +02:00
|
|
|
}
|
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-07-21 05:17:21 +02:00
|
|
|
public static boolean isDisguised(Entity disguiser) {
|
2013-06-01 08:35:31 +02:00
|
|
|
return get(disguiser) != null;
|
2013-05-17 23:05:19 +02:00
|
|
|
}
|
|
|
|
|
2013-07-21 05:17:21 +02:00
|
|
|
@Deprecated
|
|
|
|
public static boolean isDisguised(Object disguiser) {
|
|
|
|
return get((Entity) disguiser) != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isVelocitySent() {
|
|
|
|
return sendVelocity;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void put(Entity obj, Disguise disguise) {
|
2013-07-06 17:43:59 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2013-07-30 02:44:00 +02:00
|
|
|
private static void removeVisibleDisguise(Player player) {
|
2013-07-31 07:12:39 +02:00
|
|
|
if (selfDisguisesIds.containsKey(player.getEntityId())) {
|
2013-07-30 02:44:00 +02:00
|
|
|
PacketContainer packet = new PacketContainer(Packets.Server.DESTROY_ENTITY);
|
2013-07-31 07:12:39 +02:00
|
|
|
packet.getModifier().write(0, new int[] { selfDisguisesIds.get(player.getEntityId()) });
|
2013-07-30 02:44:00 +02:00
|
|
|
try {
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
2013-07-31 07:12:39 +02:00
|
|
|
selfDisguisesIds.remove(player.getEntityId());
|
2013-07-30 02:44:00 +02:00
|
|
|
}
|
|
|
|
EntityPlayer entityplayer = ((CraftPlayer) player).getHandle();
|
|
|
|
EntityTrackerEntry tracker = (EntityTrackerEntry) ((WorldServer) entityplayer.world).tracker.trackedEntities.get(player
|
|
|
|
.getEntityId());
|
2013-07-31 07:12:39 +02:00
|
|
|
if (tracker != null) {
|
|
|
|
tracker.trackedPlayers.remove(entityplayer);
|
|
|
|
}
|
2013-07-30 02:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static void setupPlayer(Player player) {
|
|
|
|
removeVisibleDisguise(player);
|
|
|
|
if (!viewDisguises())
|
|
|
|
return;
|
|
|
|
int id = 0;
|
|
|
|
try {
|
|
|
|
Field field = net.minecraft.server.v1_6_R2.Entity.class.getDeclaredField("entityCount");
|
|
|
|
field.setAccessible(true);
|
|
|
|
id = field.getInt(null);
|
|
|
|
field.set(null, id + 1);
|
2013-07-31 07:12:39 +02:00
|
|
|
selfDisguisesIds.put(player.getEntityId(), id);
|
2013-07-30 02:44:00 +02:00
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
EntityPlayer entityplayer = ((CraftPlayer) player).getHandle();
|
|
|
|
EntityTrackerEntry tracker = (EntityTrackerEntry) ((WorldServer) entityplayer.world).tracker.trackedEntities.get(player
|
|
|
|
.getEntityId());
|
2013-07-31 07:12:39 +02:00
|
|
|
Validate.notNull(tracker,
|
|
|
|
"If you are disguising as soon as they log in, please wait a tick or 2 for their EntityTracker to be constructed");
|
2013-07-30 02:44:00 +02:00
|
|
|
tracker.trackedPlayers.add(entityplayer);
|
|
|
|
|
|
|
|
// CraftBukkit end
|
|
|
|
Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) entityplayer);
|
|
|
|
entityplayer.playerConnection.sendPacket(packet);
|
|
|
|
if (!tracker.tracker.getDataWatcher().d()) {
|
2013-07-31 07:12:39 +02:00
|
|
|
entityplayer.playerConnection.sendPacket(new Packet40EntityMetadata(player.getEntityId(), tracker.tracker
|
|
|
|
.getDataWatcher(), true));
|
2013-07-30 02:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (tracker.tracker instanceof EntityLiving) {
|
|
|
|
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) tracker.tracker).aW();
|
|
|
|
Collection collection = attributemapserver.c();
|
|
|
|
|
|
|
|
if (!collection.isEmpty()) {
|
|
|
|
entityplayer.playerConnection.sendPacket(new Packet44UpdateAttributes(player.getEntityId(), collection));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tracker.j = tracker.tracker.motX;
|
|
|
|
tracker.k = tracker.tracker.motY;
|
|
|
|
tracker.l = tracker.tracker.motZ;
|
|
|
|
boolean isMoving = false;
|
|
|
|
try {
|
|
|
|
Field field = EntityTrackerEntry.class.getDeclaredField("isMoving");
|
|
|
|
field.setAccessible(true);
|
|
|
|
isMoving = field.getBoolean(tracker);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
if (isMoving) {
|
2013-07-31 07:12:39 +02:00
|
|
|
entityplayer.playerConnection.sendPacket(new Packet28EntityVelocity(player.getEntityId(), tracker.tracker.motX,
|
|
|
|
tracker.tracker.motY, tracker.tracker.motZ));
|
2013-07-30 02:44:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// CraftBukkit start
|
2013-07-30 05:31:07 +02:00
|
|
|
if (tracker.tracker.vehicle != null && player.getEntityId() > tracker.tracker.vehicle.id) {
|
2013-07-30 02:44:00 +02:00
|
|
|
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker, tracker.tracker.vehicle));
|
2013-07-30 05:31:07 +02:00
|
|
|
} else if (tracker.tracker.passenger != null && player.getEntityId() > tracker.tracker.passenger.id) {
|
2013-07-30 02:44:00 +02:00
|
|
|
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker.passenger, tracker.tracker));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tracker.tracker instanceof EntityInsentient && ((EntityInsentient) tracker.tracker).bI() != null) {
|
|
|
|
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(1, tracker.tracker,
|
|
|
|
((EntityInsentient) tracker.tracker).bI()));
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
|
|
|
|
if (tracker.tracker instanceof EntityLiving) {
|
|
|
|
for (int i = 0; i < 5; ++i) {
|
|
|
|
ItemStack itemstack = ((EntityLiving) tracker.tracker).getEquipment(i);
|
|
|
|
|
|
|
|
if (itemstack != null) {
|
2013-07-30 05:31:07 +02:00
|
|
|
entityplayer.playerConnection.sendPacket(new Packet5EntityEquipment(player.getEntityId(), i, itemstack));
|
2013-07-30 02:44:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tracker.tracker instanceof EntityHuman) {
|
|
|
|
EntityHuman entityhuman = (EntityHuman) tracker.tracker;
|
|
|
|
|
|
|
|
if (entityhuman.isSleeping()) {
|
|
|
|
entityplayer.playerConnection.sendPacket(new Packet17EntityLocationAction(tracker.tracker, 0, (int) Math
|
|
|
|
.floor(tracker.tracker.locX), (int) Math.floor(tracker.tracker.locY), (int) Math
|
|
|
|
.floor(tracker.tracker.locZ)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CraftBukkit start - Fix for nonsensical head yaw
|
|
|
|
tracker.i = (int) Math.floor(tracker.tracker.getHeadRotation() * 256.0F / 360.0F); // tracker.ao() should be
|
|
|
|
// getHeadRotation
|
2013-07-30 05:31:07 +02:00
|
|
|
tracker.broadcast(new Packet35EntityHeadRotation(player.getEntityId(), (byte) tracker.i));
|
2013-07-30 02:44:00 +02:00
|
|
|
// CraftBukkit end
|
|
|
|
|
|
|
|
if (tracker.tracker instanceof EntityLiving) {
|
|
|
|
EntityLiving entityliving = (EntityLiving) tracker.tracker;
|
|
|
|
Iterator iterator = entityliving.getEffects().iterator();
|
|
|
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
MobEffect mobeffect = (MobEffect) iterator.next();
|
|
|
|
|
2013-07-30 05:31:07 +02:00
|
|
|
entityplayer.playerConnection.sendPacket(new Packet41MobEffect(player.getEntityId(), mobeffect));
|
2013-07-30 02:44:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-21 05:17:21 +02:00
|
|
|
public static void setVelocitySent(boolean sendVelocityPackets) {
|
|
|
|
sendVelocity = sendVelocityPackets;
|
|
|
|
}
|
|
|
|
|
2013-07-30 02:44:00 +02:00
|
|
|
public static void setViewDisguises(boolean seeOwnDisguise) {
|
|
|
|
if (viewDisguises != seeOwnDisguise) {
|
|
|
|
viewDisguises = seeOwnDisguise;
|
|
|
|
if (viewDisguises) {
|
|
|
|
ProtocolLibrary.getProtocolManager().addPacketListener(viewDisguisesListener);
|
|
|
|
} else {
|
|
|
|
ProtocolLibrary.getProtocolManager().removePacketListener(viewDisguisesListener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-07-21 05:17:21 +02:00
|
|
|
Disguise disguise = getDisguise(entity);
|
|
|
|
if (disguise == null)
|
|
|
|
return;
|
2013-07-24 02:16:54 +02:00
|
|
|
UndisguisedEvent event = new UndisguisedEvent(entity, disguise);
|
|
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled())
|
|
|
|
return;
|
2013-07-21 05:17:21 +02:00
|
|
|
disguise.getScheduler().cancel();
|
|
|
|
put(entity, null);
|
|
|
|
if (entity.isValid()) {
|
|
|
|
refresh(entity);
|
|
|
|
}
|
2013-07-30 02:44:00 +02:00
|
|
|
if (entity instanceof Player)
|
|
|
|
removeVisibleDisguise((Player) entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean viewDisguises() {
|
|
|
|
return viewDisguises;
|
2013-05-17 23:05:19 +02:00
|
|
|
}
|
|
|
|
}
|