PacketPlayOutNamedEntitySpawn - packet help.

Discussion in 'Spigot Plugin Development' started by Moderance, Apr 20, 2017.

  1. In short; I am wanting to color player names, I am using packets rather than teams as players in the same faction should be able to see themselves as green name tags, whereas others red.

    Here's my code;

    Code (Text):

    public static void updatePlayerColors() {
            for (Player player : Bukkit.getOnlinePlayers()) {
                for (Player target : Bukkit.getOnlinePlayers()) {
                    EntityPlayer entityTarget = ((CraftPlayer) target).getHandle();
                    PacketPlayOutNamedEntitySpawn packet = new PacketPlayOutNamedEntitySpawn(entityTarget);
               
                    try {
                        Field field = packet.getClass().getDeclaredField("b");
                        field.setAccessible(true);
                   
                        Object gameProfile = field.get(packet);
                        Field name = gameProfile.getClass().getDeclaredField("name");
                   
                        name.setAccessible(true);
                        name.set(gameProfile, color("&c" + target.getName()));
                        //TODO if same faction, make green instead.
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                       
                    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
                    entityTarget.displayName = target.getName(); // trying to put it back to normal?
                }
            }
        }
     
    Problems:

    Whenever I use player.getName() it returns their colored version.
    Doesn't show up in tab.

    So my question, is there a better way of doing this? Sending players different coloured versions of players names for above their head and on the list.



    Note- using spigot 1.7.10
     
    #1 Moderance, Apr 20, 2017
    Last edited: Apr 20, 2017
  2. So all i understand is, you have player.getName() returning the colored version, but the tablist doesn't contain the color?
     
  3. Yes, tab does not show their colour - I can do this with entityTarget.listName = "..." however I can't send different players different coloured versions of it.
     
  4. Ok, so you can use the listName function for that, so your problem is just sending different colors?
    I see your code just had 1 color available ( &c ) & you send the packet to everyone, what about like sending only 1 player that color and for a test method you create another packet that sends the other player the color for the player with the red color
     
  5. I can change the names above player's head by editing their GameProfile name - but this effects the player.getName() method. That's 1 problem, the next is that it doesn't update in tab.

    I want to be able to send certain players different color versions of the same player's name - so for example everyone in the same faction will be sent a green version, everyone else a red version. (Both for tablist and above their heads).

    I'm sure I can do this, but using a different method than altering GameProfiles.
     
  6. I don't know if this was already implemented in 1.7 but there's a PacketPlayOutPlayerInfo that should solve the tab thing Example here
     
  7. Yes, just checked. So I can remove a real player with PacketPlayOutPlayerInfo.removePlayer(EntityPlayer), then add a fake (copy) of the real player with an altered coloured name, but how would I send this packet to individual players, as all of the methods are static..
     
  8. Found this in the spigot jar

    Code (Text):


      public static PacketPlayOutPlayerInfo removePlayer(EntityPlayer player) {
        PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
        packet.action = 4;
        packet.username = player.listName;
        packet.player = player.getProfile();
        return packet;
      }


     
    So it seems like just returning the packet, you could send that to just specific players

    And the same with addPlayer(EntityPlayer player);

    Edit:

    Found this also maybe it solves your issue better

    Code (Text):


    public static PacketPlayOutPlayerInfo updateDisplayName(EntityPlayer player) {
        PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo();
        packet.action = 3;
        packet.username = player.listName;
        packet.player = player.getProfile();
        return packet;
      }


     
     
  9. Here's what I've done:

    Code (Text):
        public static void updatePlayerColors() {
            for (Player player : Bukkit.getOnlinePlayers()) {
                for (Player target : Bukkit.getOnlinePlayers()) {        
                    EntityPlayer entityTarget = ((CraftPlayer) target).getHandle();
                    PacketPlayOutPlayerInfo packet = PacketPlayOutPlayerInfo.removePlayer(entityTarget);    
                    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
                 
                    entityTarget.displayName = color("&c" + target.getName());
                    entityTarget.listName = color("&c" + target.getName());
                 
                    packet = PacketPlayOutPlayerInfo.addPlayer(entityTarget);    
                    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
                }
            }
        }
    List updates, and player.getName() returns their name uncoloured which it should do, however player nametags are white.

    EDIT: Seems like the list only changed due to entityTarget.listName
     
    #9 Moderance, Apr 20, 2017
    Last edited: Apr 20, 2017