InventoryClickEvent can't be cancelled, and item duplicate

Discussion in 'Spigot Plugin Development' started by Ohwnead, Aug 10, 2018.

  1. Hi, I was reworking some code, and now my teleport class is bugy,
    All is in the title,

    Here is my code

    Code (Java):
    public class _4island_tp implements Listener
    {

        @EventHandler
        public void PlayerClickBaseInventory(InventoryClickEvent e)
        {
            if (e.getCurrentItem() != null
                    && e.getClickedInventory().getHolder() == null
                    && e.getClickedInventory().getName().contains("Île")
                    && e.getCurrentItem().getType() == Material.DRAGONS_BREATH)
            {
                e.setCancelled(true);
                TPToIsland(Bukkit.getOfflinePlayer(e.getWhoClicked().getUniqueId()));
                e.setCancelled(true);
            }
        }
    }
     
    Code (Java):
    public class TPToIsland
    {

        public static void TPToIsland(OfflinePlayer Op)
        {
            FileConfiguration PlayerCFG;
            File PlayerFile;

            FileConfiguration IslandCFG;
            File IslandFile;

            Main plugin = Main.getPlugin(Main.class);
            PlayerFile = new File(plugin.getDataFolder(), Op.getUniqueId().toString() + ".yml");
            IslandFile = new File(plugin.getDataFolder(), "_Island.yml");

            if (Op.isOnline())
            {
                Player p = Op.getPlayer();
                if (PlayerFile.exists()
                        && IslandFile.exists())
                {
                    PlayerCFG = YamlConfiguration.loadConfiguration(PlayerFile);
                    IslandCFG = YamlConfiguration.loadConfiguration(IslandFile);

                    if (PlayerHasIsland(p))
                    {
                        int xIle = PlayerCFG.getInt("Info.Player.IleNumX");
                        int zIle = PlayerCFG.getInt("Info.Player.IleNumZ");

                        setEffectAfterTP(p);

                        Location loc = (Location) IslandCFG.get(xIle + " " + zIle + ".location");

                        p.teleport(loc);
                    }
                    else
                    {
                        setEffectAfterTP(p);

                        Location loc = new Location(Bukkit.getWorld("Spawn"), 0.5, 100.5, 0.5, 0, 0);

                        p.teleport(loc);
                    }

                }
            }
        }

        public static void setEffectAfterTP(Player p)
        {
            p.setFallDistance(0);
            p.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 20 * 20, 1));

            if (PlayerHasIsland(Bukkit.getOfflinePlayer(p.getUniqueId())))
            {
                FileConfiguration IslandCFG;
                File IslandFile;
                FileConfiguration PlayerCFG;
                File PlayerFile;

                Main plugin = Main.getPlugin(Main.class);
                IslandFile = new File(plugin.getDataFolder(), "_Island.yml");
                PlayerFile = new File(plugin.getDataFolder(), p.getUniqueId().toString() + ".yml");
                if (IslandFile.exists())
                {
                    PlayerCFG = YamlConfiguration.loadConfiguration(PlayerFile);
                    IslandCFG = YamlConfiguration.loadConfiguration(IslandFile);

                    int xIle = PlayerCFG.getInt("Info.Player.IleNumX");
                    int zIle = PlayerCFG.getInt("Info.Player.IleNumZ");

                    Location loc = (Location) IslandCFG.get(xIle + " " + zIle + ".location");
                    loc.setY(loc.getY() - 1);

                    if (loc.getBlock().getType() == Material.AIR)
                    {
                        Material material = loc.getBlock().getType();
                        p.sendBlockChange(loc, Material.BEDROCK, (byte) 0);
                        Bukkit.getServer().getScheduler().runTaskLater(plugin, new Runnable()
                        {
                            public void run()
                            {
                                if (loc.getBlock().getType() == Material.BEDROCK)
                                {
                                    loc.getBlock().getState().update();
                                }
                            }

                        }, (5 * 20));
                    }
                }
            }
        }
    }

    Sorry for that bad code ^^'
    It remain from the begining of my project :p
     
  2. salut :)
    Que cherches-tu à faire ?
     
  3. Just use the event with only the cancel line and maybe a line to send a message to see then the event was fired.
     
  4. Does it still not cancel with that?
     
  5. The full event is fire, but the cancelling event "normaly" prevent for keeping item on click and it just don't work on this class (other class work)
     
  6. What do you mean? Does it cancel the event or not? And use only one cancel event, but do it before you teleport the player.
    Also, method names should be lower camelCase (ex: tpToIsland, instead of TPToIsland)
     
  7. Have you even registered the events for that class?
     
    • Like Like x 1
  8. About the TPToIsland method... Change the OfflinePlayer variable to Player. Because you cannot teleport an Offline player :)
    Try debugging your methods... For example instead of the first #setCancelled() method call a #sendMessage() method and check if the player gets the message
     
  9. Ok here are some of the issues I noticed.


    JAVA NAMING CONVENTIONS:
    1. It is not advisable to use special characters or numbers on the beginning of the class name in your case to avoid this. Instead of naming your class _4island_tp, you can change this to FourIslandTp or you can name it to a more readable form like TeleportManager or Teleporter.
    remember class names starts all significant names with a capital letter.

    2. Your methods names should start with small letters then the following significant names should start with capital letters.
    Example: PlayerClickBaseInventory
    Change to: playerClickBaseInventory

    ABOUT YOUR CODE:

    1. you are cancelling the event twice.
    2. you forgot to check if the clicked inventory is null. When the player clicks outside the open inventory it will return null.
    3. Instead of passing an offline player to the TPToIsland method you should pass the direct player who clicked the inventory using e.getWhoClicked() you can cast this to a player. Then you can check if player is null in the other method which still would be unlikely.
    4. I do not know why you are declaring your variable twice which you can do it in one line.
    Example:
    Code (Text):
    File IslandFile;
    IslandFile = new File(plugin.getDataFolder(), "_Island.yml");
    Which you can just do this:
    Code (Text):
    File IslandFile = new File(plugin.getDataFolder(), "_Island.yml");
     
  10. Full event is fire except event cancelling,
    So the player duplicate item on click
    so yeah Event is already added to the reg

    It's old code, sorry for naming conventons, i never learn it

    I have the null cast for inventory :
    Code (Text):
    && e.getClickedInventory().getHolder() == null
    In main case i cast OfflinePlayer for the first part (because it can get offlinePlayer and OnlinePlayer) and if he is online in cast a Player and make my stuff.

    And I was casting var in 2 lines, because in my old code there was another function wich was playing with file & CFG, and i never put it back ^^
     
    #10 Ohwnead, Aug 11, 2018
    Last edited: Aug 11, 2018
  11. Solved, adding a scheduler with a 0 tick delay, and inside the TP code make work the event cancelling

    Thanks for help
     
  12. Si tu as d’autres soucis n’hesite pas à passer mp ;)
     
    • Friendly Friendly x 1
  13. Merci de ton aide :D
     

Share This Page