Keep items in crafting slots

Discussion in 'Spigot Plugin Development' started by MrDienns, Jun 11, 2018.

  1. So,

    I'm trying to develop a feature where players can wear rings and necklaces in their crafting slot. But naturally, when the player closes their inventory, the items are either dropped on the ground (which I'm already cancelling), or added back to the main inventory screen.

    How do I make it so that the items aren't actually dropped when they close their inventory? If that's not possible, another option would be to save the items saved in the crafting slot in the database, remove them when the inventory closes, then add them again when the inventory is opened, but since the survival inventory opening is client sided, how should I achieve that?

    Would appreciate some tips.

    Thanks
     
  2. I also had such ideas with the Crafting inventory and tryd several things already.. I checked through so many Packets to see if I can find anything, but nope (maybe there are Packets to use, but I could not find them). And yes the thing with the InventoryOpenEvent.. well maybe that can be fixed sometimes (idk if spigot COULD do so or if mojang has to do smth for this).

    I did it then with the more complicated way of checking the Achievement for first inv open. Yeah you have to give up your Achievement/Advancement system, but It works..

    Edit: And yes I remove the items when closing the inventory, with dropevent.
     
  3. I heard about that achievement thing before, but I was told this doesn't work anymore nowadays. I'm not too sure why. I assume we can just set some kind of client achievement for opening the inventory and just reset it all the time so we force the player to keep sending packets? Unless the achievement system is 100% client sided...

    Edit: It seems like we have this event that will probably help us.
     
  4. I don't think the system is 100% client sided.. would be weird and other things would probably not work either.

    Im not too sure if this still works in 1.12.2 with the advancement system, in 1.8.8 it still works.. I will try this for 1.12.2 if I have time (is there still a inventoryopen advancement in 1.12.2 xD? <-Not playing 1.12 too much right now)
     
  5. The newest versions of Minecraft no longer have those kind of achievement. Nowadays, they're called advancement and the server as able to set up these advancements and give them to the player. We can make our own achievement tree nowadays. If we need an inventory open advancement, we can make one. By all means I'm yet to look into it but I'm pretty sure it's as possible as can be, it just works slightly differently than it used to in older versions. I will give this a shot and let you know.
     
  6. I am at least 70% sure that this is possible.
    These inventory slots are assigned an ID:
    [​IMG]
    As stated here on the wiki. http://wiki.vg/Inventory
    However, it does confirm that no packets are sent by the player when their inventory is opened.
    However, you DO have a packet for a closing inventory (as how we have the event).
    I haven't sifted through the source code myself, but I'd guess that the client only checks the crafting slots to discard the items once (as the inventory is closed).
    Therefore, you MAY be able to set the slots with a bukkit runnable set after the inventory is closed. However, I do not know how you would grab the window ID to use a packet (though I have reason to believe "0" is defined as the players inventory). Perhaps there could be a method using the player's inventory through getRawSlot()?
     
  7. Having made mods I can assure you there is no packet sent from client when the inventory is opened. I've had to add my own packet to clients for this.
     
    • Like Like x 1
  8. In addition, regarding advancements - There is no trigger that would detect if a player is opening their inventory anymore. (See the fill list of triggers here) It seems as if there is no more way to replicate that "Open Inventory" achievement in this new advancement system.

    The closest trigger would be an InventoryChange trigger, but that seems to be only called if items are moved around.

    [Edit #1] An idea would be to to constantly check if the PlayerInventory's viewers (using getViewers()) contains the player themselves.

    [Edit #2] Seems as if the javadocs read my mind:

    java.util.List<HumanEntity> getViewers()

    Gets a list of players viewing the inventory. Note that a player is considered to be viewing their own inventory and internal crafting screen even when said inventory is not open. They will normally be considered to be viewing their inventory even when they have a different inventory screen open, but it's possible for customized inventory screens to exclude the viewer's inventory, so this should never be assumed to be non-empty.
    Returns:
    A list of HumanEntities who are viewing this Inventory.
     
    #8 JustDJplease, Jun 11, 2018
    Last edited: Jun 11, 2018
    • Like Like x 1
  9. joehot200

    Supporter

    Am I missing a reason as to why you can't simply use the InventoryOpenEvent?
     
  10. As mentioned earlier, the opening of the survival inventory doesn't send any packet, meaning Spigot can't fire any InventoryOpenEvent for that... Well done Mojang, by the way.
     
    • Agree Agree x 1
    • Optimistic Optimistic x 1
  11. You're a little quick to blame Mojang for not implementing a feature that would only waste bandwidth resources.

    Edit: At all the IQ very high people, please think a second; Mojang can't predict what kind of shit you need for your unsupported modifications, and you can't expect them to randomly add packets with no purpose either. It's not all about you. Sorry for going off here, but this kind of selective "I need it why did people not do it for me?????" mindset pisses me off.
     
    #11 StillNoNumber, Jun 11, 2018
    Last edited: Jun 12, 2018
    • Optimistic Optimistic x 4
  12. Ah yes, bandwidth. We're sending an inventory close packet, no? Why can't we send an inventory open event on survival inventory then? Do you have any clue how much data is being sent from the server literally every second? What makes you think they can't add this tiny packet just to indicate that the player opened his survival inventory? Blaming it on bandwidth resources is the most stupid thing I've heard all day.

    In fact, here's a graph of the network activity on my server with 1 bloody player online (me). What in in the world makes you think they can't add one tiny packet to this list? Just look at the left of the graph how much packets are being sent by one player... I'm a little confused about the duplication of things and the colors, but it goes without question that one single player sends hundreds or maybe even a thousand packets (when properly playing) to the server every minute.
    [​IMG]
    The first part of the graph is nobody being online. The first peak (17:59:50) is me joining and being AFK. The second peak (18:01:30) is me running around, doing a few commands, killing some chicken, etc. One player, thousands of packets per minute. Boi am I happy this one simple extra inventory open packet wasn't send when opening only the survival inventory. Imagine the horrors that would happen.
     
    #12 MrDienns, Jun 11, 2018
    Last edited: Jun 11, 2018
    • Agree Agree x 3
    • Creative Creative x 1
  13. The only way I can think of is constantly sending window items or set slot packets that contain the crafting slot contents. I don't know how the client would react to it if the inventory is closed though.
     
  14. Chill down mr. center of the universe. Mojang doesn't need the packet. Original Minecraft doesn't. Why would they implement it only because you need it? Think for a second before being stupid please.

    "Oh, let's add a million random events and not use them." Not how to make a game.
     
    #14 StillNoNumber, Jun 12, 2018
    Last edited: Jun 12, 2018
    • Agree Agree x 2
    • Optimistic Optimistic x 1
  15. As BillyGalbreath mentioned above, there's really no way to detect players opening their inventory. If you really want a solution to this, the only way I've found was to continuously set the item at on their crafting matrix. Fortunately, InventoryCloseEvent is called before the inventory is actually closed, so it is possible to simply clear the smaller crafting matrix instead of having to look through the player's entire inventory and remove the ring items after in order to avoid the player duping their ring items.

    I've uploaded the source here if you want to check it out: https://github.com/AgentTroll/static-player-inv

    I have a demo here: https://streamable.com/98mg3
     
    • Winner Winner x 3