How To Prevent Players From Placing Items In A GUI

Discussion in 'Spigot Plugin Development' started by DeathNote_15, Jul 14, 2015.

  1. Basically what the title says. So far I can prevent players from taking items out of the inventory GUI, but I can't prevent them from placing their items in the GUI. My code so far:
    Code (Text):
        @EventHandler(priority = EventPriority.HIGH)
        public void onOnline(final InventoryClickEvent event) {
            final Player player = (Player)event.getWhoClicked();
            if(event.getInventory().getName().equalsIgnoreCase(getConfig().getString("guiTitle").replaceAll("&", "§"))) {
                if(event.getCurrentItem() != null && event.getCurrentItem().getType() != Material.AIR) {
                    if(event.getCurrentItem().getType() == Material.REDSTONE_TORCH_ON) {
                        //Some hash map code
                        event.setCancelled(true);
                        player.updateInventory();
                        player.sendMessage("Success Next");
                    }
                    if(event.getCurrentItem().getType() == Material.REDSTONE_TORCH_OFF) {
                        //Some hash map code
                        event.setCancelled(true);
                        player.updateInventory();
                        player.sendMessage("Success Prev");
                    }
                    if(event.getCurrentItem().getType() == Material.SKULL_ITEM) {
                        event.setCancelled(true);
                        String str = getConfig().getString("guiClickCmd");
                        if(str != null && !str.isEmpty()) {
                            //On a side note, how would I be able to allow the plugin to use the retrieved string, place it in to the target player's (whoever clicked the head) text box, without sending the command? For example, if it said "guiClickCmd: '/msg %player% ' " in the config, how do I input this into the targets text box without sending the command, this allowing the user to edit it first?
                            player.closeInventory();
                            player.sendMessage("Success Head 1");
                        } else {
                            player.updateInventory();
                            player.sendMessage("Success Head 2");
                        }
                    }
                    if(event.getCurrentItem().getType() == Material.IRON_FENCE) {
                        event.setCancelled(true);
                        player.updateInventory();
                        player.sendMessage("Success Bar");
                    }
                } else {
                    player.sendMessage("Success Other");
                }
            }
           }
    PS: Ignore the 'Success' messages, they are for me to see if the event was registered/if the code worked :p
     
  2. If the inventory you open up for them is 54 slots for example, then you can use event.getRawSlot() to get the unique id of the slot clicked - and doing
    Code (Text):
    if(event.getRawSlot() > 53) { event.setCancelled(true); }
    should work to cancel inventory clicks on their own personal inventory.
     
  3. The inventory size varies depending on the number of online players (9 slots if >= 9 players online, then 18 if >= 18 players online, 27, etc etc, 54. Anything over 54 creates another page to the GUI). So would this code still work if the size is less than 54? I'm assuming it would, since I don't see a problem with it
     
  4. @Wood Nvm. This code prevents players from moving stuff in their inventories while the GUI is open. I'm looking for a way players can interact with their inventory, but NOT place anything in the GUI
     
  5. So instead of 54, have a variable called invSize. Have invSize = numberPlayerOnline * 9; and if you want to not allow players to move items in the gui, just cancel if (e.getRawSlot() < invSize) {}

    That will only work if your GUI only consists of GUI clicks; but if players need to move items around in your GUI too, you'll need to get creative.
    @DeathNote_15
     
  6. Simple, like he said. Cancel the event, and open the same inventory again for the frozen effect (unless you want so).
     
  7. Check for the inventory name, and prevent people from placing/removing items from it. (InventoryClickEvent)
     
  8. Have you tried cancelling InventoryItemDragEvent (or similar)?
     
  9. You can try adding a variable so when you open the gui that variable is "true" and use it on a "if" sentence that cancel the event InventoryClickEvent if its true. So you only has to put the variable to "false" when the player close the GUI.
     
    #9 adri1711, Jul 15, 2015
    Last edited: Jul 15, 2015
  10. Look into InventoryAction in the java docs.
     
  11. Before
    Code (Text):
    if(event.getCurrentItem().getType() == Material.REDSTONE_TORCH_ON) {
    add this :
    Code (Text):
    event.setCancelled(true);
    The event will be cancelled, so they won't place items there.
     
  12. Yea but using anyone of the methods you guys suggested either disables moving things completely (from the GUI as well as the players inventory while the GUI is open) or enables it. I just wants things to be prevented being placed/swapped around in the GUI, but if the player wants to mess around with their own inventory that is fine (this is what I'm trying to achieve). So far, this is what I have:
    Code (Text):

        @EventHandler(priority = EventPriority.HIGH)
        public void onOnline(final InventoryClickEvent event) {
            final Player player = (Player)event.getWhoClicked();

            if(event.getInventory().getName().equalsIgnoreCase(getConfig().getString("guiTitle").replaceAll("&", "§")) && event.getCurrentItem() != null) {

                if(event.getCurrentItem().getType() == Material.REDSTONE_TORCH_ON) {
                    int nPage = onlinePageMap.get(player.getName()) + 1;
                    onlinePageMap.put(player.getName(), nPage);
                      event.setCancelled(true);
                      player.updateInventory();
                    player.sendMessage("Success Next");
                }

                if(event.getCurrentItem().getType() == Material.REDSTONE_TORCH_OFF) {
                    int pPage = onlinePageMap.get(player.getName()) - 1;
                    onlinePageMap.put(player.getName(), pPage);
                    event.setCancelled(true);
                    player.updateInventory();
                    player.sendMessage("Success Prev");
                }

                if(event.getCurrentItem().getType() == Material.SKULL_ITEM) {
                    event.setCancelled(true);
                    String str = getConfig().getString("guiClickCmd");
                    if(str != null && !str.isEmpty()) {
                        //Some stuff
                        player.closeInventory();
                        player.sendMessage("Success Head 1");
                    } else {
                        player.updateInventory();
                        player.sendMessage("Success Head 2");
                    }
                }

                if(event.getRawSlot() < invSize) {
                    event.setCancelled(true);
                    player.updateInventory();
                }
            }
        }
     
    The code is pretty glitchy, you can't directly place things in your own inventory or the GUI, but if you spam it/get a stack and spread it the cursor items will be placed :/

    PS: I tried Woods raw slot method but the glitchy stuff remains (i.e. spamming an item on a slot/dragging it over the slot will place it. I'm thinking I have to tackle that with InventoryDragEvent but I'm looking for the most efficient way, trying to do it all under one method).

    @DanyBv @adri1711 @Wood

    And yes, @Synic, I've looked under the docs. I'm not sure which InventoryAction would cover drag events (possibly the PLACE ones) or spamming an item to a slot. Which is why I'm assuming I need to create a different method to handle the DragEvent, but just wondering if its possible to do it all under one method.
     
    #13 DeathNote_15, Jul 19, 2015
    Last edited: Jul 19, 2015