1.17.x NPC Right Click

Discussion in 'Spigot Plugin Development' started by SouprP, Jul 6, 2021.

Thread Status:
Not open for further replies.
  1. Hello, I'm creating an NPC for my banker plugin and I can't figure out what field from PacketPlayInUseEntity sends info about right clicking an NPC. I've already looked into 1.17 NMS mappings, but still couldnt find an anwser.

    Code (Text):
    package me.SouprPK.NPC;

    import java.lang.reflect.Field;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;

    import org.bukkit.Bukkit;
    import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
    import org.bukkit.entity.Player;

    import io.netty.channel.Channel;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.handler.codec.MessageToMessageDecoder;
    import me.SouprPK.Main.Main;
    import net.minecraft.network.protocol.Packet;
    import net.minecraft.network.protocol.game.PacketPlayInUseEntity;
    import net.minecraft.server.level.EntityPlayer;

    public class PacketReader {

        Channel channel;
        public static Map<UUID, Channel> channels = new HashMap<UUID, Channel>();
        public void inject(Player player) {
            CraftPlayer craftPlayer = (CraftPlayer) player;
            channel = craftPlayer.getHandle().b.a.k;
            channels.put(player.getUniqueId(), channel);
            if(channel.pipeline().get("PacketInjector") != null)
            channel.pipeline().addAfter("decoder", "PacketInjector", new MessageToMessageDecoder<PacketPlayInUseEntity>(){

                protected void decode(ChannelHandlerContext channel, PacketPlayInUseEntity packet, List<Object> arg) throws Exception {
                    readPacket(player, packet);
        public void uninject(Player player) {
            channel = channels.get(player.getUniqueId());
            if(channel.pipeline().get("PacketInjector") != null) {
        public void readPacket(Player player, Packet<?> packet) {
            if(packet.getClass().getSimpleName().equalsIgnoreCase("PacketPlayInUseEntity")) {
                if(getValue(packet, "b").toString().equalsIgnoreCase("ATTACK")) // ATTACK  b?
                if(getValue(packet, "d").toString().equalsIgnoreCase("OFF_HAND")) // OFF_HAND  a?
                if(getValue(packet, "b").toString().equalsIgnoreCase("INTERACT_AT"))  // INTERACT_AT  c?
                int id = (int) getValue(packet, "a");
                if(getValue(packet, "b").toString().equalsIgnoreCase("INTERACT")) {  // "INTERACT"? or "b"?
                    System.out.println("I got the packet!");
                    for (EntityPlayer npc : NPC.getNPCs()) {
                        if (npc.getId() == id) {
                            Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getPlugin(Main.class), new Runnable() {
                                public void run() {
                                    Bukkit.getPluginManager().callEvent(new RightClickNPC(player, npc));
                            }, 0);
        private Object getValue(Object instance, String name) {
            Object result = null;
            try {
                Field field = instance.getClass().getDeclaredField(name);
                result = field.get(instance);
            } catch(Exception e) {
            // Checking if b is equal to interacting with right hand
            if(name.equalsIgnoreCase("b")) {
                if(result.toString().equalsIgnoreCase("INTERACT")) // b? or INTERACT?
                  System.out.println("OBJECT FIELD VALUE IS >> " + result.toString());
            return result;
Thread Status:
Not open for further replies.