Solved Custom GUI help!

Discussion in 'Spigot Plugin Development' started by NamerPRO, Jul 7, 2018.

Thread Status:
Not open for further replies.
  1. So I have a custom chest gui and I want to check when it's closed by a player. I have a way to close it in my code, using p.closeInventory(); where p is Player p = (Player) e.getWhoClicked();

    I tried to use InventoryCloseEvent, but it works too when I do p.closeInventory(); in my code. How to avoid that?

    I want something like:
    If inventory was closed by player, kick this player else do nothing.

    I saw one creator of plugin who'd done it, but I have no idea how. Link to that plugin: https://www.spigotmc.org/resources/captcha-antibotsystem.53846/
     
  2. JanTuck

    Supporter

    Just store some ref that you closed the inv and not the player?
     
  3. May I have a code example, please.
     
  4. JanTuck

    Supporter

    If you do feel free to share it. Kappa


    Sent from my iPhone using Tapatalk
     
  5. I feel free to get it from you :)
     
  6. JanTuck

    Supporter

    I’m not gonna give it to you though. Use some brainpower and go figure it out.


    Sent from my iPhone using Tapatalk
     
  7. Create a Set<UUID>. Before you close the player's inventory add them in the set. On InventoryCloseEvent check if the set contains the player's uuid. If true then the inventory has been closed by you (not the player). Finally remove them from the set.
     
  8. Ok, so in your listener class, make a List<Player>, when YOU close the inventory, make sure that you do this:
    Code (Text):
    list.add(player);
    Then, in your actual close event, do this:
    Code (Text):
    if(list.contains(e.getPlayer)) // they didn't close it, you did.
    list.remove(e.getPlayer()); // remember to remove them afterwards. Only if they were in it in the first place.
    Edit: I got beaten to it ;( and yea a Set is a better idea than a List.
     
  9. I like your idea, but I'd never worked with sets before. How to use them? Same as list?

    If I say something stupid, then sorry :rolleyes:
    If I say even more then stupid, then SORRRRRRRRRRRRRRRY :(
    If I speak on unknown language, then buy my dictionary :LOL:
     
  10. JanTuck

    Supporter

    Use a HashSet fast lookup and no duplicates. Use it the same way as a list.
     
  11. I can only add a player using (Player) e.getWhoClicked(); So this is not the best solution for 1st time close. I have a gui, which opens on player join. So I do it like this:
    Code (Java):
    @EventHandler
        public void onJoin(PlayerJoinEvent e) {
            Bukkit.getScheduler().runTaskLater(this, new Runnable() {
                @Override
                public void run() {
                    openRules(e.getPlayer());
                }
            }, 1);
        }
    In openRules:
    Code (Java):
    private void openRules(Player p) {
    //MY GUI CODE
    p.openInventory(inv);
    }
    I check player clicks in:
    Code (Java):
    @EventHandler
    public void onInvClick(InventoryClickEvent e) {
    //MY CODE HERE
    //Somewhere in code p.closeInventory();
    }
     
  12. Storing player variables may lead to memory leak. It is safer to store UUID's
     
  13. Thank you, I'll keep that in mind for the future :)
     
  14. Sets are sort of same with List but List is ordered. You don't it to be sorted and therefore a Set is ideal. Also, Sets don't allow for dupes.


    Here's some pseudo code.
    Code (Java):

    Set<UUID> yourSet = ...

    public void onPlayerJoin(PlayerJoinEvent e) {
    // open the inventory 1 tick later.
    }

    public void onClose(InventoryCloseEvent e) {
    if (!yourSet.contains(playerUUID)) {
    // kick the player.
      }
    }

    public void onInvClick(InventoryClickEvent e) {
    // other code

    yourSet.add(playerUUID);
    // close the player's inventory
    }

     
     
    #14 darklazerog, Jul 7, 2018
    Last edited: Jul 7, 2018
  15. Remember, if you do end up ignoring it, and not kicking them from the server, to remove them from the set.
     
  16. It's not totally necessary since they are added only once they click on the inventory and then immediately removed. Meaning they won't be in the list, and Sets don't allow for dupes.
     
  17. But, if you need to kick them the next time, instead of pardoning them, they are still in the set and will not actually be kicked. Depends on the nature of the plugin but for compatability's sake.
     
  18. How would the player be kicked twice o_O?
    If the player does wrong once he is kicked. Then the code runs from the start.

    I'm just suggesting a solution that fits the OP's needs. This thread could expand and the algorithm could change greatly but it's not needed.
     
    • Like Like x 1
  19. So I do:
    Code (Java):
    @EventHandler
        public void onJoin(PlayerJoinEvent e) {
            Set<UUID> PlayerList = e.getPlayer().getUniqueId();
            Bukkit.getScheduler().runTaskLater(this, new Runnable() {
                @Override
                public void run() {
                    openRules(e.getPlayer());
                }
            }, 1);
        }

    public void onClose(InventoryCloseEvent e) {
    if (!yourSet.contains(playerUUID)) {
    // kick the player.
      } esle {
         PlayerList.remove(e.getPlayer().getUniqueId());
      }
    }

    public void onInvClick(InventoryClickEvent e) {
    // other code

    yourSet.add(playerUUID);
    // close the player's inventory
    }
     
     
  20. I already gave you the pseudo code necessary and what you did is not nearly close it. The Set should be a "global" variable.
     
Thread Status:
Not open for further replies.