diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java index 9035d653..dd7418ad 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/PlayerWatcher.java @@ -1,20 +1,74 @@ package me.libraryaddict.disguise.disguisetypes.watchers; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; + import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.ReflectionManager; public class PlayerWatcher extends LivingWatcher { + private boolean isInBed; public PlayerWatcher(Disguise disguise) { super(disguise); } + public PlayerWatcher clone(Disguise disguise) { + PlayerWatcher watcher = (PlayerWatcher) super.clone(disguise); + watcher.isInBed = isInBed; + return watcher; + } + public int getArrowsSticking() { return (Byte) getValue(9, (byte) 0); } + public boolean isSleeping() { + return isInBed; + } + public void setArrowsSticking(int arrowsNo) { setValue(9, (byte) arrowsNo); sendData(9); } + /** + * The facing direction for the bed is the block metadata. 0 - 90 degrees. 1 - 0 degrees. 2 - 270 degrees. 3 - 180 degrees. + */ + public void setSleeping(boolean sleep) { + if (sleep != isSleeping()) { + isInBed = sleep; + if (DisguiseUtilities.isDisguiseInUse(getDisguise())) { + PacketContainer packet; + if (isSleeping()) { + packet = new PacketContainer(PacketType.Play.Server.BED); + StructureModifier mods = packet.getIntegers(); + mods.write(0, getDisguise().getEntity().getEntityId()); + Location loc = getDisguise().getEntity().getLocation(); + mods.write(1, loc.getBlockX()); + mods.write(2, loc.getBlockY()); + mods.write(3, loc.getBlockZ()); + } else { + packet = new PacketContainer(PacketType.Play.Server.ANIMATION); + StructureModifier mods = packet.getIntegers(); + mods.write(0, getDisguise().getEntity().getEntityId()); + mods.write(1, ReflectionManager.isAfter17() ? 3 : 2); + } + try { + for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + } + } diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index c865609d..9aa03e38 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -14,6 +14,7 @@ import me.libraryaddict.disguise.disguisetypes.FlagWatcher; import me.libraryaddict.disguise.disguisetypes.MiscDisguise; import me.libraryaddict.disguise.disguisetypes.MobDisguise; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; +import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType; import org.bukkit.Art; @@ -164,7 +165,7 @@ public class PacketsManager { for (int i = 0; i < packets.size(); i++) { spawnPackets[i + 2] = packets.get(i); } - Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguisedEntity, disguise.getType()), 0); + Location loc = disguisedEntity.getLocation().clone().add(0, getYModifier(disguise), 0); byte yaw = getYaw(disguise.getType(), disguisedEntity.getType(), (byte) (int) (loc.getYaw() * 256.0F / 360.0F)); if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { @@ -227,6 +228,15 @@ public class PacketsManager { spawnPackets[0].getDataWatcherModifier().write(0, createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); + if (((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED); + StructureModifier mods = spawnPackets[1].getIntegers(); + mods.write(0, disguisedEntity.getEntityId()); + mods.write(1, loc.getBlockX()); + mods.write(2, loc.getBlockY()); + mods.write(3, loc.getBlockZ()); + } + } else if (disguise.getType().isMob()) { DisguiseValues values = DisguiseValues.getDisguiseValues(disguise.getType()); @@ -417,18 +427,18 @@ public class PacketsManager { /** * Get the Y level to add to the disguise for realism. */ - private static double getYModifier(Entity entity, DisguiseType disguiseType) { - switch (disguiseType) { + private static double getYModifier(Disguise disguise) { + switch (disguise.getType()) { case BAT: - if (entity instanceof LivingEntity) - return ((LivingEntity) entity).getEyeHeight(); + if (disguise.getEntity() instanceof LivingEntity) + return ((LivingEntity) disguise.getEntity()).getEyeHeight(); case MINECART: case MINECART_CHEST: case MINECART_FURNACE: case MINECART_HOPPER: case MINECART_MOB_SPAWNER: case MINECART_TNT: - switch (entity.getType()) { + switch (disguise.getEntity().getType()) { case MINECART: case MINECART_CHEST: case MINECART_FURNACE: @@ -452,6 +462,11 @@ public class PacketsManager { case THROWN_EXP_BOTTLE: case WITHER_SKULL: return 0.7; + case PLAYER: + if (((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + return 0.5; + } + break; default: break; } @@ -1141,6 +1156,12 @@ public class PacketsManager { else if (sentPacket.getType() == PacketType.Play.Server.COLLECT) { if (disguise.getType().isMisc()) { packets = new PacketContainer[0]; + } else if (disguise.getType().isPlayer() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { + PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ANIMATION); + StructureModifier mods = newPacket.getIntegers(); + mods.write(0, disguise.getEntity().getEntityId()); + mods.write(1, ReflectionManager.isAfter17() ? 3 : 2); + packets = new PacketContainer[] { newPacket, sentPacket }; } } @@ -1159,7 +1180,7 @@ public class PacketsManager { byte pitchValue = (Byte) mods.read(5); mods.write(5, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue)); if (sentPacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT) { - double y = getYModifier(entity, disguise.getType()); + double y = getYModifier(disguise); if (y != 0) { y *= 32; mods.write(2, (Integer) mods.read(2) + (int) Math.floor(y));