Search code examples
javabukkit

Check if block is still in the world after delay


I want to check if a block that's placed is still there after a short delay and execute a command

I have tried with sleep but it just gives the block that was there before the delay

public class BlockListener implements Listener {
    @EventHandler
    public void check(BlockPlaceEvent e)
    {          
      Material blockType = e.getBlockPlaced().getType();
      int locationX = e.getBlockPlaced().getLocation().getBlockX();
      int locationY = e.getBlockPlaced().getLocation().getBlockY();
      int locationZ = e.getBlockPlaced().getLocation().getBlockZ();
      String locationXb = String.valueOf(locationX);
      String locationYb = String.valueOf(locationY);
      String locationZb = String.valueOf(locationZ);
      World world = e.getPlayer().getWorld();          
      if ((blockType == Material.PLAYER_HEAD) || (blockType == Material.PLAYER_WALL_HEAD))
        {
          try
          {
            Thread.sleep(1000);
          }
          catch (InterruptedException ex)
          {
            
          }
          Material block = world.getBlockAt(locationX, locationY, locationZ).getType();
          if((block == Material.PLAYER_WALL_HEAD) || (block == Material.PLAYER_HEAD)){
             //empty
          }
          else {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
          }
        }
      }

Solution

  • You should NEVER use the Thread.sleep method on spigot. It stop the all server.

    You need to use Scheduler (Tutorial - Javadoc: BukkitScheduler) :

    @EventHandler
    public void check(BlockPlaceEvent e) {
      Material blockType = e.getBlockPlaced().getType();
      int locationX = e.getBlockPlaced().getLocation().getBlockX();
      int locationY = e.getBlockPlaced().getLocation().getBlockY();
      int locationZ = e.getBlockPlaced().getLocation().getBlockZ();
      String locationXb = String.valueOf(locationX);
      String locationYb = String.valueOf(locationY);
      String locationZb = String.valueOf(locationZ);
      World world = e.getPlayer().getWorld();
      if ((blockType == Material.PLAYER_HEAD) || (blockType == Material.PLAYER_WALL_HEAD)) {
        Bukkit.getScheduler().runTaskLater(MyPlugin.getInstance(), () -> {
          Material block = world.getBlockAt(locationX, locationY, locationZ).getType();
          if ((block == Material.PLAYER_WALL_HEAD) || (block == Material.PLAYER_HEAD)) {
            //empty
          } else {
            Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
          }
        }, 20);
      }
    }
    

    Where:

    • MyPlugin.getInstance() is to get the instance of your JavaPlugin, it's also mostly called as plugin variable.
    • () -> {} is what will be run
    • 20 is the time (in ticks) that the server should wait. 20 ticks = 1 second.