Making a Book Open Automatically

Discussion in 'Plugin Development' started by Piesrgr8, Jun 7, 2017.

Thread Status:
Not open for further replies.
  1. Offline

    Piesrgr8

    Ive seen this happen on hypixel where if someone wants to vote for the server, a book will appear in their inventory and then disappear, then afterwards it opens the book that was in the inventory.

    I've seen some random forums about book gui's and some people say that you can do it server side, but then there are some that say its only client side. What is the truth, since its 1.9 that im working with??? Can I make this possible?
     
  2. I think you may be able to do it with openInventory...
     
  3. Offline

    timtower Administrator Administrator Moderator

    @MGlolenstine Book isn't really an inventory though.
    @Piesrgr8 If this is possible then it will high likely require Packets.
     
  4. Well... Sorry... My limited knowledge is killing me ;)

    Sent from my E2303 using Tapatalk
     
  5. Offline

    Piesrgr8

    @timtower How could I achieve this with packets? All I have is that old method that was used from a different forum post.
     
    Last edited: Jun 8, 2017
  6. Offline

    Horsey

  7. Offline

    Piesrgr8

    Oh boy, I wasn't expecting to use an api just to open the book, but I guess I can use it and see if it works.
     
  8. Offline

    Horsey

    That's not an API, it's a utility class.
     
  9. Offline

    Desle

    Hey,

    I think this code still works but I'm not sure. I've used it for a plugin once.
    Code:
        public void openBook() {     
            int slot = this.player.getInventory().getHeldItemSlot();
            ItemStack item = this.player.getInventory().getItem(slot);
          
            this.player.getInventory().setItem(slot, getBook());
      
           ByteBuf buf = Unpooled.buffer(256);
           buf.setByte(0, (byte)0);
           buf.writerIndex(1);
      
            PacketPlayOutCustomPayload packet = new PacketPlayOutCustomPayload("MC|BOpen", new PacketDataSerializer(buf));
            ((CraftPlayer) this.player).getHandle().playerConnection.sendPacket(packet);
          
            this.player.getInventory().setItem(slot, item);
        }
    If you need to see the whole class and it's methods this code might be using;
    https://pastebin.com/fTxuwQwh
     
  10. @Desle
    Can confirm that this works in 1.12, although I think it'd be a bit better to populate the PacketDataSerializer like this:
    Code:java
    1. PacketDataSerializer dataSerializer = new PacketDataSerializer(Unpooled.buffer());
    2. // PacketDataSerializer#a(Enum) = writeEnum
    3. // It basically just writes a VarInt with the index of the enum constant to the buffer
    4. dataSerializer.a(EnumHand.MAIN_HAND);
    5. new PacketPlayOutCustomPayload(..., dataSerializer);
    Because it actually gives a clue as to what is being written. The VarInt you're writing (but you're doing a byte, which works when the VarInt takes up 7 bits or less) is actually detailing which hand the book is being opened in, 0 for EnumHand.MAIN_HAND, and 1 for EnumHand.OFF_HAND

    @Horsey's method is also viable (although that Util class is monstrously large). It basically boils down to this (but the Util one uses reflection, so more version independent):
    Code:java
    1. // The ItemStack argument is a bit weird, it doesn't matter which ItemStack you put in, just that it's a Written Book
    2. // In reality, it's the item in whichever EnumHand specified that will be opened.
    3. ((CraftPlayer) sender).getHandle().a(new net.minecraft.server.v1_12_R1.ItemStack(Items.WRITTEN_BOOK), EnumHand.MAIN_HAND);


    @Piesrgr8
    Both of these methods are perfectly usable, so pick whichever one you feel more accustomed to. But do remember that these use NMS and will break with every single update, unless you edit them to use reflection (or use the unwieldy util class in the spigot thread, but I wouldn't recommend that).
     
    Zombie_Striker likes this.
  11. Offline

    Piesrgr8

    @Desle That is the same exact method that I was talking about, and it doesnt work.
    @AlvinB Im using this in one plugin that has a ton of stuff in it already, and my server uses viaversions, which is a plugin that allows people that uses versions 1.9 to 1.12, so I cant use anything that will be version independent.
     
  12. Offline

    timtower Administrator Administrator Moderator

    Locked
    Protocol hacks are not supported by Bukkit.
     
Thread Status:
Not open for further replies.

Share This Page