Search in sources :

Example 6 with StructureModifier

use of com.comphenix.protocol.reflect.StructureModifier in project LibsDisguises by libraryaddict.

the class PacketHandlerSpawn method constructSpawnPackets.

/**
 * Construct the packets I need to spawn in the disguise
 */
private void constructSpawnPackets(final Player observer, LibsPackets packets, Entity disguisedEntity) {
    Disguise disguise = packets.getDisguise();
    boolean sendArmor = true;
    Location loc = disguisedEntity.getLocation().clone().add(0, DisguiseUtilities.getYModifier(disguise) + disguise.getWatcher().getYModifier(), 0);
    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(disguisedEntity.getType()), yaw);
        }
        if (pitchLock == null) {
            pitch = DisguiseUtilities.getPitch(DisguiseType.getType(disguisedEntity.getType()), pitch);
        }
        yaw = DisguiseUtilities.getYaw(disguise.getType(), yaw);
        pitch = DisguiseUtilities.getPitch(disguise.getType(), pitch);
    }
    boolean normalPlayerDisguise = true;
    if (disguise.getType() == DisguiseType.EXPERIENCE_ORB) {
        PacketContainer spawnOrb = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB);
        packets.addPacket(spawnOrb);
        StructureModifier<Object> mods = spawnOrb.getModifier();
        mods.write(0, disguisedEntity.getEntityId());
        mods.write(1, loc.getX());
        mods.write(2, loc.getY() + 0.06);
        mods.write(3, loc.getZ());
        mods.write(4, 1);
    } else if (disguise.getType() == DisguiseType.PAINTING) {
        PacketContainer spawnPainting = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_PAINTING);
        packets.addPacket(spawnPainting);
        StructureModifier<Object> mods = spawnPainting.getModifier();
        mods.write(0, disguisedEntity.getEntityId());
        mods.write(1, disguise.getUUID());
        mods.write(2, ReflectionManager.getBlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
        mods.write(3, ReflectionManager.getEnumDirection(((int) loc.getYaw()) % 4));
        int id = ((MiscDisguise) disguise).getData();
        mods.write(4, NmsVersion.v1_13.isSupported() ? id : ReflectionManager.getEnumArt(Art.values()[id]));
        // Make the teleport packet to make it visible..
        PacketContainer teleportPainting = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT);
        packets.addPacket(teleportPainting);
        mods = teleportPainting.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);
    } else if (disguise.getType().isPlayer()) {
        PlayerDisguise playerDisguise = (PlayerDisguise) disguise;
        boolean visibleOrNewCompat = playerDisguise.isNameVisible() || DisguiseConfig.isScoreboardNames();
        int entityId = disguisedEntity.getEntityId();
        PlayerSkinHandler.PlayerSkin skin;
        if (!playerDisguise.isDisplayedInTab() || !playerDisguise.isNameVisible()) {
            // Send player info along with the disguise
            PacketContainer sendTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
            // Add player to the list, necessary to spawn them
            sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0));
            List playerList = Collections.singletonList(ReflectionManager.getPlayerInfoData(sendTab.getHandle(), ReflectionManager.getGameProfileWithThisSkin(playerDisguise.getUUID(), playerDisguise.getProfileName(), playerDisguise.getGameProfile())));
            sendTab.getModifier().write(1, playerList);
            packets.addPacket(sendTab);
            // Remove player from the list
            PacketContainer deleteTab = sendTab.shallowClone();
            deleteTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(4));
            skin = LibsDisguises.getInstance().getSkinHandler().addPlayerSkin(observer, playerDisguise);
            if (LibsPremium.getPaidInformation() != null && !LibsPremium.getPaidInformation().getBuildNumber().matches("#[0-9]+")) {
                skin.getSleptPackets().computeIfAbsent(0, (a) -> new ArrayList<>()).add(new PacketContainer(PacketType.Play.Server.HELD_ITEM_SLOT));
            }
        } else {
            skin = LibsDisguises.getInstance().getSkinHandler().addPlayerSkin(observer, playerDisguise);
            skin.setDoTabList(false);
        }
        // Spawn the player
        PacketContainer spawnPlayer = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
        // Id
        spawnPlayer.getIntegers().write(0, entityId);
        spawnPlayer.getModifier().write(1, playerDisguise.getUUID());
        double dist = observer.getLocation().toVector().distanceSquared(disguisedEntity.getLocation().toVector());
        // If self disguise, or further than 50 blocks, or not in front of entity
        normalPlayerDisguise = observer == disguisedEntity || disguisedEntity.getPassengers().contains(observer) || dist > (50 * 50) || (observer.getLocation().add(observer.getLocation().getDirection().normalize()).toVector().distanceSquared(disguisedEntity.getLocation().toVector()) - dist) < 0.3;
        sendArmor = normalPlayerDisguise;
        skin.setSleepPackets(!normalPlayerDisguise);
        Location spawnAt = normalPlayerDisguise ? loc : observer.getLocation().add(observer.getLocation().getDirection().normalize().multiply(10));
        // Spawn him in front of the observer
        StructureModifier<Double> doubles = spawnPlayer.getDoubles();
        doubles.write(0, spawnAt.getX());
        doubles.write(1, spawnAt.getY());
        doubles.write(2, spawnAt.getZ());
        StructureModifier<Byte> bytes = spawnPlayer.getBytes();
        bytes.write(0, yaw);
        bytes.write(1, pitch);
        packets.addPacket(spawnPlayer);
        WrappedDataWatcher toSend;
        if (!normalPlayerDisguise) {
            toSend = new WrappedDataWatcher();
            WrappedDataWatcher.WrappedDataWatcherObject obj = ReflectionManager.createDataWatcherObject(MetaIndex.ENTITY_META, (byte) 32);
            // Set invis
            toSend.setObject(obj, (byte) 32);
        } else {
            toSend = DisguiseUtilities.createSanitizedDataWatcher(observer, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher());
        }
        if (NmsVersion.v1_15.isSupported()) {
            PacketContainer metaPacket = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, entityId, toSend, true).createPacket(entityId, toSend, true);
            packets.addPacket(metaPacket);
        } else {
            spawnPlayer.getDataWatcherModifier().write(0, toSend);
        }
    } else if (disguise.isMobDisguise() || disguise.getType() == DisguiseType.ARMOR_STAND) {
        Vector vec = disguisedEntity.getVelocity();
        if (disguise.getType() == DisguiseType.SQUID && disguisedEntity.getType() != EntityType.SQUID) {
            vec = new Vector();
        }
        PacketContainer spawnEntity = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING);
        packets.addPacket(spawnEntity);
        StructureModifier<Object> mods = spawnEntity.getModifier();
        mods.write(0, disguisedEntity.getEntityId());
        mods.write(1, disguise.getUUID());
        if (!disguise.getType().isCustom()) {
            mods.write(2, disguise.getType().getTypeId());
        } else {
            mods.write(2, ((ModdedDisguise) disguise).getModdedEntity().getTypeId());
        }
        // region Vector calculations
        double d1 = 3.9D;
        double d2 = vec.getX();
        double d3 = vec.getY();
        double d4 = vec.getZ();
        if (d2 < -d1) {
            d2 = -d1;
        }
        if (d3 < -d1) {
            d3 = -d1;
        }
        if (d4 < -d1) {
            d4 = -d1;
        }
        if (d2 > d1) {
            d2 = d1;
        }
        if (d3 > d1) {
            d3 = d1;
        }
        if (d4 > d1) {
            d4 = d1;
        }
        // endregion
        mods.write(3, loc.getX());
        mods.write(4, loc.getY());
        mods.write(5, loc.getZ());
        mods.write(6, (int) (d2 * 8000.0D));
        mods.write(7, (int) (d3 * 8000.0D));
        mods.write(8, (int) (d4 * 8000.0D));
        mods.write(9, yaw);
        mods.write(10, pitch);
        mods.write(11, yaw);
        WrappedDataWatcher newWatcher = DisguiseUtilities.createSanitizedDataWatcher(observer, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher());
        if (NmsVersion.v1_15.isSupported()) {
            PacketContainer metaPacket = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, disguisedEntity.getEntityId(), newWatcher, true).createPacket(disguisedEntity.getEntityId(), newWatcher, true);
            packets.addPacket(metaPacket);
        } else {
            spawnEntity.getDataWatcherModifier().write(0, newWatcher);
        }
    } else if (disguise.getType().isMisc()) {
        int data = ((MiscDisguise) disguise).getData();
        double x = loc.getX();
        double y = loc.getY();
        double z = loc.getZ();
        if (disguise.getType() == DisguiseType.FALLING_BLOCK) {
            data = ((FallingBlockWatcher) disguise.getWatcher()).getBlockCombinedId();
            if (((FallingBlockWatcher) disguise.getWatcher()).isGridLocked()) {
                double yMod = disguise.getWatcher().getYModifier();
                y -= yMod;
                // Center the block
                x = loc.getBlockX() + 0.5;
                y = Math.floor(y) + yMod + (y % 1 >= 0.85 ? 1 : y % 1 >= 0.35 ? .5 : 0);
                z = loc.getBlockZ() + 0.5;
            }
        } else if (disguise.getType() == DisguiseType.FISHING_HOOK && data == -1) {
            // If the MiscDisguise data isn't set. Then no entity id was provided, so default to the owners
            // entity id
            data = observer.getEntityId();
        } else if (disguise.getType() == DisguiseType.ITEM_FRAME) {
            data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4;
        }
        PacketContainer spawnEntity;
        if (NmsVersion.v1_14.isSupported()) {
            Object entityType;
            if (disguise.isCustomDisguise()) {
                entityType = ((ModdedDisguise) disguise).getModdedEntity().getEntityType();
            } else {
                entityType = ReflectionManager.getEntityType(disguise.getType().getEntityType());
            }
            Object[] params = new Object[] { disguisedEntity.getEntityId(), disguise.getUUID(), x, y, z, loc.getPitch(), loc.getYaw(), entityType, data, ReflectionManager.getVec3D(disguisedEntity.getVelocity()) };
            spawnEntity = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, params).createPacket(params);
        } else {
            int objectId = disguise.getType().getObjectId();
            if (disguise.isCustomDisguise()) {
                objectId = ((ModdedDisguise) disguise).getModdedEntity().getTypeId();
            }
            Object nmsEntity = ReflectionManager.getNmsEntity(disguisedEntity);
            spawnEntity = ProtocolLibrary.getProtocolManager().createPacketConstructor(PacketType.Play.Server.SPAWN_ENTITY, nmsEntity, objectId, data).createPacket(nmsEntity, objectId, data);
            StructureModifier<Double> doubles = spawnEntity.getDoubles();
            doubles.write(0, x);
            doubles.write(1, y);
            doubles.write(2, z);
        }
        spawnEntity.getModifier().write(8, pitch);
        spawnEntity.getModifier().write(9, yaw);
        packets.addPacket(spawnEntity);
        // cancel
        if (DisguiseType.getType(disguisedEntity) != disguise.getType()) {
            StructureModifier<Integer> ints = spawnEntity.getIntegers();
            ints.write(1, 0);
            ints.write(2, 0);
            ints.write(3, 0);
            if (disguise.getType() == DisguiseType.DROPPED_ITEM) {
                PacketContainer velocity = new PacketContainer(PacketType.Play.Server.ENTITY_VELOCITY);
                velocity.getIntegers().write(0, disguisedEntity.getEntityId());
                packets.addPacket(velocity);
            }
        }
        if (disguise.getType() == DisguiseType.ITEM_FRAME) {
            if (data % 2 == 0) {
                spawnEntity.getModifier().write(4, loc.getZ() + (data == 0 ? -1 : 1));
            } else {
                spawnEntity.getModifier().write(2, loc.getX() + (data == 3 ? -1 : 1));
            }
        }
    }
    if (packets.getPackets().size() <= 1 || disguise.isPlayerDisguise()) {
        PacketContainer rotateHead = new PacketContainer(PacketType.Play.Server.ENTITY_HEAD_ROTATION);
        StructureModifier<Object> mods = rotateHead.getModifier();
        if (!DisguiseUtilities.isRunningPaper()) {
            packets.addPacket(rotateHead);
        } else {
            packets.addDelayedPacket(rotateHead, 10);
        }
        mods.write(0, disguisedEntity.getEntityId());
        mods.write(1, yaw);
    }
    if (disguise.getType() == DisguiseType.EVOKER_FANGS) {
        PacketContainer newPacket = new PacketContainer(PacketType.Play.Server.ENTITY_STATUS);
        StructureModifier<Object> mods = newPacket.getModifier();
        mods.write(0, disguise.getEntity().getEntityId());
        mods.write(1, (byte) 4);
        packets.addPacket(newPacket);
    }
    if (DisguiseConfig.isMiscDisguisesForLivingEnabled()) {
        if (disguise.getWatcher() instanceof LivingWatcher) {
            ArrayList<WrappedAttribute> attributes = new ArrayList<>();
            WrappedAttribute.Builder builder = WrappedAttribute.newBuilder().attributeKey(NmsVersion.v1_16.isSupported() ? "generic.max_health" : "generic.maxHealth");
            if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
                builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
            } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity() && disguisedEntity instanceof Damageable) {
                builder.baseValue(((Damageable) disguisedEntity).getMaxHealth());
            } else {
                builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
            }
            PacketContainer packet = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
            builder.packet(packet);
            attributes.add(builder.build());
            packet.getIntegers().write(0, disguisedEntity.getEntityId());
            packet.getAttributeCollectionModifier().write(0, attributes);
            packets.addPacket(packet);
        }
    }
    if (!disguise.isPlayerDisguise() || normalPlayerDisguise) {
        DisguiseUtilities.getNamePackets(disguise, new String[0]).forEach(packets::addPacket);
    }
    // This sends the armor packets so that the player isn't naked.
    if (DisguiseConfig.isEquipmentPacketsEnabled()) {
        for (EquipmentSlot slot : EquipmentSlot.values()) {
            // Get what the disguise wants to show for its armor
            ItemStack itemToSend = disguise.getWatcher().getItemStack(slot);
            // If the disguise armor isn't visible
            if (itemToSend == null) {
                itemToSend = ReflectionManager.getEquipment(slot, disguisedEntity);
                // If natural armor isn't sent either
                if (itemToSend == null || itemToSend.getType() == Material.AIR) {
                    continue;
                }
            } else if (itemToSend.getType() == Material.AIR) {
                // Its air which shouldn't be sent
                continue;
            }
            PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_EQUIPMENT);
            StructureModifier<Object> mods = packet.getModifier();
            mods.write(0, disguisedEntity.getEntityId());
            if (NmsVersion.v1_16.isSupported()) {
                List<Pair<Object, Object>> list = new ArrayList<>();
                list.add(Pair.of(ReflectionManager.createEnumItemSlot(slot), ReflectionManager.getNmsItem(itemToSend)));
                mods.write(1, list);
            } else {
                mods.write(1, ReflectionManager.createEnumItemSlot(slot));
                mods.write(2, ReflectionManager.getNmsItem(itemToSend));
            }
            packets.addDelayedPacket(packet);
        }
    }
}
Also used : FallingBlockWatcher(me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher) ModdedDisguise(me.libraryaddict.disguise.disguisetypes.ModdedDisguise) Damageable(org.bukkit.entity.Damageable) ProtocolLibrary(com.comphenix.protocol.ProtocolLibrary) Disguise(me.libraryaddict.disguise.disguisetypes.Disguise) Art(org.bukkit.Art) Player(org.bukkit.entity.Player) PlayerSkinHandler(me.libraryaddict.disguise.utilities.listeners.PlayerSkinHandler) StructureModifier(com.comphenix.protocol.reflect.StructureModifier) WrappedDataWatcher(com.comphenix.protocol.wrappers.WrappedDataWatcher) ArrayList(java.util.ArrayList) Location(org.bukkit.Location) LivingWatcher(me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher) IPacketHandler(me.libraryaddict.disguise.utilities.packets.IPacketHandler) MiscDisguise(me.libraryaddict.disguise.disguisetypes.MiscDisguise) NmsVersion(me.libraryaddict.disguise.utilities.reflection.NmsVersion) Material(org.bukkit.Material) EquipmentSlot(org.bukkit.inventory.EquipmentSlot) ReflectionManager(me.libraryaddict.disguise.utilities.reflection.ReflectionManager) Entity(org.bukkit.entity.Entity) DisguiseType(me.libraryaddict.disguise.disguisetypes.DisguiseType) WrappedAttribute(com.comphenix.protocol.wrappers.WrappedAttribute) PacketType(com.comphenix.protocol.PacketType) EntityType(org.bukkit.entity.EntityType) Pair(com.mojang.datafixers.util.Pair) ItemStack(org.bukkit.inventory.ItemStack) LibsDisguises(me.libraryaddict.disguise.LibsDisguises) Vector(org.bukkit.util.Vector) PacketContainer(com.comphenix.protocol.events.PacketContainer) DisguiseUtilities(me.libraryaddict.disguise.utilities.DisguiseUtilities) List(java.util.List) DisguiseConfig(me.libraryaddict.disguise.DisguiseConfig) PacketsHandler(me.libraryaddict.disguise.utilities.packets.PacketsHandler) LibsPremium(me.libraryaddict.disguise.utilities.LibsPremium) LibsPackets(me.libraryaddict.disguise.utilities.packets.LibsPackets) Collections(java.util.Collections) DisguiseValues(me.libraryaddict.disguise.utilities.DisguiseValues) MetaIndex(me.libraryaddict.disguise.disguisetypes.MetaIndex) PlayerDisguise(me.libraryaddict.disguise.disguisetypes.PlayerDisguise) ModdedDisguise(me.libraryaddict.disguise.disguisetypes.ModdedDisguise) Disguise(me.libraryaddict.disguise.disguisetypes.Disguise) MiscDisguise(me.libraryaddict.disguise.disguisetypes.MiscDisguise) PlayerDisguise(me.libraryaddict.disguise.disguisetypes.PlayerDisguise) PacketContainer(com.comphenix.protocol.events.PacketContainer) StructureModifier(com.comphenix.protocol.reflect.StructureModifier) ArrayList(java.util.ArrayList) EquipmentSlot(org.bukkit.inventory.EquipmentSlot) LivingWatcher(me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher) ModdedDisguise(me.libraryaddict.disguise.disguisetypes.ModdedDisguise) ArrayList(java.util.ArrayList) List(java.util.List) WrappedDataWatcher(com.comphenix.protocol.wrappers.WrappedDataWatcher) Vector(org.bukkit.util.Vector) PlayerSkinHandler(me.libraryaddict.disguise.utilities.listeners.PlayerSkinHandler) Pair(com.mojang.datafixers.util.Pair) MiscDisguise(me.libraryaddict.disguise.disguisetypes.MiscDisguise) Damageable(org.bukkit.entity.Damageable) FallingBlockWatcher(me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher) PlayerDisguise(me.libraryaddict.disguise.disguisetypes.PlayerDisguise) WrappedAttribute(com.comphenix.protocol.wrappers.WrappedAttribute) ItemStack(org.bukkit.inventory.ItemStack) Location(org.bukkit.Location)

Aggregations

StructureModifier (com.comphenix.protocol.reflect.StructureModifier)6 PacketContainer (com.comphenix.protocol.events.PacketContainer)4 Disguise (me.libraryaddict.disguise.disguisetypes.Disguise)4 Player (org.bukkit.entity.Player)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Location (org.bukkit.Location)3 ItemStack (org.bukkit.inventory.ItemStack)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 PlayerDisguise (me.libraryaddict.disguise.disguisetypes.PlayerDisguise)2 LibsPackets (me.libraryaddict.disguise.utilities.packets.LibsPackets)2 Vector (org.bukkit.util.Vector)2 PacketType (com.comphenix.protocol.PacketType)1 ProtocolLibrary (com.comphenix.protocol.ProtocolLibrary)1 WrappedAttribute (com.comphenix.protocol.wrappers.WrappedAttribute)1 WrappedDataWatcher (com.comphenix.protocol.wrappers.WrappedDataWatcher)1 WrappedWatchableObject (com.comphenix.protocol.wrappers.WrappedWatchableObject)1 Pair (com.mojang.datafixers.util.Pair)1 ChunkBlocks (com.vanillage.raytraceantixray.data.ChunkBlocks)1 PlayerData (com.vanillage.raytraceantixray.data.PlayerData)1