1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем Bezobrazie, 10 июн 2021.

Статус темы:
Закрыта.
  1. Автор темы
    Bezobrazie

    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; }
    }
    
     
  2. imDaniX

    imDaniX Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Tы при каждом вводе команды создаешь новый таймер. Простейшее решение - храни переменную таймера за пределами метода onCommand.
     
  3. Автор темы
    Bezobrazie

    Bezobrazie Активный участник Пользователь

    Баллы:
    46
    Имя в Minecraft:
    MySoulIsCry
    немного не понимаю как это сделать если при таком случае не получится передать игрока в поток а это нужно обязательно.
     
  4. imDaniX

    imDaniX Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Просто присваивай ей значение уже в команде.
     
  5. Автор темы
    Bezobrazie

    Bezobrazie Активный участник Пользователь

    Баллы:
    46
    Имя в Minecraft:
    MySoulIsCry
    да оно работает! но оно одноразовое, просто выдает ошибку на строчке 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 объект класса с потоком.
     
    Последнее редактирование: 10 июн 2021
  6. MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Используй ооп.

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

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

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

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

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

    Bezobrazie Активный участник Пользователь

    Баллы:
    46
    Имя в Minecraft:
    MySoulIsCry
    Люто сложно для моего уровня знания JAVA, но все равно спасибо я чтото понял)
     
Статус темы:
Закрыта.

Поделиться этой страницей