TinyProtocol: PacketPlayOutPlayerInfo

Discussion in 'Spigot Plugin Development' started by konsolas, May 25, 2015.

  1. konsolas


    I've been trying to send a PacketPlayOutPlayerInfo with https://github.com/aadnk/ProtocolLi...ocol/src/main/java/com/comphenix/tinyprotocol

    Apparently, on http://wiki.vg/ it is "documented" as Player List Item. To spawn a player, one must first send this packet, adding the player to the tab list and then send a PacketPlayOutNamedEntitySpawn. The first two fields are simple enough, but the rest of the packet is an array.

    So my question: How do I send an array as a field in a packet, with TinyProtocol

    PS: Please don't reply saying "give up while you can". It's okay if you don't think I should be using this, but I'm asking a question and I don't really want to hear it.
  2. konsolas


    Bump. Does anyone know?
  3. The array is constructed by a PlayerInfoData object. These PlayerInfoData objects are stored in PacketPlayOutPlayerInfo.b (= List<PlayerInfoData>).

    PlayerInfoData looks like this:

    or {nms}.PacketPlayOutPlayerInfo.PlayerInfoData
    Code (Text):
    public class PlayerInfoData {
        private final int b;
        private final WorldSettings.EnumGamemode c;
        private final GameProfile d;
        private final IChatBaseComponent e;

        public PlayerInfoData(GameProfile d, int b, WorldSettings.EnumGamemode c, IChatBaseComponent e) {
          this.d = d;
          this.b = b;
          this.c = c;
          this.e = e;

        public GameProfile a() {
          return this.d;

        public int b() {
          return this.b;

        public WorldSettings.EnumGamemode c() {
          return this.c;

        public IChatBaseComponent d()
          return this.e;

        public String toString()
          return Objects.toStringHelper(this).add("latency", this.b).add("gameMode", this.c).add("profile", this.d).add("displayName", this.e == null ? null : IChatBaseComponent.ChatSerializer.a(this.e)).toString();
    You should be able to inject the data you need in these objects and send them ;)

    Good Luck!
    • Like Like x 1
  4. konsolas


    Thanks for the help, that's awesome. Is this possible to do using TinyProtocol's packet sending mechanism?

    For example, could I have a field accessor like:
    Code (Text):
    private Reflection.FieldAccessor<List> infoArray = Reflection.getField(playerInfoClass, List.class, 0);
    And set that to a list of my own PlayerInfoData structure (i'm trying to avoid using NMS).

    (But then I'd have to create a gameprofile class, and a chat component class *sigh*).
  5. 1. Yeah, you can set that to your own List
    2a. Try modifying the existing GameProfile. You can get it by calling ((CraftPlayer)player).getProfile()
    2b. No need to do so. Use IChatComponentBase.serialize("{text:\"Your text of the ChatComponent goes here\"}");
  6. konsolas


    Now would probably be a good time to mention I'm trying to spawn a fake player.

    I'm able to create a GameProfile object through ProtocolLib's wrappers,
    Code (Text):
    WrappedGameProfile profile = new WrappedGameProfile(uuid, name);
    However, i'd quite like to avoid using the GameProfile class, or the IChatComponentBase class. Is there a way to do this without using NMS?
  7. Every player needs an NMS object. Its not like a creeper which is just there. A player has additional data that has to be delivered. You cant say i want the player to have a name, but i dont want to send it. There is no other way sry. Why do you want to avoid it? Its pretty simple.
  8. It doesnt even have to be version dependent. Just use reflection like you already did before. And you need no WrappedGameProfile or stuff like that. Just create a plain one using reflection.
  9. konsolas


    I see. I'll try that then. Thanks.