Test Commit

This commit is contained in:
Andrew 2013-10-04 12:51:29 +13:00
parent 9b9829073c
commit d230962e19
47 changed files with 505 additions and 113 deletions

@ -17,4 +17,10 @@ DisguiseSounds: true
HearSelfDisguise: false HearSelfDisguise: false
# Shall I send the velocity packets? I REALLY recommend you don't disable. # Shall I send the velocity packets? I REALLY recommend you don't disable.
# This is the only thing allowing the mobs to fly without glitching out. # This is the only thing allowing the mobs to fly without glitching out.
SendVelocity: true SendVelocity: true
# For self disguises, they need to have the armor and the held item removed
# Else they see floating armor, floating held items.
# However! This doesn't actually remove the armor!
# It just makes the client think the armor was removed so that it doesn't render it!
RemoveArmor: true
RemoveHeldItem: true

@ -238,6 +238,8 @@ public class DisguiseAPI {
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
// TODO Restore their currently held item
// TODO Restore their armor
} }
} }
@ -288,23 +290,6 @@ public class DisguiseAPI {
// If the disguised player can't see himself. Return // If the disguised player can't see himself. Return
if (!disguise.viewSelfDisguise()) if (!disguise.viewSelfDisguise())
return; return;
// Grab the entity player
EntityPlayer entityplayer = ((CraftPlayer) player).getHandle();
EntityTrackerEntry tracker = (EntityTrackerEntry) ((WorldServer) entityplayer.world).tracker.trackedEntities.get(player
.getEntityId());
if (tracker == null) {
// A check incase the tracker is null.
// If it is, then this method will be run again in one tick. Which is when it should be constructed.
// Else its going to run in a infinite loop hue hue hue..
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
setupPlayerFakeDisguise(disguise);
}
});
return;
}
// Add himself to his own entity tracker
tracker.trackedPlayers.add(entityplayer);
try { try {
// Grab the entity ID the fake disguise will use // Grab the entity ID the fake disguise will use
Field field = net.minecraft.server.v1_6_R3.Entity.class.getDeclaredField("entityCount"); Field field = net.minecraft.server.v1_6_R3.Entity.class.getDeclaredField("entityCount");
@ -316,81 +301,7 @@ public class DisguiseAPI {
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
// Send the player a packet with himself being spawned PacketsManager.sendSelfDisguise(player);
Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) entityplayer);
entityplayer.playerConnection.sendPacket(packet);
if (!tracker.tracker.getDataWatcher().d()) {
entityplayer.playerConnection.sendPacket(new Packet40EntityMetadata(player.getEntityId(), tracker.tracker
.getDataWatcher(), true));
}
// Send himself some entity attributes
if (tracker.tracker instanceof EntityLiving) {
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) tracker.tracker).aX();
Collection collection = attributemapserver.c();
if (!collection.isEmpty()) {
entityplayer.playerConnection.sendPacket(new Packet44UpdateAttributes(player.getEntityId(), collection));
}
}
// Why do we even have this?
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();
}
// Send the velocity packets
if (isMoving) {
entityplayer.playerConnection.sendPacket(new Packet28EntityVelocity(player.getEntityId(), tracker.tracker.motX,
tracker.tracker.motY, tracker.tracker.motZ));
}
// Why the hell would he even need this. Meh.
if (tracker.tracker.vehicle != null && player.getEntityId() > tracker.tracker.vehicle.id) {
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker, tracker.tracker.vehicle));
} else if (tracker.tracker.passenger != null && player.getEntityId() > tracker.tracker.passenger.id) {
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker.passenger, tracker.tracker));
}
if (tracker.tracker instanceof EntityInsentient && ((EntityInsentient) tracker.tracker).getLeashHolder() != null) {
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(1, tracker.tracker,
((EntityInsentient) tracker.tracker).getLeashHolder()));
}
// Resend the armor
for (int i = 0; i < 5; ++i) {
ItemStack itemstack = ((EntityLiving) tracker.tracker).getEquipment(i);
if (itemstack != null) {
entityplayer.playerConnection.sendPacket(new Packet5EntityEquipment(player.getEntityId(), i, itemstack));
}
}
// If the disguised is sleeping for w/e reason
if (entityplayer.isSleeping()) {
entityplayer.playerConnection
.sendPacket(new Packet17EntityLocationAction(entityplayer, 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
tracker.broadcast(new Packet35EntityHeadRotation(player.getEntityId(), (byte) tracker.i));
// CraftBukkit end
// Resend any active potion effects
Iterator iterator = entityplayer.getEffects().iterator();
while (iterator.hasNext()) {
MobEffect mobeffect = (MobEffect) iterator.next();
entityplayer.playerConnection.sendPacket(new Packet41MobEffect(player.getEntityId(), mobeffect));
}
} }
/** /**

@ -18,21 +18,39 @@ import me.libraryaddict.disguise.disguisetypes.MobDisguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.disguisetypes.Values; import me.libraryaddict.disguise.disguisetypes.Values;
import me.libraryaddict.disguise.disguisetypes.DisguiseSound.SoundType; import me.libraryaddict.disguise.disguisetypes.DisguiseSound.SoundType;
import net.minecraft.server.v1_6_R3.AttributeMapServer;
import net.minecraft.server.v1_6_R3.AttributeSnapshot; import net.minecraft.server.v1_6_R3.AttributeSnapshot;
import net.minecraft.server.v1_6_R3.Block; import net.minecraft.server.v1_6_R3.Block;
import net.minecraft.server.v1_6_R3.DataWatcher; import net.minecraft.server.v1_6_R3.DataWatcher;
import net.minecraft.server.v1_6_R3.EntityHuman;
import net.minecraft.server.v1_6_R3.EntityInsentient;
import net.minecraft.server.v1_6_R3.EntityLiving; import net.minecraft.server.v1_6_R3.EntityLiving;
import net.minecraft.server.v1_6_R3.EntityPlayer;
import net.minecraft.server.v1_6_R3.EntityTrackerEntry;
import net.minecraft.server.v1_6_R3.EnumArt; import net.minecraft.server.v1_6_R3.EnumArt;
import net.minecraft.server.v1_6_R3.EnumEntitySize; import net.minecraft.server.v1_6_R3.EnumEntitySize;
import net.minecraft.server.v1_6_R3.ItemStack; import net.minecraft.server.v1_6_R3.ItemStack;
import net.minecraft.server.v1_6_R3.MathHelper; import net.minecraft.server.v1_6_R3.MathHelper;
import net.minecraft.server.v1_6_R3.MobEffect;
import net.minecraft.server.v1_6_R3.Packet17EntityLocationAction;
import net.minecraft.server.v1_6_R3.Packet20NamedEntitySpawn;
import net.minecraft.server.v1_6_R3.Packet28EntityVelocity;
import net.minecraft.server.v1_6_R3.Packet35EntityHeadRotation;
import net.minecraft.server.v1_6_R3.Packet39AttachEntity;
import net.minecraft.server.v1_6_R3.Packet40EntityMetadata;
import net.minecraft.server.v1_6_R3.Packet41MobEffect;
import net.minecraft.server.v1_6_R3.Packet44UpdateAttributes;
import net.minecraft.server.v1_6_R3.Packet5EntityEquipment;
import net.minecraft.server.v1_6_R3.WatchableObject; import net.minecraft.server.v1_6_R3.WatchableObject;
import net.minecraft.server.v1_6_R3.World; import net.minecraft.server.v1_6_R3.World;
import net.minecraft.server.v1_6_R3.WorldServer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity; import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftLivingEntity; import org.bukkit.craftbukkit.v1_6_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_6_R3.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_6_R3.inventory.CraftItemStack;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -55,10 +73,14 @@ import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
public class PacketsManager { public class PacketsManager {
private static PacketListener inventoryListenerClient;
private static PacketListener inventoryListenerServer;
private static boolean inventoryModifierEnabled;
private static PacketListener soundsListener; private static PacketListener soundsListener;
private static boolean soundsListenerEnabled; private static boolean soundsListenerEnabled;
private static PacketListener viewDisguisesListener; private static PacketListener viewDisguisesListener;
private static boolean viewDisguisesListenerEnabled; private static boolean viewDisguisesListenerEnabled;
private static LibsDisguises libsDisguises;
protected static void addPacketListeners(final JavaPlugin libsDisguises) { protected static void addPacketListeners(final JavaPlugin libsDisguises) {
ProtocolManager manager = ProtocolLibrary.getProtocolManager(); ProtocolManager manager = ProtocolLibrary.getProtocolManager();
@ -101,7 +123,7 @@ public class PacketsManager {
}); });
// Now add a client listener to cancel them interacting with uninteractable disguised entitys. // Now add a client listener to cancel them interacting with uninteractable disguised entitys.
// You ain't supposed to be allowed to 'interact' with a item that cannot be clicked. // You ain't supposed to be allowed to 'interact' with a item that cannot be clicked.
// Kicks you for hacking. // Because it kicks you for hacking.
manager.addPacketListener(new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.NORMAL, manager.addPacketListener(new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.NORMAL,
Packets.Client.USE_ENTITY) { Packets.Client.USE_ENTITY) {
@Override @Override
@ -370,6 +392,9 @@ public class PacketsManager {
return value; return value;
} }
/**
* Get the Y level to add to the disguise for realism.
*/
private static double getYModifier(Entity entity, DisguiseType disguiseType) { private static double getYModifier(Entity entity, DisguiseType disguiseType) {
switch (disguiseType) { switch (disguiseType) {
case BAT: case BAT:
@ -400,7 +425,11 @@ public class PacketsManager {
return 0; return 0;
} }
protected static void init(JavaPlugin libsDisguises) { /**
* Creates the packet listeners
*/
protected static void init(LibsDisguises plugin) {
libsDisguises = plugin;
soundsListener = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL, soundsListener = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.NORMAL,
Packets.Server.NAMED_SOUND_EFFECT, Packets.Server.ENTITY_STATUS) { Packets.Server.NAMED_SOUND_EFFECT, Packets.Server.ENTITY_STATUS) {
@Override @Override
@ -652,12 +681,412 @@ public class PacketsManager {
} }
} }
}; };
// TODO Potentionally combine both listeners.
inventoryListenerServer = new PacketAdapter(libsDisguises, ConnectionSide.SERVER_SIDE, ListenerPriority.HIGHEST,
Packets.Server.SET_SLOT) {
@Override
public void onPacketSending(PacketEvent event) {
// If the inventory is the players inventory
if (event.getPacket().getIntegers().read(0) == 0) {
Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer());
// If the player is disguised, views self disguises and is hiding a item.
if (disguise != null && disguise.viewSelfDisguise()
&& (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) {
switch (event.getPacketID()) {
// If the server is setting the slot
// Need to set it to air if its in a place it shouldn't be.
// Things such as picking up a item, spawned in item. Plugin sets the item. etc. Will fire this
case Packets.Server.SET_SLOT: {
// The raw slot
// nms code has the start of the hotbar being 36.
int slot = event.getPacket().getIntegers().read(1);
Bukkit.broadcastMessage("Set slot: " + slot);
// If the slot is a armor slot
if (slot >= 5 && slot <= 8) {
if (disguise.isHidingArmorFromSelf()) {
// Get the bukkit armor slot!
int armorSlot = Math.abs((slot - 5) - 3);
org.bukkit.inventory.ItemStack item = event.getPlayer().getInventory().getArmorContents()[armorSlot];
if (item != null && item.getType() != Material.AIR) {
event.setPacket(event.getPacket().shallowClone());
event.getPacket().getModifier()
.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
}
}
// Else if its a hotbar slot
} else if (slot >= 36 && slot <= 44) {
if (disguise.isHidingHeldItemFromSelf()) {
int currentSlot = event.getPlayer().getInventory().getHeldItemSlot();
// Check if the player is on the same slot as the slot that its setting
if (slot == currentSlot + 36) {
org.bukkit.inventory.ItemStack item = event.getPlayer().getItemInHand();
if (item != null && item.getType() != Material.AIR) {
event.setPacket(event.getPacket().shallowClone());
event.getPacket().getModifier()
.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
}
}
}
}
break;
}
// Don't think that we will ever need this.
// We will see.
case Packets.Server.WINDOW_ITEMS: {
// TODO Find out how this works
// It seems to 'update' the inventory.. Screw you..
break;
}
default:
break;
}
}
}
}
};
// TODO Add a listener for player click event.
// Items placed do not have the server confirm it
// So I need to set the item slot
inventoryListenerClient = new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.HIGHEST,
Packets.Client.BLOCK_ITEM_SWITCH, Packets.Client.SET_CREATIVE_SLOT, Packets.Client.WINDOW_CLICK) {
@Override
public void onPacketReceiving(PacketEvent event) {
Disguise disguise = DisguiseAPI.getDisguise(event.getPlayer());
// If player is disguised, views self disguises and has a inventory modifier
if (disguise != null && disguise.viewSelfDisguise()
&& (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) {
switch (event.getPacketID()) {
// If they are in creative and clicked on a slot
case Packets.Client.SET_CREATIVE_SLOT: {
int slot = event.getPacket().getIntegers().read(0);
if (slot >= 5 && slot <= 8) {
if (disguise.isHidingArmorFromSelf()) {
int armorSlot = Math.abs(slot - 9);
org.bukkit.inventory.ItemStack item = event.getPlayer().getInventory().getArmorContents()[armorSlot];
if (item != null && item.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
} else if (slot >= 36 && slot <= 44) {
if (disguise.isHidingHeldItemFromSelf()) {
int currentSlot = event.getPlayer().getInventory().getHeldItemSlot();
if (slot + 36 == currentSlot) {
org.bukkit.inventory.ItemStack item = event.getPlayer().getItemInHand();
if (item != null && item.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet,
false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
break;
}
// If the player switched item, aka he moved from slot 1 to slot 2
// TODO Listen for this server sided, sometimes it may force him back to a old slot
// ^ But I think the client sends the packet again..
// This currently works fine
case Packets.Client.BLOCK_ITEM_SWITCH: {
if (disguise.isHidingHeldItemFromSelf()) {
// From logging, it seems that both bukkit and nms uses the same thing for the slot switching.
// 0 1 2 3 - 8
// If the packet is coming, then I need to replace the item they are switching to
// As for the old item, I need to restore it.
org.bukkit.inventory.ItemStack currentlyHeld = event.getPlayer().getItemInHand();
// If his old weapon isn't air
if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, event.getPlayer().getInventory().getHeldItemSlot() + 36);
mods.write(2, CraftItemStack.asNMSCopy(currentlyHeld));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
org.bukkit.inventory.ItemStack newHeld = event.getPlayer().getInventory()
.getItem(event.getPacket().getIntegers().read(0));
// If his new weapon isn't air either!
if (newHeld != null && newHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, event.getPacket().getIntegers().read(0) + 36);
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
break;
}
case Packets.Client.WINDOW_CLICK:
// Seems like the cases are never met..
// Probably slot mismatches again
{
int slot = event.getPacket().getIntegers().read(1);
org.bukkit.inventory.ItemStack clickedItem;
if (event.getPacket().getIntegers().read(3) == 1) {
// Its a shift click
clickedItem = event.getPacket().getItemModifier().read(0);
if (clickedItem != null && clickedItem.getType() != Material.AIR) {
org.bukkit.inventory.ItemStack armorItem = null;
int armorSlot = 0;
switch (clickedItem.getType()) {
case LEATHER_BOOTS:
case GOLD_BOOTS:
case CHAINMAIL_BOOTS:
case IRON_BOOTS:
case DIAMOND_BOOTS:
armorSlot = 8;
armorItem = event.getPlayer().getInventory().getBoots();
break;
case LEATHER_LEGGINGS:
case GOLD_LEGGINGS:
case CHAINMAIL_LEGGINGS:
case IRON_LEGGINGS:
case DIAMOND_LEGGINGS:
armorSlot = 7;
armorItem = event.getPlayer().getInventory().getLeggings();
break;
case LEATHER_CHESTPLATE:
case GOLD_CHESTPLATE:
case CHAINMAIL_CHESTPLATE:
case IRON_CHESTPLATE:
case DIAMOND_CHESTPLATE:
armorSlot = 6;
armorItem = event.getPlayer().getInventory().getChestplate();
break;
case LEATHER_HELMET:
case GOLD_HELMET:
case CHAINMAIL_HELMET:
case IRON_HELMET:
case DIAMOND_HELMET:
armorSlot = 5;
armorItem = event.getPlayer().getInventory().getHelmet();
break;
default:
break;
}
// Its a piece of armor they clicked on..
if (armorSlot > 0) {
if (armorItem == null || armorItem.getType() == Material.AIR) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, armorSlot);
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet,
false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
} else {
org.bukkit.inventory.ItemStack heldItem = event.getPlayer().getItemInHand();
// If its not a piece of armor they clicked on
// Then it can't go into a armor slot
// So it has to go into the held item..
// But the held item is full.
if (heldItem == null || heldItem.getType() == Material.AIR) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, 36 + event.getPlayer().getInventory().getHeldItemSlot());
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet,
false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
return;
} else {
// If its not a player inventory click
// Shift clicking is exempted for the item in hand..
if (event.getPacket().getIntegers().read(0) != 0) {
return;
}
clickedItem = event.getPlayer().getItemOnCursor();
}
if (clickedItem != null && clickedItem.getType() != Material.AIR) {
// If the slot is a armor slot
if (slot >= 5 && slot <= 8) {
if (disguise.isHidingArmorFromSelf()) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
// Else if its a hotbar slot
} else if (slot >= 36 && slot <= 44) {
if (disguise.isHidingHeldItemFromSelf()) {
int currentSlot = event.getPlayer().getInventory().getHeldItemSlot();
// Check if the player is on the same slot as the slot that its setting
if (slot == currentSlot + 36) {
PacketContainer packet = new PacketContainer(Packets.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(2, CraftItemStack.asNMSCopy(new org.bukkit.inventory.ItemStack(0)));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet,
false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
break;
}
default:
break;
}
}
}
};
}
/**
* Sends the self disguise to the player
*/
public static void sendSelfDisguise(final Player player) {
EntityPlayer entityplayer = ((CraftPlayer) player).getHandle();
EntityTrackerEntry tracker = (EntityTrackerEntry) ((WorldServer) entityplayer.world).tracker.trackedEntities.get(player
.getEntityId());
if (tracker == null) {
// A check incase the tracker is null.
// If it is, then this method will be run again in one tick. Which is when it should be constructed.
// Else its going to run in a infinite loop hue hue hue..
Bukkit.getScheduler().scheduleSyncDelayedTask(libsDisguises, new Runnable() {
public void run() {
sendSelfDisguise(player);
}
});
return;
}
// Add himself to his own entity tracker
tracker.trackedPlayers.add(entityplayer);
// Send the player a packet with himself being spawned
Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) entityplayer);
entityplayer.playerConnection.sendPacket(packet);
if (!tracker.tracker.getDataWatcher().d()) {
entityplayer.playerConnection.sendPacket(new Packet40EntityMetadata(player.getEntityId(), tracker.tracker
.getDataWatcher(), true));
}
// Send himself some entity attributes
if (tracker.tracker instanceof EntityLiving) {
AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) tracker.tracker).aX();
Collection collection = attributemapserver.c();
if (!collection.isEmpty()) {
entityplayer.playerConnection.sendPacket(new Packet44UpdateAttributes(player.getEntityId(), collection));
}
}
// Why do we even have this?
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();
}
// Send the velocity packets
if (isMoving) {
entityplayer.playerConnection.sendPacket(new Packet28EntityVelocity(player.getEntityId(), tracker.tracker.motX,
tracker.tracker.motY, tracker.tracker.motZ));
}
// Why the hell would he even need this. Meh.
if (tracker.tracker.vehicle != null && player.getEntityId() > tracker.tracker.vehicle.id) {
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker, tracker.tracker.vehicle));
} else if (tracker.tracker.passenger != null && player.getEntityId() > tracker.tracker.passenger.id) {
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(0, tracker.tracker.passenger, tracker.tracker));
}
if (tracker.tracker instanceof EntityInsentient && ((EntityInsentient) tracker.tracker).getLeashHolder() != null) {
entityplayer.playerConnection.sendPacket(new Packet39AttachEntity(1, tracker.tracker,
((EntityInsentient) tracker.tracker).getLeashHolder()));
}
// Resend the armor
for (int i = 0; i < 5; ++i) {
ItemStack itemstack = ((EntityLiving) tracker.tracker).getEquipment(i);
if (itemstack != null) {
entityplayer.playerConnection.sendPacket(new Packet5EntityEquipment(player.getEntityId(), i, itemstack));
}
}
// If the disguised is sleeping for w/e reason
if (entityplayer.isSleeping()) {
entityplayer.playerConnection
.sendPacket(new Packet17EntityLocationAction(entityplayer, 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
tracker.broadcast(new Packet35EntityHeadRotation(player.getEntityId(), (byte) tracker.i));
// CraftBukkit end
// Resend any active potion effects
Iterator iterator = entityplayer.getEffects().iterator();
while (iterator.hasNext()) {
MobEffect mobeffect = (MobEffect) iterator.next();
entityplayer.playerConnection.sendPacket(new Packet41MobEffect(player.getEntityId(), mobeffect));
}
} }
public static boolean isHearDisguisesEnabled() { public static boolean isHearDisguisesEnabled() {
return soundsListenerEnabled; return soundsListenerEnabled;
} }
public static boolean isInventoryListenerEnabled() {
return inventoryModifierEnabled;
}
public static boolean isViewDisguisesListenerEnabled() { public static boolean isViewDisguisesListenerEnabled() {
return viewDisguisesListenerEnabled; return viewDisguisesListenerEnabled;
} }
@ -673,9 +1102,24 @@ public class PacketsManager {
} }
} }
public static void setInventoryListenerEnabled(boolean enabled) {
if (inventoryModifierEnabled != enabled) {
inventoryModifierEnabled = enabled;
// TODO Update all disguises to update their inventories.
if (inventoryModifierEnabled) {
ProtocolLibrary.getProtocolManager().addPacketListener(inventoryListenerClient);
ProtocolLibrary.getProtocolManager().addPacketListener(inventoryListenerServer);
} else {
ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListenerClient);
ProtocolLibrary.getProtocolManager().removePacketListener(inventoryListenerServer);
}
}
}
public static void setViewDisguisesListener(boolean enabled) { public static void setViewDisguisesListener(boolean enabled) {
if (viewDisguisesListenerEnabled != enabled) { if (viewDisguisesListenerEnabled != enabled) {
viewDisguisesListenerEnabled = enabled; viewDisguisesListenerEnabled = enabled;
// TODO Remove all self disguises, or add them.
if (viewDisguisesListenerEnabled) { if (viewDisguisesListenerEnabled) {
ProtocolLibrary.getProtocolManager().addPacketListener(viewDisguisesListener); ProtocolLibrary.getProtocolManager().addPacketListener(viewDisguisesListener);
} else { } else {

@ -26,7 +26,6 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.comphenix.protocol.Packets; import com.comphenix.protocol.Packets;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketContainer;
@ -41,12 +40,24 @@ public class Disguise {
private DisguiseType disguiseType; private DisguiseType disguiseType;
private org.bukkit.entity.Entity entity; private org.bukkit.entity.Entity entity;
private boolean hearSelfDisguise = DisguiseAPI.canHearSelfDisguise(); private boolean hearSelfDisguise = DisguiseAPI.canHearSelfDisguise();
private boolean replaceSounds; private boolean hideArmorFromSelf = DisguiseAPI.isHidingArmorFromSelf();
private boolean hideHeldItemFromSelf = DisguiseAPI.isHidingHeldItemFromSelf();
private boolean replaceSounds = DisguiseAPI.isSoundEnabled();
private BukkitRunnable runnable; private BukkitRunnable runnable;
private boolean velocitySent = DisguiseAPI.isVelocitySent(); private boolean velocitySent = DisguiseAPI.isVelocitySent();
private boolean viewSelfDisguise = DisguiseAPI.isViewDisguises(); private boolean viewSelfDisguise = DisguiseAPI.isViewDisguises();
private FlagWatcher watcher; private FlagWatcher watcher;
public boolean canHearSelfDisguise() {
return hearSelfDisguise;
}
public Disguise clone() {
Disguise disguise = new Disguise().createDisguise(getType(), replaceSounds());
disguise.setViewSelfDisguise(viewSelfDisguise());
return disguise;
}
protected Disguise createDisguise(DisguiseType newType, boolean doSounds) { protected Disguise createDisguise(DisguiseType newType, boolean doSounds) {
if (getWatcher() != null) if (getWatcher() != null)
return this; return this;
@ -55,7 +66,12 @@ public class Disguise {
// Set the option to replace the sounds // Set the option to replace the sounds
setReplaceSounds(doSounds); setReplaceSounds(doSounds);
// Get if they are a adult now.. // Get if they are a adult now..
boolean isBaby = !(this instanceof MobDisguise && ((MobDisguise) this).isAdult()); boolean isBaby = false;
if (this instanceof MobDisguise) {
if (!((MobDisguise) this).isAdult()) {
isBaby = true;
}
}
try { try {
// Construct the FlagWatcher from the stored class // Construct the FlagWatcher from the stored class
setWatcher((FlagWatcher) getType().getWatcherClass().getConstructor(Disguise.class).newInstance(this)); setWatcher((FlagWatcher) getType().getWatcherClass().getConstructor(Disguise.class).newInstance(this));
@ -259,16 +275,6 @@ public class Disguise {
return this; return this;
} }
public boolean canHearSelfDisguise() {
return hearSelfDisguise;
}
public Disguise clone() {
Disguise disguise = new Disguise().createDisguise(getType(), replaceSounds());
disguise.setViewSelfDisguise(viewSelfDisguise());
return disguise;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
@ -327,6 +333,14 @@ public class Disguise {
return watcher; return watcher;
} }
public boolean isHidingArmorFromSelf() {
return hideArmorFromSelf;
}
public boolean isHidingHeldItemFromSelf() {
return hideHeldItemFromSelf;
}
public boolean isMiscDisguise() { public boolean isMiscDisguise() {
return this instanceof MiscDisguise; return this instanceof MiscDisguise;
} }
@ -363,7 +377,7 @@ public class Disguise {
disguises.remove(getEntity().getEntityId()); disguises.remove(getEntity().getEntityId());
// Gotta do reflection, copy code or open up calls. // Gotta do reflection, copy code or open up calls.
// Reflection is the cleanest? // Reflection is the cleanest?
if (entity instanceof Player) { if (getEntity() instanceof Player) {
disguiseAPI.removeVisibleDisguise((Player) entity); disguiseAPI.removeVisibleDisguise((Player) entity);
} }
// Better refresh the entity to undisguise it // Better refresh the entity to undisguise it
@ -401,6 +415,16 @@ public class Disguise {
this.hearSelfDisguise = hearSelfDisguise; this.hearSelfDisguise = hearSelfDisguise;
} }
public void setHideArmorFromSelf(boolean hideArmor) {
this.hideArmorFromSelf = hideArmor;
// TODO Update their armor if player
}
public void setHideHeldItemFromSelf(boolean hideHeldItem) {
this.hideHeldItemFromSelf = hideHeldItem;
// TODO Update their held item if player
}
public void setReplaceSounds(boolean areSoundsReplaced) { public void setReplaceSounds(boolean areSoundsReplaced) {
replaceSounds = areSoundsReplaced; replaceSounds = areSoundsReplaced;
} }

@ -22,7 +22,9 @@ public enum DisguiseSound {
CREEPER(Sound.CREEPER_HISS, Sound.STEP_GRASS, Sound.CREEPER_DEATH), CREEPER(Sound.CREEPER_HISS, Sound.STEP_GRASS, Sound.CREEPER_DEATH),
DONKEY(Sound.DONKEY_HIT, Sound.STEP_GRASS, Sound.DONKEY_DEATH, Sound.DONKEY_IDLE, Sound.DONKEY_ANGRY), DONKEY(Sound.DONKEY_HIT, Sound.STEP_GRASS, Sound.DONKEY_DEATH, Sound.DONKEY_IDLE, Sound.DONKEY_ANGRY, Sound.HORSE_GALLOP,
Sound.HORSE_ANGRY, Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, Sound.HORSE_SOFT,
Sound.HORSE_WOOD),
ENDER_DRAGON(Sound.ENDERDRAGON_HIT, null, Sound.ENDERDRAGON_DEATH, Sound.ENDERDRAGON_GROWL, Sound.ENDERDRAGON_WINGS, ENDER_DRAGON(Sound.ENDERDRAGON_HIT, null, Sound.ENDERDRAGON_DEATH, Sound.ENDERDRAGON_GROWL, Sound.ENDERDRAGON_WINGS,
Sound.FALL_BIG, Sound.FALL_SMALL), Sound.FALL_BIG, Sound.FALL_SMALL),
@ -35,7 +37,8 @@ public enum DisguiseSound {
GIANT(Sound.HURT_FLESH, Sound.STEP_GRASS), GIANT(Sound.HURT_FLESH, Sound.STEP_GRASS),
HORSE(Sound.HORSE_HIT, Sound.STEP_GRASS, "mob.horse.death", Sound.HORSE_IDLE), HORSE(Sound.HORSE_HIT, Sound.STEP_GRASS, "mob.horse.death", Sound.HORSE_IDLE, Sound.HORSE_GALLOP, Sound.HORSE_ANGRY,
Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, Sound.HORSE_SOFT, Sound.HORSE_WOOD),
IRON_GOLEM(Sound.IRONGOLEM_HIT, Sound.IRONGOLEM_WALK, Sound.IRONGOLEM_DEATH, Sound.IRONGOLEM_THROW), IRON_GOLEM(Sound.IRONGOLEM_HIT, Sound.IRONGOLEM_WALK, Sound.IRONGOLEM_DEATH, Sound.IRONGOLEM_THROW),
@ -59,7 +62,9 @@ public enum DisguiseSound {
SKELETON(Sound.SKELETON_HURT, Sound.SKELETON_WALK, Sound.SKELETON_DEATH, Sound.SKELETON_IDLE), SKELETON(Sound.SKELETON_HURT, Sound.SKELETON_WALK, Sound.SKELETON_DEATH, Sound.SKELETON_IDLE),
SKELETON_HORSE("mob.horse.skeleton.hit", Sound.STEP_GRASS, Sound.HORSE_SKELETON_DEATH, Sound.HORSE_SKELETON_IDLE), SKELETON_HORSE("mob.horse.skeleton.hit", Sound.STEP_GRASS, Sound.HORSE_SKELETON_DEATH, Sound.HORSE_SKELETON_IDLE,
Sound.HORSE_GALLOP, Sound.HORSE_ANGRY, Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE,
Sound.HORSE_SOFT, Sound.HORSE_WOOD),
SLIME(Sound.SLIME_ATTACK, Sound.SLIME_WALK2, null, null, Sound.SLIME_WALK), SLIME(Sound.SLIME_ATTACK, Sound.SLIME_WALK2, null, null, Sound.SLIME_WALK),
@ -69,7 +74,9 @@ public enum DisguiseSound {
SQUID(), SQUID(),
UNDEAD_HORSE(Sound.HORSE_ZOMBIE_HIT, Sound.STEP_GRASS, Sound.HORSE_ZOMBIE_DEATH, Sound.HORSE_ZOMBIE_IDLE), UNDEAD_HORSE(Sound.HORSE_ZOMBIE_HIT, Sound.STEP_GRASS, Sound.HORSE_ZOMBIE_DEATH, Sound.HORSE_ZOMBIE_IDLE, Sound.HORSE_GALLOP,
Sound.HORSE_ANGRY, Sound.HORSE_ARMOR, Sound.HORSE_JUMP, Sound.HORSE_LAND, Sound.HORSE_SADDLE, Sound.HORSE_SOFT,
Sound.HORSE_WOOD),
VILLAGER(Sound.VILLAGER_HIT, null, Sound.VILLAGER_DEATH, Sound.VILLAGER_IDLE, Sound.VILLAGER_HAGGLE, Sound.VILLAGER_YES, VILLAGER(Sound.VILLAGER_HIT, null, Sound.VILLAGER_DEATH, Sound.VILLAGER_IDLE, Sound.VILLAGER_HAGGLE, Sound.VILLAGER_YES,
Sound.VILLAGER_NO), Sound.VILLAGER_NO),