Solved Inventory click event bug

Discussion in 'Spigot Plugin Development' started by MrIvanPlays, May 25, 2019.

Thread Status:
Not open for further replies.
  1. Hello again!

    I've encountered with weird bug. So me and my friend are in the whitelist at the server while when we try to take some blocks, move and stuff, it does not work! Here's my code

    Code (Java):
        @EventHandler
        public void onClick(InventoryClickEvent event) {
            if (!plugin.getGame().isCurrentlyPlaying()) {
                Set<OfflinePlayer> whitelisted = plugin.getServer().getWhitelistedPlayers();
                if (event.getWhoClicked() instanceof Player) {
                    Player player = (Player) event.getWhoClicked();
                    whitelisted.forEach(offline -> {
                        System.out.println(player.getUniqueId().equals(offline.getUniqueId()));
                        if (!player.getUniqueId().equals(offline.getUniqueId())) {
                            event.setCancelled(true);
                        }
                    });
                }
            }
        }
    The code's being called as it is, but the check fails and i dont know why while I click the inventory. I am whitelisted
     
  2. This is because you cancel for every player, let's say there's 2 people in the whitelist. It will see let's say your friend, it isn't you so it will be cancelled. Then it sees you ok so don't call cancel again.

    A better way to do this is to just see if you're in the whitelist and if not then cancel, this can be done with streams easily.

    Code (Java):
    if (Bukkit.getWhitelistedPlayers().stream().noneMatch(p -> p.getUniqueId().equals(player.getUniqueId())))
        event.setCancelled(true)
     
  3. I would highly suggest you didn't use the arrow pattern and instead switched to if not statements so as to have a more readable code.

    Code (Java):
        @EventHandler
        public void onClick(InventoryClickEvent event) {
            if (plugin.getGame().isCurrentlyPlaying()) {
                  return;
                 }


                if (!(event.getWhoClicked() instanceof Player)) {
                    return;
                   }

                     Player player = (Player) event.getWhoClicked();

                Set<OfflinePlayer> whitelisted = plugin.getServer().getWhitelistedPlayers();

                    whitelisted.forEach(offline -> {
                        System.out.println(player.getUniqueId().equals(offline.getUniqueId()));
                        if (!player.getUniqueId().equals(offline.getUniqueId())) {
                            event.setCancelled(true);
                        }
                    });
           
        }
    What your code does in other words is: if at least 1 whitelisted user's uuid doesn't match the one that clicked the inventory, cancel the event.
    I assume you want this to happen if the player's uuid that is clicking the inventory doesn't belong into the whitelisted players.

    In that case, I'd use a stream.

    Code (Java):
    boolean exists = whitelisted.stream().anyMatch(offline -> player.getUniqueId().equals(offline.getUniqueId());
    if (!exists){
    // the player clicking the inventory isn't in the whitelisted collection.
    }
     
  4. Thanks for the replies. Fixed. Final code:

    Code (Java):
        @EventHandler
        public void onClick(InventoryClickEvent event) {
            if (plugin.getGame().isCurrentlyPlaying()) {
                return;
            }
            if (!(event.getWhoClicked() instanceof Player)) {
                return;
            }
            Player player = (Player) event.getWhoClicked();
            if (plugin.getServer().getWhitelistedPlayers().stream().noneMatch(whitelisted -> player.getUniqueId().equals(whitelisted.getUniqueId()))) {
                event.setCancelled(true);
            }
        }
     
Thread Status:
Not open for further replies.