Solved Help with playerInteract + SignChange?

Discussion in 'Plugin Development' started by GlacialCreeper, May 25, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    GlacialCreeper

    Hello, I've got a bug that I have NOT been able to figure out, I started the small project from scratch, and it still wont work. The worst part is that the terminal doesn't say any issues upon loading the plugin.
    So here's my code for the main class:
    Code:java
    1. package me.glacialcreeper.simplesigns;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Location;
    6. import org.bukkit.World;
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.entity.Player;
    10. import org.bukkit.plugin.java.JavaPlugin;
    11.  
    12. public class Initial extends JavaPlugin {
    13.  
    14. public void onEnable(){
    15. Bukkit.getServer().getPluginManager().registerEvents(new SignListeners(), this);
    16. }
    17.  
    18. public void onDisable(){
    19.  
    20. }
    21.  
    22. public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, String[] args){
    23. Player player = (Player) sender;
    24.  
    25. if (!(sender instanceof Player)){
    26. sender.sendMessage(ChatColor.RED+"This can only be run in-game!");
    27. }
    28.  
    29. if (cmdLabel.equalsIgnoreCase("spawn")){
    30. World w = player.getWorld();
    31. double x = w.getSpawnLocation().getX();
    32. double y = w.getSpawnLocation().getY();
    33. double z = w.getSpawnLocation().getZ();
    34. player.teleport(new Location(w, x, y, z));
    35. }
    36.  
    37. return true;
    38. }
    39.  
    40. }
    41.  


    Incase you're wondering, I"m trying to make a small plugin for a friend's server to teleport you back to the hub, along with a /spawn and /hub command alias. Also making a small kit for his pvp arena. So here's the sign listener class, there's no errors in eclipse either:
    Code:java
    1. package me.glacialcreeper.simplesigns;
    2.  
    3. import org.bukkit.Location;
    4. import org.bukkit.Material;
    5. import org.bukkit.World;
    6. import org.bukkit.block.Sign;
    7. import org.bukkit.enchantments.Enchantment;
    8. import org.bukkit.entity.Player;
    9. import org.bukkit.event.EventHandler;
    10. import org.bukkit.event.Listener;
    11. import org.bukkit.event.block.Action;
    12. import org.bukkit.event.block.SignChangeEvent;
    13. import org.bukkit.event.player.PlayerInteractEvent;
    14. import org.bukkit.inventory.ItemStack;
    15. import org.bukkit.inventory.PlayerInventory;
    16.  
    17. public class SignListeners implements Listener {
    18.  
    19. @EventHandler
    20. public void onSignChange(SignChangeEvent e){
    21. if ((e.getLine(0).equalsIgnoreCase("#SPAWN#")) || (e.getLine(0).equalsIgnoreCase("#HUB#"))){
    22. e.setLine(0, "§1Click here to");
    23. e.setLine(1, "§1return to hub");
    24. }
    25.  
    26. if (e.getLine(0).equalsIgnoreCase("#PVPKIT#")){
    27. e.setLine(0, "§aClick here to");
    28. e.setLine(1, "§aget pvp items");
    29. }
    30. }
    31.  
    32. @EventHandler
    33. public void onPlayerInteract(PlayerInteractEvent e){
    34. if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK) || !(e.getAction() == Action.LEFT_CLICK_BLOCK)) return;
    35. if (e.getClickedBlock().getState() instanceof Sign){
    36. Sign sign = (Sign) e.getClickedBlock().getState();
    37. Player player = e.getPlayer();if (sign.getLine(1).equalsIgnoreCase("§1return to hub")){
    38. World w = player.getWorld();
    39. double x = w.getSpawnLocation().getX();
    40. double y = w.getSpawnLocation().getY();
    41. double z = w.getSpawnLocation().getZ();
    42.  
    43. player.teleport(new Location(w, x, y, z));
    44. } else if (sign.getLine(1).equalsIgnoreCase("§aget pvp items")){
    45. PlayerInventory plinv = player.getInventory();
    46. plinv.setHelmet(new ItemStack(Material.IRON_HELMET));
    47. plinv.setChestplate(new ItemStack(Material.IRON_CHESTPLATE));
    48. plinv.setLeggings(new ItemStack(Material.IRON_LEGGINGS));
    49. plinv.setBoots(new ItemStack(Material.IRON_BOOTS));
    50.  
    51. ItemStack sword = new ItemStack(Material.STONE_SWORD);
    52. ItemStack bow = new ItemStack(Material.BOW);
    53. sword.addEnchantment(Enchantment.DURABILITY, 3);
    54. bow.addEnchantment(Enchantment.KNOCKBACK, 1);
    55. bow.addEnchantment(Enchantment.ARROW_INFINITE, 1);
    56.  
    57. plinv.addItem(new ItemStack(Material.ARROW, 1));
    58. plinv.setItem(0, sword);
    59. plinv.setItem(1, bow);
    60. plinv.setItem(2, new ItemStack(Material.GOLDEN_APPLE, 32));
    61. plinv.setItem(8, new ItemStack(Material.ARROW));
    62.  
    63. plinv.setItemInHand(sword);
    64.  
    65. } else {
    66. return;
    67. }
    68. }
    69. }
    70. }


    When I place the sign with #spawn# on it, the words change like it's supposed to, but when I click it, nothing happens. I check the terminal after clicking it, and it shows no issues as well. I've reloaded a couple of times too. Can someone help me? Thanks.
     
  2. Offline

    mythbusterma

    Add debugging messages, i.e. Bukkit.getServer ().getLogger ().log (Level.INFO, "message 1") after every if and you can see how far the code gets, which will help you identify the problem. Tell us the updated code and the output afterward
     
  3. Offline

    GlacialCreeper

    Alright, about to try that..

    Ok here's the updated main file:
    Code:java
    1. package me.glacialcreeper.simplesigns;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Location;
    6. import org.bukkit.World;
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.entity.Player;
    10. import org.bukkit.plugin.java.JavaPlugin;
    11.  
    12. public class Initial extends JavaPlugin {
    13.  
    14. public void onEnable(){
    15. Bukkit.getServer().getPluginManager().registerEvents(new SignListeners(), this);
    16. Bukkit.getServer().getLogger().info("Has been enabled successfully!");
    17. }
    18.  
    19. public void onDisable(){
    20. Bukkit.getServer().getLogger().info("Has been disabled successfully!");
    21. }
    22.  
    23. public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, String[] args){
    24. Player player = (Player) sender;
    25.  
    26. if (!(sender instanceof Player)){
    27. sender.sendMessage(ChatColor.RED+"This can only be run in-game!");
    28. }
    29.  
    30. if (cmdLabel.equalsIgnoreCase("spawn")){
    31. World w = player.getWorld();
    32. double x = w.getSpawnLocation().getX();
    33. double y = w.getSpawnLocation().getY();
    34. double z = w.getSpawnLocation().getZ();
    35. player.teleport(new Location(w, x, y, z));
    36. player.sendMessage("An error occurred running this command.");
    37. }
    38.  
    39. return true;
    40. }
    41.  
    42. }
    43.  


    Well thats good, the /spawn command works (Forgot I meant to say "spawn successful or something similar). But the signs are somehow glitchy. Here's the new SignListener:
    Code:java
    1. package me.glacialcreeper.simplesigns;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.ChatColor;
    5. import org.bukkit.Location;
    6. import org.bukkit.Material;
    7. import org.bukkit.World;
    8. import org.bukkit.block.Sign;
    9. import org.bukkit.enchantments.Enchantment;
    10. import org.bukkit.entity.Player;
    11. import org.bukkit.event.EventHandler;
    12. import org.bukkit.event.Listener;
    13. import org.bukkit.event.block.Action;
    14. import org.bukkit.event.block.SignChangeEvent;
    15. import org.bukkit.event.player.PlayerInteractEvent;
    16. import org.bukkit.inventory.ItemStack;
    17. import org.bukkit.inventory.PlayerInventory;
    18.  
    19. public class SignListeners implements Listener {
    20.  
    21. @EventHandler
    22. public void onSignChange(SignChangeEvent e){
    23. if ((e.getLine(0).equalsIgnoreCase("#SPAWN#")) || (e.getLine(0).equalsIgnoreCase("#HUB#"))){
    24. e.setLine(0, "§1Click here to");
    25. e.setLine(1, "§1return to hub");
    26. Bukkit.getServer().getLogger().info("Spawn sign set successfully.");
    27. e.getPlayer().sendMessage(ChatColor.GREEN+"spawn sign set.");
    28. }
    29.  
    30. if (e.getLine(0).equalsIgnoreCase("#PVPKIT#")){
    31. e.setLine(0, "§aClick here to");
    32. e.setLine(1, "§aget pvp items");
    33. Bukkit.getServer().getLogger().info("PvP sign set successfully.");
    34. e.getPlayer().sendMessage(ChatColor.GREEN+"pvp sign set.");
    35. }
    36. }
    37.  
    38. @EventHandler
    39. public void onPlayerInteract(PlayerInteractEvent e){
    40. if (!(e.getAction() == Action.RIGHT_CLICK_BLOCK) || !(e.getAction() == Action.LEFT_CLICK_BLOCK)) return;
    41. if (e.getClickedBlock().getState() instanceof Sign){
    42. Sign sign = (Sign) e.getClickedBlock().getState();
    43. Player player = e.getPlayer();
    44. player.sendMessage(ChatColor.GREEN+"You clicked a sign!");
    45.  
    46. if (sign.getLine(1).equalsIgnoreCase("§1return to hub")){
    47. World w = player.getWorld();
    48. double x = w.getSpawnLocation().getX();
    49. double y = w.getSpawnLocation().getY();
    50. double z = w.getSpawnLocation().getZ();
    51. player.teleport(new Location(w, x, y, z));
    52. player.sendMessage(ChatColor.GREEN+"Teleported!");
    53.  
    54. } else if (sign.getLine(1).equalsIgnoreCase("§aget pvp items")){
    55. PlayerInventory plinv = player.getInventory();
    56. plinv.setHelmet(new ItemStack(Material.IRON_HELMET));
    57. plinv.setChestplate(new ItemStack(Material.IRON_CHESTPLATE));
    58. plinv.setLeggings(new ItemStack(Material.IRON_LEGGINGS));
    59. plinv.setBoots(new ItemStack(Material.IRON_BOOTS));
    60.  
    61. ItemStack sword = new ItemStack(Material.STONE_SWORD);
    62. ItemStack bow = new ItemStack(Material.BOW);
    63. sword.addEnchantment(Enchantment.DURABILITY, 3);
    64. bow.addEnchantment(Enchantment.KNOCKBACK, 1);
    65. bow.addEnchantment(Enchantment.ARROW_INFINITE, 1);
    66.  
    67. plinv.addItem(new ItemStack(Material.ARROW, 1));
    68. plinv.setItem(0, sword);
    69. plinv.setItem(1, bow);
    70. plinv.setItem(2, new ItemStack(Material.GOLDEN_APPLE, 32));
    71. plinv.setItem(8, new ItemStack(Material.ARROW));
    72.  
    73. plinv.setItemInHand(sword);
    74. player.sendMessage(ChatColor.GREEN+"You've received your kit!");
    75. } else {
    76. return;
    77. }
    78. }
    79. }
    80. }


    They do say "spawn sign set" and "pvp sign set", and so does the terminal, upon setting them, but the clicks somehow seem to not be registering (they dont get to the debug messages, not even "you clicked a sign!"). Idk what's wrong :/

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  4. Offline

    PreFiXAUT

    GlacialCreeper
    You could also try to use an external CommandExecutor (add this in your enable method:
    Code:java
    1. this.getCommand("CommandName").setExecutor(new ExecutorClass());
    )

    I had sometimes Bugs with the JavaPlugin onCommand thingy, so may try that out.
    When you're doing it in a external Class, you don't need to check if the Command is right. Also maybe just move the Player player = (Player) sender; under the checking if the Player is a Player (might cause trouble as well).

    #EDIT: Didn't see the new Post yet.
    Use a System.out.println("Message"); , it will send the Message to the Console, so you can see when the Method is called. I would also suggest you to save the Block etc. in a variable, so you can check like every little step.

    Out of my Plugin:
    Code:
        @EventHandler
        public void onInteract(PlayerInteractEvent e) {
            if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
            Player p = e.getPlayer();
            Block block = e.getClickedBlock();
            BlockState bs = block.getState();
            if (!(bs instanceof Sign)) return;
            Sign sign  = (Sign) bs;
            if (!sign.getLine(0).equalsIgnoreCase("§4[Lobby]")) return;
     
  5. Offline

    GlacialCreeper

    Thanks, but I'd rather keep my class like it is (no executor), and anyway its just one command with an alias.
    About the System.out.println(); , I might try that. Do you see any bugs in my code though?
     
  6. Offline

    PreFiXAUT

    @GlacialCreeper
    Currently I can't see a Bug, but as I said, try saving everything into a Variable and check if they are null. if so return and otherwise use the println and write a Message. That's the once I could think of.
     
  7. Offline

    mythbusterma

    Im probably wrong about this, but you might want to use e.getBlock ().getType().equals (Material.WALL_SIGN) or.... equals (Material.SIGN_POST). That might give you better results than instanceof Sign. I could be totally wrong, but that is what I use in my code.
     
  8. Offline

    PreFiXAUT

    I use the instanceof in my Code and it works fine.
     
  9. Offline

    mythbusterma

    Wow, I feel dumb. I see it now, line 40 is a logical fallacy, one of those statements will always evaluate to false, as the action cannot be both a left and right click. Instead contain all your code in an if block that is: if (e.getAction ().equals (Action.LEFT_CLICK_BLOCK) || .....(Action.RIGHT....) and it will work.
     
  10. Offline

    GlacialCreeper

    Ok guys I have figured it out! ;) I had to remake the project since I deleted it again...
    So here's the new SignListeners:
    Code:java
    1. package me.glacialcreeper.spawnstuff;
    2.  
    3. import org.bukkit.ChatColor;
    4. import org.bukkit.Location;
    5. import org.bukkit.Material;
    6. import org.bukkit.World;
    7. import org.bukkit.block.Sign;
    8. import org.bukkit.enchantments.Enchantment;
    9. import org.bukkit.entity.Player;
    10. import org.bukkit.event.EventHandler;
    11. import org.bukkit.event.Listener;
    12. import org.bukkit.event.block.Action;
    13. import org.bukkit.event.block.SignChangeEvent;
    14. import org.bukkit.event.player.PlayerInteractEvent;
    15. import org.bukkit.inventory.ItemStack;
    16. import org.bukkit.inventory.PlayerInventory;
    17.  
    18. public class SignListeners implements Listener {
    19.  
    20. @EventHandler
    21. public void onSignChange(SignChangeEvent event){
    22. String line0 = event.getLine(0);
    23. if ((line0.equalsIgnoreCase("#SPAWN#")) || (line0.equalsIgnoreCase("#HUB#"))){
    24. event.setLine(0, "§1Click here to");
    25. event.setLine(1, "§1return to hub");
    26. } else if (line0.equalsIgnoreCase("#PVPKIT#")){
    27. event.setLine(0, "§aClick here to");
    28. event.setLine(1, "§aget pvp items");
    29.  
    30. } else {
    31. return;
    32. }
    33. }
    34.  
    35. @SuppressWarnings("deprecation")
    36. @EventHandler
    37. public void onPlayerInteract(PlayerInteractEvent event){
    38. Player player = event.getPlayer();
    39. Action action = event.getAction();
    40.  
    41. if ((action == Action.LEFT_CLICK_BLOCK) || (action == Action.RIGHT_CLICK_BLOCK)){
    42. if (event.getClickedBlock().getState() instanceof Sign){
    43.  
    44. Sign sign = (Sign) event.getClickedBlock().getState();
    45. String line1 = sign.getLine(1);
    46.  
    47. if (line1.equals("§1return to hub")){
    48. World w = player.getWorld();
    49. double x = w.getSpawnLocation().getX();
    50. double y = w.getSpawnLocation().getY();
    51. double z = w.getSpawnLocation().getZ();
    52. player.teleport(new Location(w, x, y, z));
    53. } else if (line1.equalsIgnoreCase("§aget pvp items")){
    54. PlayerInventory plinv = player.getInventory();
    55. plinv.clear();
    56. plinv.setHelmet(new ItemStack(Material.IRON_HELMET));
    57. plinv.setChestplate(new ItemStack(Material.IRON_CHESTPLATE));
    58. plinv.setLeggings(new ItemStack(Material.IRON_LEGGINGS));
    59. plinv.setBoots(new ItemStack(Material.IRON_BOOTS));
    60.  
    61. ItemStack sword = new ItemStack(Material.STONE_SWORD);
    62. ItemStack bow = new ItemStack(Material.BOW);
    63. bow.addEnchantment(Enchantment.ARROW_KNOCKBACK, 1);
    64. bow.addEnchantment(Enchantment.ARROW_INFINITE, 1);
    65.  
    66. plinv.addItem(new ItemStack(Material.ARROW, 1));
    67. plinv.setItem(0, sword);
    68. plinv.setItem(1, bow);
    69. plinv.setItem(2, new ItemStack(Material.GOLDEN_APPLE, 32));
    70. plinv.setItem(8, new ItemStack(Material.ARROW));
    71.  
    72. plinv.setItemInHand(sword);
    73. player.updateInventory();
    74. player.sendMessage(ChatColor.GREEN+"You've received your kit!");
    75.  
    76. } else {
    77. return;
    78. }
    79. }
    80. } else {
    81. return;
    82. }
    83. }
    84.  
    85. }
    86.  

    Part of what happened was that some enchantments couldnt be put on the bow and sword (the type of enchantment). Secondly, I saw a video earlier today that showed the player.updateInventory() deprecated method. I'd forgotten all about that. That fixed it! Also I removed the (!(e.getAction)) stuff, and added the return in some else clauses later.

    Also, I was gonna abandon this, but it'll probably be useful to somebody and also to let you guys know I fixed it.
    :)

    mythbusterma PreFiXAUT

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
Thread Status:
Not open for further replies.

Share This Page