Compatibility for Anvil GUI's for clients running 1.7.10/1.8?

Discussion in 'Spigot Plugin Development' started by Adamki11s, Mar 6, 2015.

  1. I'm running Spigot build #1646, which allows both clients running MC 1.7.10 and 1.8 to join. However the protocol for opening inventories has changed. Opening anvil's for clients on 1.7.8 as follows works fine.


    Code (Text):
    EntityPlayer p = ((CraftPlayer) player).getHandle();

    AnvilContainer container = new AnvilContainer(p);

    int c = p.nextContainerCounter();

    p.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c, 8, "Repairing", 9, true));
    However trying to use that code for 1.8 only opens a standard inventory.

    I have tried using protocol lib to adapt to the new protocol as shown below, but I just get FieldAccessExceptions when trying to set the chat component.

    Code (Text):
    PacketContainer packet = protocolManager.createPacket(PacketType.Play.Server.OPEN_WINDOW);

                packet.getIntegers().write(0, c);
                packet.getStrings().write(0, "minecraft:anvil");
                packet.getChatComponents().write(0, WrappedChatComponent.fromJson("{\"text\": \"" + "Title here" + "\"}"));
                packet.getIntegers().write(1, 0);

                try {
                   protocolManager.sendServerPacket(player, packet);
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
    Any help would be great?
     
  2. Can anyone shed some light?
     
  3. @Adamki11s the issue occurs because you try to use ProtocolLib (which uses the 1.7 protocol as it's a 1.7 Spigot) with the 1.8 protocol :p. The 1.7 packet object has no IChatBaseComponent fields. A quick comparison of the 1.7 and 1.8 packet fields:

    The 1.7 protocol
    • private int a;
    • private int b;
    • private String c;
    • private int d;
    • private boolean e;
    • private int f;
    The 1.8 protocol
    • private int a;
    • private int a;
    • private String b;
    • private IChatBaseComponent c;
    • private int d;
    • private int e;
    Function of the different fields
    • Both the first int fields are the inventory IDs.
    • Field b is in both protocols the inventory type.
    • Field c is in both protocols the inventory name. For the default name, you could pass the translation entry (I checked the default name for hopper, it was 'container.hopper'. I'm assuming it works the same for the other containers).
    • Field d is the inventory size.
    • The boolean field e in the 1.7 protocol holds whether the inventory has a custom name. This is obsolete for the 1.8 protocol as it always transfers an IChatBaseComponent.
    • The last int field (f in 1.7, 3 in 1.8) holds the entity ID of the entity that holds the inventory. This is only set if the inventory belongs to a horse.