Помогите почемуто не работает timer.cancel();

Статус
Закрыто для дальнейших ответов.

Bezobrazie

Активный участник
Пользователь
Баллы
46
Имя в Minecraft
MySoulIsCry
У меня есть плагин с потоком. проблема в том что поток не вожможно отменить. я пытаюсь использовать cancel(); но оно постоянно выдает ошибку и срабатывает try catch, в ошибке сказано что якобы поток еще не запущен, хотя он по факту запущен.
Код:
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
     Player p = (Player)sender;
     if (args.length == 0) {
            p.sendMessage("§7[§d§lU§b§lM§7] Правильное использование - /check <НИК>");
            return false;
            }
     Player cheater = Bukkit.getPlayer(args[0]);

     if (p.hasPermission("moder.check")) {
          
            if(cheater == null) {
                    p.sendMessage("§7[§b§lU§d§lM§7] Игрок §b§l" + args[0] + "§7 не онлайн.");
                    return false;
                }
             Timer timer = new Timer(cheater, cheater.getLocation());
            if (args.length == 1) {
                p.sendMessage("§7[§b§lU§d§lM§7] Игрок §d§l" + cheater.getDisplayName() + " §7вызван на проверку.");
                cheater.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 3600, 250));
                cheater.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 3600, 250));
                String str = new String("god " +cheater.getDisplayName());
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), str);
                cheater.sendTitle("§d§lВы были вызваны на проверку!", "§d§lВся информация находится в чате!");
                cheater.sendMessage("§7[§b§lU§d§lM§7] Вас вызвали на проверку! Не волнуйтесь, напишите в чат ваш §d§lID Discord§7. Если от вас не поступит ответ в течении 3х минут вы будете забанены §d§lНАВСЕГДА§7.");  
                timer.runTaskTimer(plugin, 80, 20);
                timer.time = 180;
              
                return false;
                }
            if (args.length == 2) {
                if(args[1].equalsIgnoreCase("stop")) {
                try {
                    timer.cancel();
                }catch(Exception e){
                    p.sendMessage("§7[§b§lU§d§lM§7] Игрок §d§l" + cheater.getDisplayName() + "§7 не был вызван на проверку.");
                    return false;
                }
                p.sendMessage("§7[§b§lU§d§lM§7] Вы отключили проверку для игрока §d§l" + args[0]);
                return false;
            }
                p.sendMessage("§7[§b§lU§d§lM§7] Выключить проверку игроку - §d§l/check [НИК] stop");
                }
     }
     p.sendMessage("§7[§b§lU§d§lM§7] Команды не существует или у вас нет прав");
            return false; }
}
 
Tы при каждом вводе команды создаешь новый таймер. Простейшее решение - храни переменную таймера за пределами метода onCommand.
 
Tы при каждом вводе команды создаешь новый таймер. Простейшее решение - храни переменную таймера за пределами метода onCommand.
немного не понимаю как это сделать если при таком случае не получится передать игрока в поток а это нужно обязательно.
 
немного не понимаю как это сделать если при таком случае не получится передать игрока в поток а это нужно обязательно.
Просто присваивай ей значение уже в команде.
 
Просто присваивай ей значение уже в команде.
да оно работает! но оно одноразовое, просто выдает ошибку на строчке timer.runTaskTimer(plugin, 80, 20); оно как будто не отмолило поток
Код:
public class Shop implements CommandExecutor {
  
   private Main plugin;
   private Main main = (Main)Main.getPlugin(Main.class);
   Timer timer = new Timer();
   public Shop(Main main) {
     this.plugin = main;
   }
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
     Player p = (Player)sender;
     if (args.length == 0) {
            p.sendMessage("§7[§d§lU§b§lM§7] Правильное использование - /check <НИК>");
            return false;
            }
     Player cheater = Bukkit.getPlayer(args[0]);

     if (p.hasPermission("moder.check")) {
          
            if(cheater == null) {
                    p.sendMessage("§7[§b§lU§d§lM§7] Игрок §b§l" + args[0] + "§7 не онлайн.");
                    return false;
                }
            
            if (args.length == 1) {
                p.sendMessage("§7[§b§lU§d§lM§7] Игрок §d§l" + cheater.getDisplayName() + " §7вызван на проверку.");
                cheater.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 3600, 250));
                cheater.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 3600, 250));
                String str = new String("god " +cheater.getDisplayName());
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), str);
                cheater.sendTitle("§d§lВы были вызваны на проверку!", "§d§lВся информация находится в чате!");
                cheater.sendMessage("§7[§b§lU§d§lM§7] Вас вызвали на проверку! Не волнуйтесь, напишите в чат ваш §d§lID Discord§7. Если от вас не поступит ответ в течении 3х минут вы будете забанены §d§lНАВСЕГДА§7.");  
                timer.runTaskTimer(plugin, 80, 20);
                timer.time = 180;
                timer.player = cheater;
                timer.loc = cheater.getLocation();
              
                return false;
                }
            if (args.length == 2) {
                if(args[1].equalsIgnoreCase("stop")) {
                try {
                    timer.player = cheater;
                    timer.loc = cheater.getLocation();
                    timer.cancel();
                }catch(Exception e){
                    p.sendMessage("§7[§b§lU§d§lM§7] Игрок §d§l" + cheater.getDisplayName() + "§7 не был вызван на проверку.");
                    return false;
                }
                p.sendMessage("§7[§b§lU§d§lM§7] Вы отключили проверку для игрока §d§l" + args[0]);
                return false;
            }
                p.sendMessage("§7[§b§lU§d§lM§7] Выключить проверку игроку - §d§l/check [НИК] stop");
                }
     }
     p.sendMessage("§7[§b§lU§d§lM§7] Команды не существует или у вас нет прав");
            return false; }
}
проверку нельзя вызвать даже сразу на 2х человек, скорее всего это происходит из за того что я имею всего 1 объект класса с потоком.
 
Последнее редактирование:
да оно работает! но оно одноразовое, просто выдает ошибку на строчке timer.runTaskTimer(plugin, 80, 20); оно как будто не отмолило поток
Код:
public class Shop implements CommandExecutor {
 
   private Main plugin;
   private Main main = (Main)Main.getPlugin(Main.class);
   Timer timer = new Timer();
   public Shop(Main main) {
     this.plugin = main;
   }
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
     Player p = (Player)sender;
     if (args.length == 0) {
            p.sendMessage("§7[§d§lU§b§lM§7] Правильное использование - /check <НИК>");
            return false;
            }
     Player cheater = Bukkit.getPlayer(args[0]);

     if (p.hasPermission("moder.check")) {
         
            if(cheater == null) {
                    p.sendMessage("§7[§b§lU§d§lM§7] Игрок §b§l" + args[0] + "§7 не онлайн.");
                    return false;
                }
           
            if (args.length == 1) {
                p.sendMessage("§7[§b§lU§d§lM§7] Игрок §d§l" + cheater.getDisplayName() + " §7вызван на проверку.");
                cheater.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 3600, 250));
                cheater.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 3600, 250));
                String str = new String("god " +cheater.getDisplayName());
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), str);
                cheater.sendTitle("§d§lВы были вызваны на проверку!", "§d§lВся информация находится в чате!");
                cheater.sendMessage("§7[§b§lU§d§lM§7] Вас вызвали на проверку! Не волнуйтесь, напишите в чат ваш §d§lID Discord§7. Если от вас не поступит ответ в течении 3х минут вы будете забанены §d§lНАВСЕГДА§7."); 
                timer.runTaskTimer(plugin, 80, 20);
                timer.time = 180;
                timer.player = cheater;
                timer.loc = cheater.getLocation();
             
                return false;
                }
            if (args.length == 2) {
                if(args[1].equalsIgnoreCase("stop")) {
                try {
                    timer.player = cheater;
                    timer.loc = cheater.getLocation();
                    timer.cancel();
                }catch(Exception e){
                    p.sendMessage("§7[§b§lU§d§lM§7] Игрок §d§l" + cheater.getDisplayName() + "§7 не был вызван на проверку.");
                    return false;
                }
                p.sendMessage("§7[§b§lU§d§lM§7] Вы отключили проверку для игрока §d§l" + args[0]);
                return false;
            }
                p.sendMessage("§7[§b§lU§d§lM§7] Выключить проверку игроку - §d§l/check [НИК] stop");
                }
     }
     p.sendMessage("§7[§b§lU§d§lM§7] Команды не существует или у вас нет прав");
            return false; }
}
проверку нельзя вызвать даже сразу на 2х человек, скорее всего это происходит из за того что я имею всего 1 объект класса с потоком.
Используй ооп.

Создай класс, назови его CheckingPlayer, наследуй BukkitRunnable.
Объяви внутри класса переменную String с именем игрока и создай конструктор для присвоение переменной.
Переопредели метод run и задай там логику, чтобы после определенного времени таймер выключился.

Затем создай хэшмап в главном классе плагина. Ключом будет String, значение класс CheckingPlayer.
Затем просто при вызове проверки на читера, проверяй, существует ли этот игрок в карте, если нет, создавай новый экземпляр CheckingPlayer, добавляй в карту и запускай таймер вызвав соответствующий метод внутри этого экземпляра.

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

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

p.s То что ты называешь потоком - и близко не поток. Ты просто создаешь задачу шедулеру, который в свою очередь планирует ее в основном потоке и выполняет. При отмене таймера, он просто удаляется из шедулера.
Исключением является асинхронная задача, они исполняются в других потоках, но их не безопасно использовать с Bukkit api.
 
Используй ооп.

Создай класс, назови его CheckingPlayer, наследуй BukkitRunnable.
Объяви внутри класса переменную String с именем игрока и создай конструктор для присвоение переменной.
Переопредели метод run и задай там логику, чтобы после определенного времени таймер выключился.

Затем создай хэшмап в главном классе плагина. Ключом будет String, значение класс CheckingPlayer.
Затем просто при вызове проверки на читера, проверяй, существует ли этот игрок в карте, если нет, создавай новый экземпляр CheckingPlayer, добавляй в карту и запускай таймер вызвав соответствующий метод внутри этого экземпляра.

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

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

p.s То что ты называешь потоком - и близко не поток. Ты просто создаешь задачу шедулеру, который в свою очередь планирует ее в основном потоке и выполняет. При отмене таймера, он просто удаляется из шедулера.
Исключением является асинхронная задача, они исполняются в других потоках, но их не безопасно использовать с Bukkit api.
Люто сложно для моего уровня знания JAVA, но все равно спасибо я чтото понял)
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх