From cbadd02b73c6a1f7451002d256ed4cb6d81eb078 Mon Sep 17 00:00:00 2001 From: Tristan Vermeesch Date: Mon, 27 Oct 2025 08:42:02 +0100 Subject: [PATCH] feat: add offline player support in conditions engine --- build.gradle | 4 +- java17-build.gradle | 4 +- java21-build.gradle | 4 +- .../playbosswar/com/CommandTimerPlugin.java | 4 +- .../playbosswar/com/commands/MainCommand.java | 8 +- .../com/conditionsengine/EventsManager.java | 12 +- .../com/gui/conditions/ConditionMenu.java | 7 + .../com/tasks/TaskValidationHelpers.java | 15 +- .../playbosswar/com/tasks/TasksManager.java | 154 ++++++++++-------- src/main/resources/plugin.yml | 2 +- 10 files changed, 130 insertions(+), 84 deletions(-) diff --git a/build.gradle b/build.gradle index 372a0617..b90aeb76 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ java { } group = 'me.playbosswar.com' -version = '8.13.2' +version = '8.14.0' description = 'CommandTimer' repositories { @@ -74,7 +74,7 @@ publishing { maven(MavenPublication) { groupId = 'me.playbosswar.com' artifactId = 'commandtimer' - version = '8.13.2' + version = '8.14.0' from components.java } diff --git a/java17-build.gradle b/java17-build.gradle index eacdf107..4ba43aed 100644 --- a/java17-build.gradle +++ b/java17-build.gradle @@ -10,7 +10,7 @@ java { group = 'me.playbosswar.com' -version = '8.13.2' +version = '8.14.0' description = 'CommandTimer' repositories { @@ -63,7 +63,7 @@ publishing { maven(MavenPublication) { groupId = 'me.playbosswar.com' artifactId = 'commandtimer-java17' - version = '8.13.2' + version = '8.14.0' from components.java } diff --git a/java21-build.gradle b/java21-build.gradle index 2186608f..2633ed2a 100644 --- a/java21-build.gradle +++ b/java21-build.gradle @@ -10,7 +10,7 @@ java { group = 'me.playbosswar.com' -version = '8.13.2' +version = '8.14.0' description = 'CommandTimer' repositories { @@ -67,7 +67,7 @@ publishing { maven(MavenPublication) { groupId = 'me.playbosswar.com' artifactId = 'commandtimer-java21' - version = '8.13.2' + version = '8.14.0' from components.java } } diff --git a/src/main/java/me/playbosswar/com/CommandTimerPlugin.java b/src/main/java/me/playbosswar/com/CommandTimerPlugin.java index 5b08da9d..a1d9ec8c 100644 --- a/src/main/java/me/playbosswar/com/CommandTimerPlugin.java +++ b/src/main/java/me/playbosswar/com/CommandTimerPlugin.java @@ -101,7 +101,7 @@ public void onEnable() { updater = new Updater(this); metrics = new Metrics(CommandTimerPlugin.getPlugin(), 9657); hooksManager = new HooksManager(); - tasksManager = new TasksManager(); + tasksManager = new TasksManager(this); inventoryManager = new InventoryManager(this); conditionEngineManager = new ConditionEngineManager(); eventsManager = new EventsManager(tasksManager); @@ -142,7 +142,7 @@ private void loadMetrics() { } public void registerCommands() { - getCommand("commandtimer").setExecutor(new MainCommand()); + getCommand("commandtimer").setExecutor(new MainCommand(this)); } public void loadConfig() { diff --git a/src/main/java/me/playbosswar/com/commands/MainCommand.java b/src/main/java/me/playbosswar/com/commands/MainCommand.java index d2da1f24..519652ea 100644 --- a/src/main/java/me/playbosswar/com/commands/MainCommand.java +++ b/src/main/java/me/playbosswar/com/commands/MainCommand.java @@ -16,6 +16,7 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -24,8 +25,13 @@ import java.util.List; public class MainCommand implements CommandExecutor { + private final Plugin plugin; private final LanguageManager languageManager = CommandTimerPlugin.getLanguageManager(); + public MainCommand(Plugin plugin) { + this.plugin = plugin; + } + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String s, String[] args) { if(!PermissionUtils.playerHasSomeAccess(sender)) { @@ -103,7 +109,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @N pl.getTasksManager().disable(); pl.saveDefaultConfig(); - pl.setTasksManager(new TasksManager()); + pl.setTasksManager(new TasksManager(plugin)); Messages.sendMessage(sender, CommandTimerPlugin.getLanguageManager().get(LanguageKey.PLUGIN_RELOADED)); return true; diff --git a/src/main/java/me/playbosswar/com/conditionsengine/EventsManager.java b/src/main/java/me/playbosswar/com/conditionsengine/EventsManager.java index 6468d279..95c4c388 100644 --- a/src/main/java/me/playbosswar/com/conditionsengine/EventsManager.java +++ b/src/main/java/me/playbosswar/com/conditionsengine/EventsManager.java @@ -13,6 +13,7 @@ import me.playbosswar.com.tasks.TasksManager; import me.playbosswar.com.utils.Messages; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; @@ -74,10 +75,10 @@ public void handleTriggeredEvent(ConditionExtension extension, EventExtension ev return; } - Player p = null; + OfflinePlayer p = null; UUID uuid = findPotentialPlayer(values); if(uuid != null) { - p = Bukkit.getPlayer(uuid); + p = Bukkit.getOfflinePlayer(uuid); } boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), p); @@ -137,6 +138,13 @@ private boolean checkSimpleCondition(EventSimpleCondition simpleCondition, Li return value.getName().equals(expected.getName()); } + if(receivedValue.getType() == Boolean.class) { + Boolean value = (Boolean) receivedValue.getDefaultValue(); + Boolean expected = (Boolean) simpleCondition.getValue(); + + return value.equals(expected); + } + return false; } diff --git a/src/main/java/me/playbosswar/com/gui/conditions/ConditionMenu.java b/src/main/java/me/playbosswar/com/gui/conditions/ConditionMenu.java index eb299cb3..0ddf91c7 100644 --- a/src/main/java/me/playbosswar/com/gui/conditions/ConditionMenu.java +++ b/src/main/java/me/playbosswar/com/gui/conditions/ConditionMenu.java @@ -173,6 +173,13 @@ public void init(Player player, InventoryContents contents) { new ConditionMenu(task, condition, onClose).INVENTORY.open(player); }); } + + if(neededValue.getType() == Boolean.class) { + ((ConditionParamField) conditionParamField).setValue(!((ConditionParamField) conditionParamField).getValue()); + task.storeInstance(); + new ConditionMenu(task, condition, onClose).INVENTORY.open(player); + } + }); contents.set(1, i, clickableItem); diff --git a/src/main/java/me/playbosswar/com/tasks/TaskValidationHelpers.java b/src/main/java/me/playbosswar/com/tasks/TaskValidationHelpers.java index 4924607b..9c650f9d 100644 --- a/src/main/java/me/playbosswar/com/tasks/TaskValidationHelpers.java +++ b/src/main/java/me/playbosswar/com/tasks/TaskValidationHelpers.java @@ -10,6 +10,7 @@ import me.playbosswar.com.conditionsengine.validations.ConditionType; import me.playbosswar.com.conditionsengine.validations.SimpleCondition; import me.playbosswar.com.utils.Messages; +import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; import org.jeasy.rules.api.Facts; @@ -19,7 +20,7 @@ import java.util.Optional; public class TaskValidationHelpers { - public static boolean processCondition(Condition topCondition, @Nullable Player p) { + public static boolean processCondition(Condition topCondition, @Nullable OfflinePlayer p) { ConditionType conditionType = topCondition.getConditionType(); if(conditionType.equals(ConditionType.SIMPLE)) { return checkSimpleCondition(topCondition.getSimpleCondition(), p); @@ -41,7 +42,7 @@ public static boolean processCondition(Condition topCondition, @Nullable Player return false; } - private static boolean checkSimpleCondition(SimpleCondition simpleCondition, @Nullable Player p) { + private static boolean checkSimpleCondition(SimpleCondition simpleCondition, @Nullable OfflinePlayer p) { final ConditionEngineManager conditionEngineManager = CommandTimerPlugin.getInstance().getConditionEngineManager(); ConditionRule rule = conditionEngineManager.getRule(simpleCondition.getConditionGroup(), @@ -90,6 +91,16 @@ private static boolean checkSimpleCondition(SimpleCondition simpleCondition, @Nu if(neededValue.getType() == World.class) { facts.put(conditionParamField.getName(), (World) conditionParamField.getValue()); } + + if(neededValue.getType() == Boolean.class) { + facts.put(conditionParamField.getName(), (Boolean) conditionParamField.getValue()); + } + } + } + + for (NeededValue neededValue : neededValues) { + if (facts.get(neededValue.getName()) == null) { + facts.put(neededValue.getName(), neededValue.getDefaultValue()); } } diff --git a/src/main/java/me/playbosswar/com/tasks/TasksManager.java b/src/main/java/me/playbosswar/com/tasks/TasksManager.java index 5acbe048..5f68efbe 100644 --- a/src/main/java/me/playbosswar/com/tasks/TasksManager.java +++ b/src/main/java/me/playbosswar/com/tasks/TasksManager.java @@ -20,6 +20,7 @@ import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandException; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.Nullable; import me.playbosswar.com.CommandTimerPlugin; @@ -34,6 +35,7 @@ public class TasksManager { + private final Plugin plugin; private static final String CONDITION_NO_MATCH = "Conditions did not match"; private static final Random RANDOM = new Random(); private static final String ALPHA_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -42,14 +44,15 @@ public class TasksManager { public boolean stopRunner = false; public int executionsSinceLastSync = 0; - public TasksManager() { - if(CommandTimerPlugin.getPlugin().getConfig().getBoolean("database.enabled")) { + public TasksManager(Plugin plugin) { + this.plugin = plugin; + if (plugin.getConfig().getBoolean("database.enabled")) { try { Messages.sendConsole("Loading all tasks from database"); List tasks = DatabaseUtils.getAllTasksFromDatabase(); loadedTasks.addAll(tasks); Messages.sendConsole("Loaded " + loadedTasks.size() + " tasks from database"); - } catch(SQLException e) { + } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } @@ -58,7 +61,7 @@ public TasksManager() { } loadedTasks.forEach(task -> { - if(task.isResetExecutionsAfterRestart()) { + if (task.isResetExecutionsAfterRestart()) { task.setTimesExecuted(0); task.setLastExecuted(new Date()); task.storeInstance(); @@ -92,19 +95,19 @@ public Task getTaskByName(String name) { } public void removeTask(Task task) throws IOException { - if(CommandTimerPlugin.getPlugin().getConfig().getBoolean("database.enabled")) { + if (CommandTimerPlugin.getPlugin().getConfig().getBoolean("database.enabled")) { try { CommandTimerPlugin.getTaskDao().delete(task); java.nio.file.Files.delete(Paths.get(Files.getTaskLocalExecutionFile(task.getId()))); loadedTasks.remove(task); - } catch(SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } else { try { java.nio.file.Files.delete(Paths.get(Files.getTaskFile(task.getId()))); loadedTasks.remove(task); - } catch(IOException e) { + } catch (IOException e) { e.printStackTrace(); } } @@ -133,7 +136,7 @@ private boolean runConsolePerUserCommand(Task task, TaskCommand taskCommand, Lis String command = taskCommand.getCommand(); Collection affectedPlayers = (Collection) Bukkit.getOnlinePlayers(); - if(!scopedPlayers.isEmpty()) { + if (!scopedPlayers.isEmpty()) { affectedPlayers = scopedPlayers.stream().map(Bukkit::getPlayer).filter(Objects::nonNull).collect(Collectors.toList()); } @@ -141,23 +144,23 @@ private boolean runConsolePerUserCommand(Task task, TaskCommand taskCommand, Lis boolean delayedExecutions = taskCommand.getInterval().toSeconds() > 0; int i = 0; boolean willExecute = false; - for(Player p : affectedPlayers) { - if(task.hasCondition()) { + for (Player p : affectedPlayers) { + if (task.hasCondition()) { boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), p); - if(!valid) { + if (!valid) { Messages.sendDebugConsole(CONDITION_NO_MATCH); continue; } } willExecute = true; - if(delayedExecutions) { + if (delayedExecutions) { CommandTimerPlugin.getScheduler().runTaskLater(() -> { Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p)); executionsSinceLastSync++; }, (20L * i * taskCommand.getInterval().toSeconds()) + 1); } else { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p)); + Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p))); executionsSinceLastSync++; } i++; @@ -166,20 +169,27 @@ private boolean runConsolePerUserCommand(Task task, TaskCommand taskCommand, Lis return willExecute; } - private boolean runConsolePerUserOfflineCommand(TaskCommand taskCommand) throws CommandException { + private boolean runConsolePerUserOfflineCommand(Task task, TaskCommand taskCommand) throws CommandException { String command = taskCommand.getCommand(); boolean delayedExecutions = taskCommand.getInterval().toSeconds() > 0; int i = 0; // TODO: Caching could be used heres, Bukkit.getOfflinePlayers() is pretty expensive - for(OfflinePlayer p : Bukkit.getOfflinePlayers()) { - if(delayedExecutions) { + for (OfflinePlayer p : Bukkit.getOfflinePlayers()) { + if (task.hasCondition()) { + boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), p); + if (!valid) { + Messages.sendDebugConsole(CONDITION_NO_MATCH); + continue; + } + } + if (delayedExecutions) { CommandTimerPlugin.getScheduler().runTaskLater(() -> { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p)); + Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p))); executionsSinceLastSync++; }, (20L * i * taskCommand.getInterval().toSeconds()) + 1); } else { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p)); + Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, p))); executionsSinceLastSync++; } i++; @@ -193,16 +203,16 @@ private boolean runConsolePerUserCommand(Task task, TaskCommand taskCommand) thr } private boolean runConsoleCommand(Task task, TaskCommand taskCommand) throws CommandException { - if(task.hasCondition()) { + if (task.hasCondition()) { boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), null); - if(!valid) { + if (!valid) { Messages.sendDebugConsole(CONDITION_NO_MATCH); return false; } } String command = taskCommand.getCommand(); - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, null)); + Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), PAPIHook.parsePAPI(command, null))); executionsSinceLastSync++; return true; } @@ -211,7 +221,7 @@ private boolean runPlayerCommand(Task task, TaskCommand taskCommand, List String command = taskCommand.getCommand(); Collection affectedPlayers = (Collection) Bukkit.getOnlinePlayers(); - if(!scopedPlayers.isEmpty()) { + if (!scopedPlayers.isEmpty()) { affectedPlayers = scopedPlayers.stream().map(Bukkit::getPlayer).filter(Objects::nonNull).collect(Collectors.toList()); } @@ -219,17 +229,17 @@ private boolean runPlayerCommand(Task task, TaskCommand taskCommand, List boolean delayedExecution = taskCommand.getInterval().toSeconds() > 0; int i = 0; boolean willExecute = false; - for(Player p : affectedPlayers) { - if(task.hasCondition()) { + for (Player p : affectedPlayers) { + if (task.hasCondition()) { boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), p); - if(!valid) { + if (!valid) { Messages.sendDebugConsole(CONDITION_NO_MATCH); continue; } } willExecute = true; - if(delayedExecution) { + if (delayedExecution) { CommandTimerPlugin.getScheduler().runTaskLater(() -> runForPlayer(p, command), (20L * i * taskCommand.getInterval().toSeconds()) + 1); } else { @@ -243,14 +253,16 @@ private boolean runPlayerCommand(Task task, TaskCommand taskCommand, List private void runForPlayer(Player p, String command) { String parsedCommand = PAPIHook.parsePAPI(command, p); - boolean executed = p.performCommand(parsedCommand); + Bukkit.getScheduler().runTask(plugin, () -> { + boolean executed = p.performCommand(parsedCommand); - if(!executed) { - String errorMessage = - new StringEnhancer("Failed to execute command {command}").add("taskName", command).parse(); - throw new CommandException(errorMessage); - } - executionsSinceLastSync++; + if (!executed) { + String errorMessage = + new StringEnhancer("Failed to execute command {command}").add("taskName", command).parse(); + throw new CommandException(errorMessage); + } + executionsSinceLastSync++; + }); } private boolean runPlayerCommand(Task task, TaskCommand taskCommand) { @@ -261,7 +273,7 @@ private boolean runOperatorCommand(Task task, TaskCommand taskCommand, List affectedPlayers = (Collection) Bukkit.getOnlinePlayers(); - if(!scopedPlayers.isEmpty()) { + if (!scopedPlayers.isEmpty()) { affectedPlayers = scopedPlayers.stream().map(Bukkit::getPlayer).filter(Objects::nonNull).collect(Collectors.toList()); } @@ -269,17 +281,17 @@ private boolean runOperatorCommand(Task task, TaskCommand taskCommand, List 0; int i = 0; boolean willExecute = false; - for(Player p : affectedPlayers) { + for (Player p : affectedPlayers) { boolean wasAlreadyOp = p.isOp(); try { p.setOp(true); - if(task.hasCondition()) { + if (task.hasCondition()) { boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), p); - if(!valid) { + if (!valid) { Messages.sendDebugConsole(CONDITION_NO_MATCH); - if(!wasAlreadyOp) { + if (!wasAlreadyOp) { p.setOp(false); } continue; @@ -287,18 +299,18 @@ private boolean runOperatorCommand(Task task, TaskCommand taskCommand, List { p.performCommand(PAPIHook.parsePAPI(command, p)); executionsSinceLastSync++; }, (20L * i * taskCommand.getInterval().toSeconds()) + 1); } else { - p.performCommand(PAPIHook.parsePAPI(command, p)); + Bukkit.getScheduler().runTask(plugin, () -> p.performCommand(PAPIHook.parsePAPI(command, p))); executionsSinceLastSync++; } } finally { - if(!wasAlreadyOp) { + if (!wasAlreadyOp) { p.setOp(false); } } @@ -313,9 +325,9 @@ private boolean runOperatorCommand(Task task, TaskCommand taskCommand) { } private boolean runConsoleProxyCommand(Task task, TaskCommand taskCommand) { - if(task.hasCondition()) { + if (task.hasCondition()) { boolean valid = TaskValidationHelpers.processCondition(task.getCondition(), null); - if(!valid) { + if (!valid) { Messages.sendDebugConsole(CONDITION_NO_MATCH); return false; } @@ -331,49 +343,51 @@ private boolean runConsoleProxyCommand(Task task, TaskCommand taskCommand) { e.printStackTrace(); } - Bukkit.getServer().sendPluginMessage(CommandTimerPlugin.getPlugin(), "commandtimer:main", b.toByteArray()); + Bukkit.getServer().sendPluginMessage(CommandTimerPlugin.getPlugin(), "commandtimer:main", b.toByteArray()); executionsSinceLastSync++; return true; } public void processCommandExecution(Task task, TaskCommand taskCommand) { - if(!task.isActive()) { + if (!task.isActive()) { return; } - Gender gender = taskCommand.getGender(); - - boolean executed = false; - if(gender.equals(Gender.CONSOLE)) { - executed = runConsoleCommand(task, taskCommand); - } else if(gender.equals(Gender.PLAYER)) { - executed = runPlayerCommand(task, taskCommand); - } else if(gender.equals(Gender.OPERATOR)) { - executed = runOperatorCommand(task, taskCommand); - } else if(gender.equals(Gender.CONSOLE_PER_USER)) { - executed = runConsolePerUserCommand(task, taskCommand); - } else if(gender.equals(Gender.CONSOLE_PER_USER_OFFLINE)) { - executed = runConsolePerUserOfflineCommand(taskCommand); - } else if(gender.equals(Gender.CONSOLE_PROXY)) { - executed = runConsoleProxyCommand(task, taskCommand); - } + Bukkit.getScheduler().runTaskAsynchronously(CommandTimerPlugin.getPlugin(), () -> { + Gender gender = taskCommand.getGender(); + + boolean executed = false; + if (gender.equals(Gender.CONSOLE)) { + executed = runConsoleCommand(task, taskCommand); + } else if (gender.equals(Gender.PLAYER)) { + executed = runPlayerCommand(task, taskCommand); + } else if (gender.equals(Gender.OPERATOR)) { + executed = runOperatorCommand(task, taskCommand); + } else if (gender.equals(Gender.CONSOLE_PER_USER)) { + executed = runConsolePerUserCommand(task, taskCommand); + } else if (gender.equals(Gender.CONSOLE_PER_USER_OFFLINE)) { + executed = runConsolePerUserOfflineCommand(task, taskCommand); + } else if (gender.equals(Gender.CONSOLE_PROXY)) { + executed = runConsoleProxyCommand(task, taskCommand); + } - if(executed) { - task.setLastExecuted(new Date()); - task.setTimesExecuted(task.getTimesExecuted() + 1); - task.storeInstance(); - } + if (executed) { + task.setLastExecuted(new Date()); + task.setTimesExecuted(task.getTimesExecuted() + 1); + task.storeInstance(); + } + }); } public int getNextTaskCommandIndex(Task task) { // If it remains -1, that means that all commands should be executed int selectedCommandIndex = -1; - if(task.getCommandExecutionMode().equals(CommandExecutionMode.RANDOM)) { + if (task.getCommandExecutionMode().equals(CommandExecutionMode.RANDOM)) { selectedCommandIndex = Tools.getRandomInt(0, task.getCommands().size() - 1); - } else if(task.getCommandExecutionMode().equals(CommandExecutionMode.ORDERED)) { + } else if (task.getCommandExecutionMode().equals(CommandExecutionMode.ORDERED)) { int currentLatestCommandIndex = task.getLastExecutedCommandIndex(); - if(currentLatestCommandIndex >= task.getCommands().size() - 1) { + if (currentLatestCommandIndex >= task.getCommands().size() - 1) { selectedCommandIndex = 0; } else { selectedCommandIndex = currentLatestCommandIndex + 1; @@ -387,7 +401,7 @@ public void disable() { List tasksToStore = loadedTasks.stream().filter(Task::isActive).collect(Collectors.toList()); tasksToStore.forEach(Task::storeInstance); stopRunner = true; - if(runnerThread != null && runnerThread.isAlive()) { + if (runnerThread != null && runnerThread.isAlive()) { runnerThread.interrupt(); } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 97633f72..cd547ce8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ main: me.playbosswar.com.CommandTimerPlugin name: "CommandTimer" -version: "8.13.2" +version: "8.14.0" description: "Schedule commands like you want" author: PlayBossWar api-version: 1.13