1.15.2 [ProtocolLib] Sending ENTITY_EFFECT Packets

Discussion in 'Spigot Plugin Development' started by Swedz, Feb 22, 2020.

  1. I have already created a system of spawning fake entities that are only visible to some players. This works all fine and dandy, but when I wanted to give an entity a potion effect, I ran into a roadblock. Currently, I'm trying to iterate over my list of PotionEffects that I want applied and just sending the ENTITY_EFFECT packet with all the fields as defined in PacketPlayOutEntityEffect. There is no error posted in the logs. Here's the code of what I'm doing so far:
    Code (Java):
    for(PotionEffect potionEffect : this.getPotionEffects()) {
        System.out.println("[DEBUG] sending potion effect: " + potionEffect.toString());
        PacketContainer potionPacket = new PacketContainer(PacketType.Play.Server.ENTITY_EFFECT);
        potionPacket.getIntegers()
                .write(0, this.getEntityId())
                .write(1, potionEffect.getDuration() > Short.MAX_VALUE ? Short.MAX_VALUE : potionEffect.getDuration());
        potionPacket.getBytes()
                .write(0, (byte) (potionEffect.getType().getId() & 255))
                .write(1, (byte) (potionEffect.getAmplifier() & 255))
                .write(2,
                        (byte) ((potionEffect.isAmbient() ? (byte) 0x1 : (byte) 0x0) |
                        (potionEffect.hasParticles() ? (byte) 0x2 : (byte) 0x0) |
                        (potionEffect.hasIcon() ? (byte) 0x4 : (byte) 0x0)));
        packets.add(potionPacket);
    }
    Note that, yes, the debug message is posted, and it says the PotionEffect's values as intended. I am testing it with INVISIBILITY to start off with so that I can see it taking effect if I were to have particles disabled by accident, or something (which is not the case).

    Any help is appreciated :)

    EDIT:
    I just tried using NMS instead and... same results! No potion effect applied and no errors either.
    Code (Java):
    MobEffect mobEffect = new MobEffect(MobEffectList.fromId(potionEffect.getType().getId()),
            potionEffect.getDuration(), potionEffect.getAmplifier(),
            potionEffect.isAmbient(), potionEffect.hasParticles(), potionEffect.hasIcon());
    PacketPlayOutEntityEffect effectPacket = new PacketPlayOutEntityEffect(this.getEntityId(), mobEffect);
    for(Player viewer : this.getViewers()) {
        ((CraftPlayer) viewer).getHandle().playerConnection.sendPacket(effectPacket);
    }
    EDIT2:
    Also note that the packets variable (from the first code block) is a List of PacketContainers that get sent to a list of players in the order that they were inserted. All the other packets in this list work as intended except for this one.
     
    #1 Swedz, Feb 22, 2020
    Last edited: Feb 23, 2020
  2. Bump - I’m not going to be able to respond for a couple/few hours so I’ll get back to anyone who responds then.
     
  3. Hey Swedz!

    If I remember correctly that information needs to be sent along in the EntityMetadata packet but not on my PC to check it out. I use that packet for making invisible armor stands and such for holograms for specific players.
     
  4. Yep. In the entity metadata you can have a byte field of 0x20 to have the invisibility tag. However I’m looking for potion effects not the invisibility tag.

    EDIT:
    I just checked the metadata thing and I was right. [​IMG]
    I also checked the living entity metadata and it seems to only have possibility for potion effect colors and ambient effects. No potion effects in it of themselves.
    [​IMG]
     
    #4 Swedz, Feb 23, 2020
    Last edited: Feb 23, 2020
  5. I still need a solution to this! PacketPlayOutRemoveEntityEffect has a field with the type MobEffectList, but in ProtocolLib I can't find any wrapper for reading/writing that object type. I really don't want to have to deal with NMS, so I'm not sure where to go from there. I found this github issue for ProtocolLib, and I don't understand what to do with what dmulloy2 said. Hopefully someone can help me figure this out.