Very strange: Buckets gets consumed even when event is cancelled?

Discussion in 'Plugin Development' started by sebastiannielsen, May 10, 2012.

Thread Status:
Not open for further replies.
  1. Here is my code:
    Code:java
    1.  
    2. @SuppressWarnings("unchecked")
    3. @EventHandler
    4. public void onPlayerEmptyBucket (PlayerBucketEmptyEvent event) {
    5. ArrayList<String> emptyList = new ArrayList<String>(Arrays.asList(new String[] {}));
    6. emptyList.clear();
    7. Block targetBlock;
    8. boolean walktest;
    9. String chunkOwner;
    10. ArrayList<String> friendsList;
    11. if (!event.isCancelled()) {
    12. Block block = event.getBlockClicked();
    13. BlockFace face = event.getBlockFace();
    14. if (face.equals(BlockFace.UP) || face.equals(BlockFace.DOWN)|| face.equals(BlockFace.SELF)) {
    15. targetBlock = block;
    16. } else {
    17. targetBlock = block.getRelative(face);
    18. }
    19. chunkOwner = getConfig().getString("main.claims." + String.valueOf(targetBlock.getChunk().getX()) + "," + String.valueOf(targetBlock.getChunk().getZ()), null);
    20. if (chunkOwner == null) {
    21. chunkOwner = "";
    22. }
    23. chunkOwner = chunkOwner.toLowerCase();
    24. if (!(chunkOwner.equals(""))) {
    25. walktest = getConfig().getBoolean("main.players." + event.getPlayer().getName().toLowerCase() + ".walktest", false);
    26. if (walktest) {
    27. int bucket = event.getBucket().getId();
    28. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_walkteston);
    29. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_chunkowner.replaceAll("##X##", String.valueOf(targetBlock.getChunk().getX())).replaceAll("##Y##", String.valueOf(targetBlock.getChunk().getZ())).replaceAll("##N##", chunkOwner.toLowerCase()));
    30. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_walktesthelp);
    31. event.setCancelled(true);
    32. event.setItemStack(new ItemStack(bucket,1));
    33. }
    34. else
    35. {
    36. if (!chunkOwner.equalsIgnoreCase(event.getPlayer().getName().toLowerCase())) {
    37. friendsList = new ArrayList<String>((List<String>) getConfig().getList("main.players." + chunkOwner.toLowerCase() + ".friends", emptyList));
    38. if (!friendsList.contains(event.getPlayer().getName().toLowerCase())) {
    39. if (!event.getPlayer().isOp()) {
    40. int bucket = event.getBucket().getId();
    41. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_chunkowner.replaceAll("##X##", String.valueOf(targetBlock.getChunk().getX())).replaceAll("##Y##", String.valueOf(targetBlock.getChunk().getZ())).replaceAll("##N##", chunkOwner.toLowerCase()));
    42. event.setCancelled(true);
    43. event.setItemStack(new ItemStack(bucket,1));
    44. }
    45. }
    46. }
    47. }
    48. }
    49. }
    50. }
    51.  
    52.  
    53. @SuppressWarnings("unchecked")
    54. @EventHandler
    55. public void onPlayerFillBucket (PlayerBucketFillEvent event) {
    56. ArrayList<String> emptyList = new ArrayList<String>(Arrays.asList(new String[] {}));
    57. emptyList.clear();
    58. Block targetBlock;
    59. boolean walktest;
    60. String chunkOwner;
    61. ArrayList<String> friendsList;
    62. if (!event.isCancelled()) {
    63. Block block = event.getBlockClicked();
    64. BlockFace face = event.getBlockFace();
    65. if (face.equals(BlockFace.UP) || face.equals(BlockFace.DOWN)|| face.equals(BlockFace.SELF)) {
    66. targetBlock = block;
    67. } else {
    68. targetBlock = block.getRelative(face);
    69. }
    70. chunkOwner = getConfig().getString("main.claims." + String.valueOf(targetBlock.getChunk().getX()) + "," + String.valueOf(targetBlock.getChunk().getZ()), null);
    71. if (chunkOwner == null) {
    72. chunkOwner = "";
    73. }
    74. chunkOwner = chunkOwner.toLowerCase();
    75. if (!(chunkOwner.equals(""))) {
    76. walktest = getConfig().getBoolean("main.players." + event.getPlayer().getName().toLowerCase() + ".walktest", false);
    77. if (walktest) {
    78. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_walkteston);
    79. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_chunkowner.replaceAll("##X##", String.valueOf(targetBlock.getChunk().getX())).replaceAll("##Y##", String.valueOf(targetBlock.getChunk().getZ())).replaceAll("##N##", chunkOwner.toLowerCase()));
    80. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_walktesthelp);
    81. event.setCancelled(true);
    82. event.setItemStack(new ItemStack(325,1));
    83. }
    84. else
    85. {
    86. if (!chunkOwner.equalsIgnoreCase(event.getPlayer().getName().toLowerCase())) {
    87. friendsList = new ArrayList<String>((List<String>) getConfig().getList("main.players." + chunkOwner.toLowerCase() + ".friends", emptyList));
    88. if (!friendsList.contains(event.getPlayer().getName().toLowerCase())) {
    89. if (!event.getPlayer().isOp()) {
    90. event.getPlayer().sendMessage(ChatColor.RED + "[CAC] " + loc_chunkowner.replaceAll("##X##", String.valueOf(targetBlock.getChunk().getX())).replaceAll("##Y##", String.valueOf(targetBlock.getChunk().getZ())).replaceAll("##N##", chunkOwner.toLowerCase()));
    91. event.setCancelled(true);
    92. event.setItemStack(new ItemStack(325,1));
    93. }
    94. }
    95. }
    96. }
    97. }
    98. }
    99. }
    100.  



    The problem is that even though I set the itemstack, and cancel the event, the bucket gets emptied. Have also tried with event.getplayer().setiteminhand and omitting setting at all. Wont work.
    How can I prevent the bucket from getting consumed?

    The strange thing is if player attempts to empty the empty bucket again somewhere, its coming water or lava as usual. Same with fill, the bucket is filled even tought the event is cancelled, and attempting to empty the filled bucket will "cancel" the empty event outside of plugin.
     
  2. Offline

    Trc202

    I remember running into this problem before. The event is canceled but the client just automatically assumes the event went through. When the player relogs, moves the bucket, attempts to pick or place using the bucket the updated version will be rendered by the client. I remember there being a fix to this by resending what ever was in the clients hand (although it's not an ideal solution). Someone else might be able to answer that part.
     
  3. How I do to resend what its in hand?
    SetItemInHand wont work, seems like its executed before event finalization.

    Also tried with getScheduler and then putting the SetItemInHand there, but then it complains it can't cast Runnable from a void.

    Tried with
    event.getPlayer().updateInventory();

    but as you see, updateInventory gets a strikethrough and the compiler starts crying about depreciated method.
     
  4. Offline

    xGhOsTkiLLeRx

    Don't worry, use updateInventory();
    There is no good replacement for this method...

    I had exactly the same issue with UnlimitedLava. I spent hours to fix it.
    This works for me (feel free to use it!)

    Code:java
    1. event.setCancelled(true);
    2. ItemStack bucket = new ItemStack(325, 1);
    3. player.setItemInHand(bucket);
    4. player.updateInventory();
     
  5. Yep, updateInventory does work currently, without using setItemInHand.

    But wonder, since the method is depreciated, bukkit dev team might remove the method altogheter in the next release?
     
  6. If I recall correctly, they won't remove it in the near future.
     
Thread Status:
Not open for further replies.

Share This Page