Can now add items to disguises.

This commit is contained in:
Andrew 2013-08-01 20:29:04 +12:00
parent 5375edc14c
commit 60246748a2
2 changed files with 204 additions and 96 deletions

View File

@ -6,20 +6,36 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.bukkit.craftbukkit.v1_6_R2.inventory.CraftItemStack;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
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;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
import me.libraryaddict.disguise.DisguiseAPI;
import net.minecraft.server.v1_6_R2.ChunkCoordinates; import net.minecraft.server.v1_6_R2.ChunkCoordinates;
import net.minecraft.server.v1_6_R2.EntityPlayer; import net.minecraft.server.v1_6_R2.EntityPlayer;
import net.minecraft.server.v1_6_R2.ItemStack; import net.minecraft.server.v1_6_R2.ItemStack;
import net.minecraft.server.v1_6_R2.WatchableObject; import net.minecraft.server.v1_6_R2.WatchableObject;
public class FlagWatcher { public class FlagWatcher {
public enum SlotType {
BOOTS(0), CHESTPLATE(2), HELD_ITEM(4), HELMET(3), LEGGINGS(1);
private int slotNo = 0;
private SlotType(int no) {
slotNo = no;
}
public int getSlot() {
return slotNo;
}
}
private static HashMap<Class, Integer> classTypes = new HashMap<Class, Integer>(); private static HashMap<Class, Integer> classTypes = new HashMap<Class, Integer>();
static { static {
@ -33,6 +49,7 @@ public class FlagWatcher {
} }
private Disguise disguise; private Disguise disguise;
private HashMap<Integer, Object> entityValues = new HashMap<Integer, Object>(); private HashMap<Integer, Object> entityValues = new HashMap<Integer, Object>();
private org.bukkit.inventory.ItemStack[] items = new org.bukkit.inventory.ItemStack[5];
public FlagWatcher(Disguise disguise) { public FlagWatcher(Disguise disguise) {
this.disguise = disguise; this.disguise = disguise;
@ -95,6 +112,14 @@ public class FlagWatcher {
return ((Byte) getValue(0, (byte) 0) & 1 << i) != 0; return ((Byte) getValue(0, (byte) 0) & 1 << i) != 0;
} }
public org.bukkit.inventory.ItemStack getItemStack(int slot) {
return items[slot];
}
public org.bukkit.inventory.ItemStack getItemStack(SlotType slot) {
return getItemStack(slot.getSlot());
}
protected Object getValue(int no, Object backup) { protected Object getValue(int no, Object backup) {
if (entityValues.containsKey(no)) if (entityValues.containsKey(no))
return entityValues.get(no); return entityValues.get(no);
@ -130,7 +155,7 @@ public class FlagWatcher {
} }
protected void sendData(int data) { protected void sendData(int data) {
if (disguise.getWatcher() == null) if (disguise.getWatcher() == null || !DisguiseAPI.isDisguised(disguise.getEntity()))
return; return;
Entity entity = disguise.getEntity(); Entity entity = disguise.getEntity();
Object value = entityValues.get(data); Object value = entityValues.get(data);
@ -178,6 +203,50 @@ public class FlagWatcher {
} }
} }
public void setItemStack(int slot, org.bukkit.inventory.ItemStack itemStack) {
// Itemstack which is null means that its not replacing the disguises itemstack.
if (itemStack == null) {
// Find the item to replace it with
if (disguise.getEntity() instanceof LivingEntity) {
EntityEquipment enquipment = ((LivingEntity) disguise.getEntity()).getEquipment();
if (slot == 4) {
itemStack = enquipment.getItemInHand();
} else {
itemStack = enquipment.getArmorContents()[slot];
}
if (itemStack != null && itemStack.getTypeId() == 0)
itemStack = null;
}
}
ItemStack itemToSend = null;
if (itemStack != null && itemStack.getTypeId() != 0)
itemToSend = CraftItemStack.asNMSCopy(itemStack);
items[slot] = itemStack;
slot++;
if (slot > 4)
slot = 0;
PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_EQUIPMENT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, disguise.getEntity().getEntityId());
mods.write(1, slot);
mods.write(2, itemToSend);
for (EntityPlayer player : disguise.getPerverts()) {
Player p = player.getBukkitEntity();
if (p != disguise.getEntity()) {
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(p, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
public void setItemStack(SlotType slot, org.bukkit.inventory.ItemStack itemStack) {
setItemStack(slot.getSlot(), itemStack);
}
public void setRiding(boolean setRiding) { public void setRiding(boolean setRiding) {
if (isSprinting() != setRiding) { if (isSprinting() != setRiding) {
setFlag(0, 2, true); setFlag(0, 2, true);

View File

@ -84,7 +84,8 @@ public class LibsDisguises extends JavaPlugin {
Packets.Server.NAMED_ENTITY_SPAWN, Packets.Server.ENTITY_METADATA, Packets.Server.ARM_ANIMATION, 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.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.ADD_EXP_ORB, Packets.Server.VEHICLE_SPAWN, Packets.Server.MOB_SPAWN,
Packets.Server.ENTITY_PAINTING, Packets.Server.COLLECT, Packets.Server.UPDATE_ATTRIBUTES) { Packets.Server.ENTITY_PAINTING, Packets.Server.COLLECT, Packets.Server.UPDATE_ATTRIBUTES,
Packets.Server.ENTITY_EQUIPMENT) {
@Override @Override
public void onPacketSending(PacketEvent event) { public void onPacketSending(PacketEvent event) {
Player observer = event.getPlayer(); Player observer = event.getPlayer();
@ -128,12 +129,36 @@ public class LibsDisguises extends JavaPlugin {
} }
protected PacketContainer[] constructPacket(Disguise disguise, Entity disguisedEntity) { protected PacketContainer[] constructPacket(Disguise disguise, Entity disguisedEntity) {
PacketContainer[] spawnPackets = new PacketContainer[2];
ProtocolManager manager = ProtocolLibrary.getProtocolManager(); ProtocolManager manager = ProtocolLibrary.getProtocolManager();
net.minecraft.server.v1_6_R2.Entity nmsEntity = ((CraftEntity) disguisedEntity).getHandle(); net.minecraft.server.v1_6_R2.Entity nmsEntity = ((CraftEntity) disguisedEntity).getHandle();
ArrayList<PacketContainer> packets = new ArrayList<PacketContainer>();
for (int i = 0; i < 5; i++) {
int slot = i - 1;
if (slot < 0)
slot = 4;
org.bukkit.inventory.ItemStack itemstack = disguise.getWatcher().getItemStack(slot);
if (itemstack != null && itemstack.getTypeId() != 0) {
ItemStack item = null;
if (nmsEntity instanceof EntityLiving)
item = ((EntityLiving) nmsEntity).getEquipment(i);
if (item == null) {
PacketContainer packet = new PacketContainer(Packets.Server.ENTITY_EQUIPMENT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, disguisedEntity.getEntityId());
mods.write(1, i);
mods.write(2, CraftItemStack.asNMSCopy(itemstack));
packets.add(packet);
}
}
}
PacketContainer[] spawnPackets = new PacketContainer[2 + packets.size()];
for (int i = 0; i < packets.size(); i++) {
spawnPackets[i + 2] = packets.get(i);
}
Location loc = disguisedEntity.getLocation(); Location loc = disguisedEntity.getLocation();
byte yaw = getYaw(disguise.getType(), DisguiseType.getType(disguise.getEntity().getType()), byte yaw = getYaw(disguise.getType(), DisguiseType.getType(disguise.getEntity().getType()),
(byte) (int) (loc.getYaw() * 256.0F / 360.0F)); (byte) (int) (loc.getYaw() * 256.0F / 360.0F));
if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) {
spawnPackets[0] = manager.createPacket(Packets.Server.ADD_EXP_ORB); spawnPackets[0] = manager.createPacket(Packets.Server.ADD_EXP_ORB);
@ -301,99 +326,6 @@ public class LibsDisguises extends JavaPlugin {
} }
protected PacketContainer[] transformPacket(PacketContainer sentPacket, Player observer) {
PacketContainer[] packets = new PacketContainer[] { sentPacket };
try {
// First get the entity, the one sending this packet
StructureModifier<Entity> entityModifer = sentPacket.getEntityModifier(observer.getWorld());
org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == sentPacket.getID() ? 1 : 0));
Disguise disguise = DisguiseAPI.getDisguise(entity);
// If disguised.
if (disguise != null) {
// If packet is Packets.Server.UPDATE_ATTRIBUTES - For some reason maven doesn't let me..
// This packet sends attributes
switch (sentPacket.getID()) {
case Packets.Server.UPDATE_ATTRIBUTES:
{
// Grab the values which are 'approved' to be sent for this entity
HashMap<String, Double> values = Values.getAttributesValues(disguise.getType());
Collection collection = new ArrayList<AttributeSnapshot>();
for (AttributeSnapshot att : (List<AttributeSnapshot>) sentPacket.getModifier().read(1)) {
if (values.containsKey(att.a())) {
collection.add(new AttributeSnapshot(null, att.a(), values.get(att.a()), att.c()));
}
}
if (collection.size() > 0) {
packets[0] = new PacketContainer(sentPacket.getID());
StructureModifier<Object> mods = packets[0].getModifier();
mods.write(0, entity.getEntityId());
mods.write(1, collection);
} else {
packets = new PacketContainer[0];
}
break;
}
// Else if the packet is sending entity metadata
case Packets.Server.ENTITY_METADATA:
{
List<WatchableObject> watchableObjects = disguise.getWatcher().convert(
(List<WatchableObject>) packets[0].getModifier().read(1));
packets[0] = new PacketContainer(sentPacket.getID());
StructureModifier<Object> newMods = packets[0].getModifier();
newMods.write(0, entity.getEntityId());
newMods.write(1, watchableObjects);
break;
}
// Else if the packet is spawning..
case Packets.Server.NAMED_ENTITY_SPAWN:
case Packets.Server.MOB_SPAWN:
case Packets.Server.ADD_EXP_ORB:
case Packets.Server.VEHICLE_SPAWN:
case Packets.Server.ENTITY_PAINTING:
{
packets = constructPacket(disguise, entity);
break;
}
// Else if the disguise is attempting to send players a forbidden packet
case Packets.Server.ARM_ANIMATION:
case Packets.Server.COLLECT:
{
if (disguise.getType().isMisc())
packets = new PacketContainer[0];
break;
}
// Else if the disguise is moving.
case Packets.Server.REL_ENTITY_MOVE_LOOK:
case Packets.Server.ENTITY_LOOK:
case Packets.Server.ENTITY_TELEPORT:
{
packets[0] = sentPacket.shallowClone();
StructureModifier<Object> mods = packets[0].getModifier();
byte value = (Byte) mods.read(4);
mods.write(4, getYaw(disguise.getType(), DisguiseType.getType(entity.getType()), value));
break;
}
default:
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return packets;
}
private byte getYaw(DisguiseType disguiseType, DisguiseType entityType, byte value) { private byte getYaw(DisguiseType disguiseType, DisguiseType entityType, byte value) {
switch (disguiseType) { switch (disguiseType) {
case ENDER_DRAGON: case ENDER_DRAGON:
@ -619,4 +551,111 @@ public class LibsDisguises extends JavaPlugin {
} }
return builder.toString(); return builder.toString();
} }
protected PacketContainer[] transformPacket(PacketContainer sentPacket, Player observer) {
PacketContainer[] packets = new PacketContainer[] { sentPacket };
try {
// First get the entity, the one sending this packet
StructureModifier<Entity> entityModifer = sentPacket.getEntityModifier(observer.getWorld());
org.bukkit.entity.Entity entity = entityModifer.read((Packets.Server.COLLECT == sentPacket.getID() ? 1 : 0));
Disguise disguise = DisguiseAPI.getDisguise(entity);
// If disguised.
if (disguise != null) {
// If packet is Packets.Server.UPDATE_ATTRIBUTES - For some reason maven doesn't let me..
// This packet sends attributes
switch (sentPacket.getID()) {
case Packets.Server.UPDATE_ATTRIBUTES:
{
// Grab the values which are 'approved' to be sent for this entity
HashMap<String, Double> values = Values.getAttributesValues(disguise.getType());
Collection collection = new ArrayList<AttributeSnapshot>();
for (AttributeSnapshot att : (List<AttributeSnapshot>) sentPacket.getModifier().read(1)) {
if (values.containsKey(att.a())) {
collection.add(new AttributeSnapshot(null, att.a(), values.get(att.a()), att.c()));
}
}
if (collection.size() > 0) {
packets[0] = new PacketContainer(sentPacket.getID());
StructureModifier<Object> mods = packets[0].getModifier();
mods.write(0, entity.getEntityId());
mods.write(1, collection);
} else {
packets = new PacketContainer[0];
}
break;
}
// Else if the packet is sending entity metadata
case Packets.Server.ENTITY_METADATA:
{
List<WatchableObject> watchableObjects = disguise.getWatcher().convert(
(List<WatchableObject>) packets[0].getModifier().read(1));
packets[0] = new PacketContainer(sentPacket.getID());
StructureModifier<Object> newMods = packets[0].getModifier();
newMods.write(0, entity.getEntityId());
newMods.write(1, watchableObjects);
break;
}
// Else if the packet is spawning..
case Packets.Server.NAMED_ENTITY_SPAWN:
case Packets.Server.MOB_SPAWN:
case Packets.Server.ADD_EXP_ORB:
case Packets.Server.VEHICLE_SPAWN:
case Packets.Server.ENTITY_PAINTING:
{
packets = constructPacket(disguise, entity);
break;
}
// Else if the disguise is attempting to send players a forbidden packet
case Packets.Server.ARM_ANIMATION:
case Packets.Server.COLLECT:
{
if (disguise.getType().isMisc())
packets = new PacketContainer[0];
break;
}
// Else if the disguise is moving.
case Packets.Server.REL_ENTITY_MOVE_LOOK:
case Packets.Server.ENTITY_LOOK:
case Packets.Server.ENTITY_TELEPORT:
{
packets[0] = sentPacket.shallowClone();
StructureModifier<Object> mods = packets[0].getModifier();
byte value = (Byte) mods.read(4);
mods.write(4, getYaw(disguise.getType(), DisguiseType.getType(entity.getType()), value));
break;
}
case Packets.Server.ENTITY_EQUIPMENT:
{
int slot = (Integer) packets[0].getModifier().read(1) - 1;
if (slot < 0)
slot = 4;
org.bukkit.inventory.ItemStack itemstack = disguise.getWatcher().getItemStack(slot);
if (itemstack != null) {
packets[0] = packets[0].shallowClone();
packets[0].getModifier().write(2,
(itemstack.getTypeId() == 0 ? null : CraftItemStack.asNMSCopy(itemstack)));
}
}
default:
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return packets;
}
} }