Code not working...

Discussion in 'Spigot Plugin Development' started by Daniel, Jun 21, 2016.

  1. Hello I'm trying to make a sign in my plugin that will show other players the chest but not take anything I have wrote this code but not sure why its not working can someone help me out? Here is the code
    Code (Text):

        @EventHandler
        public void SignChanges(SignChangeEvent event){
                if (event.getLine(0).equalsIgnoreCase("preview")){
                    event.setLine(0, ChatColor.DARK_GRAY + "[Preview]");

            }
        }

        @EventHandler
        public void PlayerInteract(PlayerInteractEvent event){
                    if (event.getAction() == Action.RIGHT_CLICK_BLOCK);
                    if(event.getClickedBlock().getState() instanceof Sign){
                        Sign sign = (Sign) event.getClickedBlock().getState();
                        if (sign.getLine(0).equalsIgnoreCase("preview")){
                            Player player = event.getPlayer();

                      player.getOpenInventory();

                        }

                    }
     
  2. if (event.getAction() == Action.RIGHT_CLICK_BLOCK); <-----

    Oh, and register your events.
     
  3. I have register my events in my Main class. Also I don't see a issue with if(event.getAction() == Action.RIGHT_CLICK_BLOCK);
     
    • Funny Funny x 1
    • Optimistic Optimistic x 1
  4. @Daniel you need to make it a block. Now the line doesn't do anything
     
  5. Ok Ty.
     
  6. Noeone mentioned the real "error" ....

    1. trying to detect an action has to be done with this line
    Code (Text):
                     if (event.getAction() == Action.RIGHT_CLICK_BLOCK){
     
    instead of
    Code (Text):
                    if (event.getAction() == Action.RIGHT_CLICK_BLOCK);
    2. Your main issue is that you are trying to read the first sign line with the value of "preview" since you are using a signchangeevent
    that automatically compiles the line "preview" to "§8[Preview]" you definately need to change the line detection from this
    Code (Text):
                         if (sign.getLine(0).equalsIgnoreCase("preview")){
    to this
    Code (Text):
                         if (sign.getLine(0).equalsIgnoreCase("§8[Preview]")){
     
    3. player.getOpenInventory(); will just return the inventory of the player that interacted with the sign
    you need to use the openInventory(inventory) function to open the inventory from the player but since the openinventory is definately null because i think that while a player is interacting with a sign he can't have the inventory open at the same time ... so you'll need a nullpointer detection with this
    and then open the inventory
    Code (Text):

    if(player.getOpenInventory() != null){
      player.openInventory(player.getOpenInventory());
    }
     
    but since i said that the open inventory is 100% null all the time during the interact, you need to get another player's inventory instead and check with the InventoryClickEvent if the inventory matches the requested client inventory and then just cancel the click event

    Hope it works ;)

    ~ Ploxh4D
     
  7. Thank you :)
     
  8. Nah, it should never be null

    HumanEntity.getOpenInventory(): Gets the inventory view the player is currently viewing. If they do not have an inventory window open, it returns their internal crafting view.

    Also, this is something you do not want to do:
    Code (Java):
    player.openInventory(player.getOpenInventory());
    That will throw an IllegalArgumentException and open a broken inventory. The inventory title will be something like container.crafting, and the item you click will likely not be the one you wanted to click.

    @Daniel
    You're gonna want to find the chest that goes with the sign and use getInventory() on its blockstate.
     
  9. Ok
     
  10. I'm not sure how but When someone places a sign on a chest with [preview] it will only allow people to view it and not take anything from it. how would I do that?
     
  11. To start out with, you'll need to create a class-scope HashSet that will contain player UUIDs

    PlayerInteractEvent:

    If the player clicked a sign...
    1. Check if it says [preview] on it
    2. Get the chest block
    3. Get the Inventory object from the Chest's blockstate
    4. Add the player's UUID to the class-scope HashSet variable, but only if it isn't already there
    5. Call player.openInventory(chestInventoryFromBlockState);​
    If the player clicked a chest...
    1. Search around it for a sign
    2. If a sign is found, check to see if it says [preview] on it
    3. If so, cancel the interact event (to prevent a deny message if WorldGuard or something is blocking access)
    4. Get the Inventory object from the Chest's blockstate
    5. Add the player's UUID to the class-scope HashSet variable, but only if it isn't already there
    6. Call player.openInventory(chestInventoryFromBlockState);​

    InventoryOpenEvent:

    If the event inventory's InventoryHolder is an instance of a Chest...
    1. Search around the chest for a sign
    2. If a sign is found, check to see if it says [preview] on it
    3. If so, add the player's UUID to the class-scope HashSet variable, but only if it isn't already there​

    InventoryClickEvent:
    If the clicker's UUID is in the class-scope HashSet variable...
    1. Cancel the event​

    InventoryDragEvent:
    If the dragger's UUID is in the class-scope HashSet variable...
    1. Cancel the event​

    InventoryCloseEvent:
    If the player's UUID is in the class-scope HashSet variable...
    1. Remove it from the HashSet​


    This should hopefully be all you need to get the desired function with enough security to properly protect the chest inventories from being edited.
     
    #11 iPyronic, Jun 22, 2016
    Last edited: Jun 22, 2016
    • Winner Winner x 1
  12. Ty