Search code examples
javabukkit

EntityMetadata packet issue


I am attempting to make a player appear like they are sneaking (crouching) on Minecraft 1.8.8 running Spigot, based on http://wiki.vg/Entities#Entity_Metadata_Format I have done the following:

Created a data watcher and mapped appropriate value for crouched from the wiki:

DataWatcher dw = new DataWatcher(null);
dw.a(0, (byte) 0x02);

Created the packet, where target is a Player object of the player that needs to appear sneaking:

PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(target.getEntityId(), dw, false);

Sent the packet to everyone online:

for (Player p : Bukkit.getOnlinePlayers()) {
    ((CraftPlayer) p).getHandle().playerConnection.sendPacket(metadataPacket);
}

This does not appear to be working though, how would be the appropriate way to go about this?

I attempted to use ProtocolLib too, though ideally I am looking for a solution that works using packets.


Solution

  • The problem is that you use the wrong method for updating. There is a internal boolean in the datawatcher that checks for updates. There are 2 ways solving this problem.

    Using DataWatcher#watch:

    Player target = Bukkit.getPlayer("RandomGuy");
    DataWatcher dw = ((CraftPlayer) target).getHandle().getDataWatcher();
    dw.watch(0, (byte) 2);
    PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(target.getEntityId(), dw, false);
    //sending packet...
    

    Skipping the internal boolean (not recommended):

    Player target = Bukkit.getPlayer("RandomGuy");
    DataWatcher dw = ((CraftPlayer) target).getHandle().getDataWatcher();
    dw.a(0, (byte) 2);
    PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(target.getEntityId(), dw, true);
    //sending packet...
    

    P.S. If that is a fake entity, I'd recommend instantiating a reference of an EntityPlayer for better packet control.