diff --git a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java index f9ddfde9..0fb9b504 100644 --- a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java @@ -52,7 +52,7 @@ public class LibsDisguises extends JavaPlugin { @Getter private final UpdateChecker updateChecker = new UpdateChecker(); @Getter - private final PlayerSkinHandler skinHandler = new PlayerSkinHandler(); + private PlayerSkinHandler skinHandler; @Override public void onLoad() { @@ -178,6 +178,7 @@ public class LibsDisguises extends JavaPlugin { PacketsManager.addPacketListeners(); listener = new DisguiseListener(this); + skinHandler = new PlayerSkinHandler(); Bukkit.getPluginManager().registerEvents(getSkinHandler(), LibsDisguises.getInstance()); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 21b58e02..46fd1c83 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -3025,7 +3025,8 @@ public class DisguiseUtilities { /** * Get the Y level to add to the disguise for realism. */ - public static double getYModifier(Entity entity, Disguise disguise) { + public static double getYModifier(Disguise disguise) { + Entity entity = disguise.getEntity(); double yMod = 0; if (disguise.getType() != DisguiseType.PLAYER && entity.getType() == EntityType.DROPPED_ITEM) { diff --git a/src/main/java/me/libraryaddict/disguise/utilities/listeners/PlayerSkinHandler.java b/src/main/java/me/libraryaddict/disguise/utilities/listeners/PlayerSkinHandler.java index 20a1d015..0f3f16ec 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/listeners/PlayerSkinHandler.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/listeners/PlayerSkinHandler.java @@ -4,6 +4,7 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.wrappers.EnumWrappers; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; @@ -11,12 +12,15 @@ import com.google.common.cache.RemovalCause; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.events.UndisguiseEvent; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.packets.LibsPackets; +import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -84,6 +88,15 @@ public class PlayerSkinHandler implements Listener { skins.clear(); }).build(); + public PlayerSkinHandler() { + new BukkitRunnable() { + @Override + public void run() { + getCache().asMap().forEach((key, value) -> doTeleport(key, value)); + } + }.runTaskTimer(LibsDisguises.getInstance(), 1, 1); + } + public PlayerSkin addPlayerSkin(Player player, PlayerDisguise disguise) { tryProcess(player, false); @@ -101,7 +114,53 @@ public class PlayerSkinHandler implements Listener { return toReturn; } + private void doTeleport(Player player, List value) { + if (player == null || !player.isOnline()) { + return; + } + + Location loc = player.getLocation(); + loc.add(loc.getDirection().normalize().multiply(10)); + + PacketContainer packet = new PacketContainer(Server.ENTITY_TELEPORT); + packet.getModifier().write(1, loc.getX()); + packet.getModifier().write(2, loc.getY()); + packet.getModifier().write(3, loc.getZ()); + + for (PlayerSkin skin : value) { + if (!skin.isSleepPackets()) { + continue; + } + + PlayerDisguise disguise = skin.getDisguise().get(); + + if (disguise == null || !disguise.isDisguiseInUse()) { + continue; + } + + packet = packet.shallowClone(); + + int id = disguise.getEntity().getEntityId(); + + if (id == player.getEntityId()) { + id = DisguiseAPI.getSelfDisguiseId(); + } + + packet.getModifier().write(0, id); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + public void handlePackets(Player player, PlayerDisguise disguise, LibsPackets packets) { + if (packets.getPackets().stream().anyMatch(p -> p.getType() == Server.NAMED_ENTITY_SPAWN)) { + return; + } + List skins = getCache().getIfPresent(player); if (skins == null) { @@ -170,6 +229,49 @@ public class PlayerSkinHandler implements Listener { } } + private void addTeleport(Player player, PlayerSkin skin) { + PlayerDisguise disguise = skin.getDisguise().get(); + + PacketContainer teleport = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); + + StructureModifier mods = teleport.getModifier(); + Location loc = disguise.getEntity().getLocation(); + + Float pitchLock = DisguiseConfig.isMovementPacketsEnabled() ? disguise.getWatcher().getPitchLock() : null; + Float yawLock = DisguiseConfig.isMovementPacketsEnabled() ? disguise.getWatcher().getYawLock() : null; + + byte yaw = (byte) (int) ((yawLock == null ? loc.getYaw() : yawLock) * 256.0F / 360.0F); + byte pitch = (byte) (int) ((pitchLock == null ? loc.getPitch() : pitchLock) * 256.0F / 360.0F); + + if (DisguiseConfig.isMovementPacketsEnabled()) { + if (yawLock == null) { + yaw = DisguiseUtilities.getYaw(DisguiseType.getType(disguise.getEntity().getType()), yaw); + } + + if (pitchLock == null) { + pitch = DisguiseUtilities.getPitch(DisguiseType.getType(disguise.getEntity().getType()), pitch); + } + + yaw = DisguiseUtilities.getYaw(disguise.getType(), yaw); + pitch = DisguiseUtilities.getPitch(disguise.getType(), pitch); + } + + int id = disguise.getEntity().getEntityId(); + + if (id == player.getEntityId()) { + id = DisguiseAPI.getSelfDisguiseId(); + } + + mods.write(0, id); + mods.write(1, loc.getX()); + mods.write(2, loc.getY() + DisguiseUtilities.getYModifier(disguise)); + mods.write(3, loc.getZ()); + mods.write(4, yaw); + mods.write(5, pitch); + + skin.getSleptPackets().computeIfAbsent(0, (a) -> new ArrayList<>()).add(teleport); + } + private void doPacketRemoval(Player player, PlayerSkin skin) { PlayerDisguise disguise = skin.getDisguise().get(); @@ -177,6 +279,10 @@ public class PlayerSkinHandler implements Listener { return; } + if (skin.isSleepPackets()) { + addTeleport(player, skin); + } + try { for (Map.Entry> entry : skin.getSleptPackets().entrySet()) { if (entry.getKey() == 0) { diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java index e21f02af..e6676596 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/LibsPackets.java @@ -19,7 +19,10 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import java.lang.reflect.InvocationTargetException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Created by libraryaddict on 3/01/2019. diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java index 1ada8501..08645fe6 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerHeadRotation.java @@ -28,6 +28,11 @@ public class PacketHandlerHeadRotation implements IPacketHandler { @Override public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer, Entity entity) { + if (disguise.getType() == DisguiseType.FALLING_BLOCK) { + packets.clear(); + return; + } + Float pitchLock = disguise.getWatcher().getPitchLock(); Float yawLock = disguise.getWatcher().getYawLock(); boolean riding = observer.getVehicle() == entity; diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java index c454b7ab..ec9693c4 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerMovement.java @@ -82,15 +82,31 @@ public class PacketHandlerMovement implements IPacketHandler { } // If falling block should be appearing in center of blocks - if (sentPacket.getType() != PacketType.Play.Server.ENTITY_LOOK && - disguise.getType() == DisguiseType.FALLING_BLOCK && + if (disguise.getType() == DisguiseType.FALLING_BLOCK && ((FallingBlockWatcher) disguise.getWatcher()).isGridLocked()) { packets.clear(); + if (sentPacket.getType() == PacketType.Play.Server.ENTITY_LOOK) { + return; + } + PacketContainer movePacket = sentPacket.shallowClone(); - // If relational movement - if (sentPacket.getType() != PacketType.Play.Server.ENTITY_TELEPORT) { + // If not relational movement + if (movePacket.getType() == PacketType.Play.Server.ENTITY_TELEPORT) { + Location loc = entity.getLocation(); + + StructureModifier doubles = movePacket.getDoubles(); + // Center the block + doubles.write(0, loc.getBlockX() + 0.5); + + double y = loc.getBlockY(); + + y += (loc.getY() % 1 >= 0.85 ? 1 : loc.getY() % 1 >= 0.35 ? .5 : 0); + + doubles.write(1, y); + doubles.write(2, loc.getBlockZ() + 0.5); + } else { StructureModifier shorts = movePacket.getShorts(); Location origLoc = entity.getLocation(); @@ -112,22 +128,10 @@ public class PacketHandlerMovement implements IPacketHandler { shorts.write(1, conRel(origY, newY)); shorts.write(2, conRel(origLoc.getBlockZ(), newLoc.getBlockZ())); } - } else { - Location loc = entity.getLocation(); - - StructureModifier doubles = movePacket.getDoubles(); - // Center the block - doubles.write(0, loc.getBlockX() + 0.5); - - double y = loc.getBlockY(); - - y += (loc.getY() % 1 >= 0.85 ? 1 : loc.getY() % 1 >= 0.35 ? .5 : 0); - - doubles.write(1, y); - doubles.write(2, loc.getBlockZ() + 0.5); } packets.addPacket(movePacket); + return; } else if (disguise.getType() == DisguiseType.RABBIT && (sentPacket.getType() == PacketType.Play.Server.REL_ENTITY_MOVE || sentPacket.getType() == PacketType.Play.Server.REL_ENTITY_MOVE_LOOK)) { @@ -220,7 +224,7 @@ public class PacketHandlerMovement implements IPacketHandler { } } - double y = DisguiseUtilities.getYModifier(entity, disguise); + double y = DisguiseUtilities.getYModifier(disguise); if (y != 0) { doubles.write(2, doubles.read(2) + y); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java index 4d1a7ed1..1275eddc 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packethandlers/PacketHandlerSpawn.java @@ -103,8 +103,7 @@ public class PacketHandlerSpawn implements IPacketHandler { } } - Location loc = disguisedEntity.getLocation().clone() - .add(0, DisguiseUtilities.getYModifier(disguisedEntity, disguise), 0); + Location loc = disguisedEntity.getLocation().clone().add(0, DisguiseUtilities.getYModifier(disguise), 0); Float pitchLock = DisguiseConfig.isMovementPacketsEnabled() ? disguise.getWatcher().getPitchLock() : null; Float yawLock = DisguiseConfig.isMovementPacketsEnabled() ? disguise.getWatcher().getYawLock() : null; @@ -123,7 +122,6 @@ public class PacketHandlerSpawn implements IPacketHandler { yaw = DisguiseUtilities.getYaw(disguise.getType(), yaw); pitch = DisguiseUtilities.getPitch(disguise.getType(), pitch); - } if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) { @@ -213,14 +211,14 @@ public class PacketHandlerSpawn implements IPacketHandler { double dist = observer.getLocation().distanceSquared(disguisedEntity.getLocation()); // If self disguise, or further than 50 blocks, or not in front of entity - boolean spawnFarAway = observer == disguisedEntity || dist > (50 * 50) || + boolean normalPlayerDisguise = observer == disguisedEntity || dist > (50 * 50) || (observer.getLocation().add(observer.getLocation().getDirection().normalize()) .distanceSquared(disguisedEntity.getLocation()) - dist) < 0.3; - skin.setSleepPackets(!spawnFarAway); + skin.setSleepPackets(!normalPlayerDisguise); - Location spawnAt = spawnFarAway ? disguisedEntity.getLocation() : - observer.getLocation().add(observer.getLocation().getDirection().normalize().multiply(50)); + Location spawnAt = normalPlayerDisguise ? disguisedEntity.getLocation() : + observer.getLocation().add(observer.getLocation().getDirection().normalize().multiply(10)); // Spawn him in front of the observer StructureModifier doubles = spawnPlayer.getDoubles(); @@ -240,7 +238,7 @@ public class PacketHandlerSpawn implements IPacketHandler { WrappedDataWatcher toSend = dataWatcher; - if (!spawnFarAway) { + if (!normalPlayerDisguise) { toSend = new WrappedDataWatcher(); WrappedDataWatcher.WrappedDataWatcherObject obj = ReflectionManager.createDataWatcherObject(MetaIndex.ENTITY_META, (byte) 32); @@ -259,23 +257,11 @@ public class PacketHandlerSpawn implements IPacketHandler { spawnPlayer.getDataWatcherModifier().write(0, toSend); } - if (!spawnFarAway) { + if (!normalPlayerDisguise) { PacketContainer metaPacket = ProtocolLibrary.getProtocolManager() .createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, entityId, dataWatcher, true) .createPacket(entityId, dataWatcher, true); - PacketContainer teleport = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); - - StructureModifier mods = teleport.getModifier(); - - mods.write(0, disguisedEntity.getEntityId()); - mods.write(1, loc.getX()); - mods.write(2, loc.getY()); - mods.write(3, loc.getZ()); - mods.write(4, yaw); - mods.write(5, pitch); - - skin.getSleptPackets().computeIfAbsent(0, (a) -> new ArrayList<>()).add(teleport); skin.getSleptPackets().computeIfAbsent(4, (a) -> new ArrayList<>()).add(metaPacket); } } else if (disguise.isMobDisguise() || disguise.getType() == DisguiseType.ARMOR_STAND) { diff --git a/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java index 70009636..e90e6587 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/packets/packetlisteners/PacketListenerViewSelfDisguise.java @@ -1,6 +1,5 @@ package me.libraryaddict.disguise.utilities.packets.packetlisteners; -import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.ListenerPriority; @@ -19,7 +18,6 @@ import me.libraryaddict.disguise.utilities.LibsPremium; import me.libraryaddict.disguise.utilities.packets.LibsPackets; import me.libraryaddict.disguise.utilities.packets.PacketsManager; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.lang.reflect.InvocationTargetException;