1.12.2 Nametags with packets

Discussion in 'Spigot Plugin Development' started by LetsHacks, Feb 2, 2020.

  1. Hello everyone,

    so what I want to do is sending (colored) nametags with packets to players.

    I tried using this:

    Code (Java):
    public class NameTags {


        private static Class<?> getNMSClass(String name) {
            String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
            try {
                return Class.forName("net.minecraft.server." + version + "." + name);
            } catch (ClassNotFoundException var3) {
                var3.printStackTrace();
                return null;
            }
        }

        private static void sendPacket(Player player, Object packet) {
            try {
                Object handle = player.getClass().getMethod("getHandle").invoke(player);
                Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
                playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet);
            } catch (Exception var4) {
                var4.printStackTrace();
            }

        }

        private static void setField(Object packet, Field field, Object value) {
            field.setAccessible(true);

            try {
                field.set(packet, value);
            } catch (IllegalAccessException | IllegalArgumentException var4) {
                var4.printStackTrace();
            }

            field.setAccessible(!field.isAccessible());
        }

        private static Field getField(Class<?> classs, String fieldname) {
            try {
                return classs.getDeclaredField(fieldname);
            } catch (SecurityException | NoSuchFieldException var3) {
                var3.printStackTrace();
                return null;
            }
        }

        public static void sendNameTagPlayers(Player player, String prefix, String suffix, Player players, int priority) {
            String pname = player.getName();
            String name = "" + priority + pname.charAt(0) + UUID.randomUUID().toString().substring(0, 10);
            List<String> pl = new ArrayList();
            pl.add(player.getName());
            PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam();
            Class<? extends PacketPlayOutScoreboardTeam> clas = packet.getClass();
       
            setField(packet, getField(clas, "a"), name);
            setField(packet, getField(clas, "b"), new ChatComponentText(player.getName()));
            setField(packet, getField(clas, "c"), new ChatComponentText(prefix));
            setField(packet, getField(clas, "d"), new ChatComponentText(suffix));
            setField(packet, getField(clas, "e"), "ALWAYS");
            setField(packet, getField(clas, "h"), pl);
            setField(packet, getField(clas, "i"), 0);

            sendPacket(players, packet);
        }

        public static void sendNameTags(Player player, String prefix, String suffix, int priority) {

            for (Player all : Bukkit.getOnlinePlayers()) {
                sendNameTagPlayers(player, prefix, suffix, all, priority);
            }

        }


    }

    But unfortunately it throws an IllegalArgumentException, that the fields cannot be set:
    https://hasteb.in/ocifodas.md
    And so it doesnt work :(

    Notice: I am using 1.12.2 paper spigot.

    Thanks for your help!
     
    • Funny Funny x 1
  2. Well, the error basically already explains your problem.
    Can not set java.lang.String field net.minecraft.server.v1_12_R1.PacketPlayOutScoreboardTeam.b to net.minecraft.server.v1_12_R1.ChatComponentText
    means that you're trying to set a field, with something which is not the same class. I'm guessing you copied this code from somewhere. Either way, the field you're trying to set are still normal Strings in 1.12(.2), only since 1.13, it has become an IChatBaseComponent, in which case it would work. So instead of inputting a ChatComponent, just input a string, and that will fix it. You would also know this if you would've decompiled the PacketPlayOutScoreboardTeam class and looked at the fields.
     
  3. Okay,
    thank you very much for your help.
    It works now