Как дать сообщение в bukkit через 60 секунд?

спасибо за все, что помогло мне! Теперь буду подробнее. Что я хочу сделать, так это плагин Bukkit, который через одну минуту, и если игрок что-то уронил, на консоли отображается информационное сообщение, например «Игроки двигаются», но я просто могу сделать так, чтобы появилось первое сообщение: «Игрок что-то уронил». и я думаю, что ошибка связана с логическим значением, которое я использовал. Пожалуйста, кто-нибудь может помочь мне с bukkit? Это мой код:

public class HgCake extends JavaPlugin implements Listener{
    boolean reference = false;
    @Override
    public void onEnable() {
        Bukkit.getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void onDropItem (PlayerDropItemEvent e) {
        getLogger().info("Player dropped something");
        reference = true;
    }

    public void onPlayerMove (PlayerMoveEvent e){
        if (reference = true){
            getLogger().info("Players are moving");
        }
    }
}

person PinguCraft    schedule 12.09.2013    source источник


Ответы (3)


Bukkit имеет встроенную систему планирования, о которой вы можете прочитать в разделе Программирование планировщика.

Используйте это вместо обычных таймеров Java, поверьте мне. Это сделает вашу жизнь проще в долгосрочной перспективе.

Чтобы сделать то, что вы хотите сделать, вам понадобится класс BukkitRunnable для планировщика.

Это общий вариант, который я слишком упростил для примера:

public class Callback extends BukkitRunnable{
        private Object targetObject;
        public Method targetMethod;
        private Object[] perameters;

        public Callback(Object targetObject, String methodName, Object[] argsOrNull){
                try {
                    this.targetMethod = targetObject.getClass().getMethod(methodName, (Class<?>[]) argsOrNull);
                } catch (Exception e){
                    e.printStackTrace();
                }
                this.targetObject = targetObject;
                this.perameters = argsOrNull;
        }

        public void run(){
                try {
                    this.targetMethod.invoke(this.targetObject,perameters);
                } catch (Exception e){
                    e.printStackTrace();
                }
        }
}

Затем вы создаете объект этого запускаемого объекта, предоставляя метод/реквизиты обратного вызова в качестве аргументов, и передаете его планировщику для запуска через 60 секунд:

Что касается движения, вы просто смотрите, пока предмет падает, и никто еще не двигался.

public class DropWatcher implements Listener {
    private Boolean hasAnythingMoved;
    private Boolean dropped;
    private Pwncraft plugin;
    private Player player;

    public DropWatcher(Pwncraft plugin, Player player){
        this.player = player;
        this.hasAnythingMoved = false;
        this.dropped = false;
        this.plugin = plugin;
        this.plugin.pluginManager.registerEvents(this, plugin);
    }

    //Drop event listener: When the player drops an item, it sets dropped to true, and initiates the countdown.
    @EventHandler
    public void onDropItem (PlayerDropItemEvent e) {
        if(e.getPlayer().equals(this.player) && !this.dropped){
            this.dropped = true;
            BukkitCallbackTask doInSixtySeconds = new BukkitCallbackTask(this, "timesUp" , null);
            doInSixtySeconds.runTaskLater(plugin, 1200); // time is in ticks (20 ticks +/- = 1 sec), so 1200 ticks = 1 min.
        }
    }

    //Watches for other-players' movement, and sets hasAnythingMoved to true if so.
    @EventHandler
    public void onMove (PlayerMoveEvent e){
        if(!e.getPlayer().equals(this.player) && this.dropped && !this.hasAnythingMoved){
            this.hasAnythingMoved = true;
        }
    }

    /*
    This is the method the runnable calls when the timer is up.
    It checks for movement, and if so, sends a message and explodes the player 
    (Just because it can. You're welcome to veto the explosion.) 
    */
    public void timesUp(){

        if(this.hasAnythingMoved){
            this.player.sendMessage("Someone moved! Time to party!");
            this.player.getWorld().createExplosion(this.player.getLocation(), 5F);
            this.dropped = false;
            this.hasAnythingMoved = false;
        }
    }
}
person Sintrinsic    schedule 20.12.2013

Я думаю, вы забыли @EventHandler для PlayerMoveEvent.

Так должно быть:

public class HgCake extends JavaPlugin implements Listener{
boolean reference = false;
@Override
public void onEnable() {
    Bukkit.getServer().getPluginManager().registerEvents(this, this);
}

@EventHandler
public void onDropItem (PlayerDropItemEvent e) {
    getLogger().info("Player dropped something");
    reference = true;
}

@EventHandler
public void onPlayerMove (PlayerMoveEvent e){
    if (reference = true){
        getLogger().info("Players are moving");
    }
}

}

person letomcat    schedule 14.09.2013

person    schedule
comment
Пожалуйста, добавьте описание к вашему ответу - person Abhinav Singh Maurya; 05.10.2015
comment
Например, вы можете объяснить, почему параметр delay равен 120, когда OP запросил 60-секундную задержку. - person dcsohl; 05.10.2015
comment
Добро пожаловать в Stack Overflow! Не могли бы вы изменить объяснение того, почему этот код отвечает на вопрос? Ответы, содержащие только код, не рекомендуются, поскольку они не учат решению. - person NathanOliver; 05.10.2015