diff --git a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/ServerUtils.java b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/ServerUtils.java index fe52252..6e04951 100644 --- a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/ServerUtils.java +++ b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/ServerUtils.java @@ -4,8 +4,6 @@ import co.aikar.commands.BukkitCommandCompletionContext; import co.aikar.commands.CommandCompletions; import co.aikar.commands.PaperCommandManager; -import java.lang.reflect.InvocationTargetException; -import java.util.Collections; import java.util.Map; import net.frankheijden.serverutils.bukkit.commands.CommandPlugins; @@ -60,6 +58,7 @@ public class ServerUtils extends JavaPlugin implements CommandExecutor { reload(); Bukkit.getPluginManager().registerEvents(new BukkitListener(), this); + plugin.enable(); ServerUtilsApp.tryCheckForUpdates(); } @@ -76,6 +75,7 @@ public class ServerUtils extends JavaPlugin implements CommandExecutor { public void onDisable() { super.onDisable(); restoreBukkitPluginCommand(); + plugin.disable(); } private void removeCommands(String... commands) { diff --git a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/commands/CommandServerUtils.java b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/commands/CommandServerUtils.java index 31bfb09..5a9101e 100644 --- a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/commands/CommandServerUtils.java +++ b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/commands/CommandServerUtils.java @@ -24,6 +24,7 @@ import net.frankheijden.serverutils.bukkit.reflection.RCraftServer; import net.frankheijden.serverutils.bukkit.utils.BukkitUtils; import net.frankheijden.serverutils.bukkit.utils.ReloadHandler; import net.frankheijden.serverutils.common.config.Messenger; +import net.frankheijden.serverutils.common.entities.AbstractResult; import net.frankheijden.serverutils.common.entities.CloseableResult; import net.frankheijden.serverutils.common.entities.Result; import net.frankheijden.serverutils.common.entities.ServerCommandSender; @@ -237,6 +238,35 @@ public class CommandServerUtils extends BaseCommand { result.sendTo(BukkitUtils.wrap(sender), "disabl", pluginName); } + /** + * Watches the given plugin and reloads it when a change is detected to the file. + * @param sender The sender of the command. + * @param pluginName The plugin name. + */ + @Subcommand("watchplugin") + @CommandCompletion("@plugins") + @CommandPermission("serverutils.watchplugin") + @Description("Watches the specified plugin for changes.") + public void onWatchPlugin(CommandSender sender, String pluginName) { + ServerCommandSender commandSender = BukkitUtils.wrap(sender); + AbstractResult result = BukkitPluginManager.get().watchPlugin(commandSender, pluginName); + result.sendTo(commandSender, "watch", pluginName); + } + + /** + * Stops watching the given plugin. + * @param sender The sender of the command. + * @param pluginName The plugin name. + */ + @Subcommand("unwatchplugin") + @CommandCompletion("@plugins") + @CommandPermission("serverutils.unwatchplugin") + @Description("Stops watching the specified plugin for changes.") + public void onUnwatchPlugin(CommandSender sender, String pluginName) { + AbstractResult result = BukkitPluginManager.get().unwatchPlugin(pluginName); + result.sendTo(BukkitUtils.wrap(sender), "unwatch", pluginName); + } + /** * Shows information about the specified plugin. * @param commandSender The sender of the command. diff --git a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitCommandSender.java b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitCommandSender.java index 9587d90..f4175f9 100644 --- a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitCommandSender.java +++ b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitCommandSender.java @@ -2,6 +2,7 @@ package net.frankheijden.serverutils.bukkit.entities; import net.frankheijden.serverutils.common.entities.ServerCommandSender; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; /** * A wrap for a Bukkit CommandSender. @@ -36,4 +37,13 @@ public class BukkitCommandSender implements ServerCommandSender { public boolean hasPermission(String permission) { return sender.hasPermission(permission); } + + /** + * Whether or not the given instance is a player. + * @return Boolean true or false. + */ + @Override + public boolean isPlayer() { + return sender instanceof Player; + } } diff --git a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitPlugin.java b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitPlugin.java index c6309a7..5e36bdc 100644 --- a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitPlugin.java +++ b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/entities/BukkitPlugin.java @@ -38,6 +38,7 @@ public class BukkitPlugin extends ServerUtilsPlugin { } @Override + @SuppressWarnings("unchecked") public BukkitTaskManager getTaskManager() { return taskManager; } diff --git a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitPluginManager.java b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitPluginManager.java index d2b9314..c5c0316 100644 --- a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitPluginManager.java +++ b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitPluginManager.java @@ -334,11 +334,21 @@ public class BukkitPluginManager extends AbstractPluginManager { return loader.getPluginDescription(file); } + @Override + public File getPluginFile(Plugin plugin) { + try { + return RJavaPlugin.getFile(plugin); + } catch (ReflectiveOperationException ex) { + throw new RuntimeException("Error retrieving current plugin file", ex); + } + } + /** * Attempts to retrieve the plugin file by plugin name. * @param pluginName The plugin name. * @return The file, or null if invalid or not found. */ + @Override public File getPluginFile(String pluginName) { for (File file : getPluginJars()) { PluginDescriptionFile descriptionFile; @@ -354,12 +364,8 @@ public class BukkitPluginManager extends AbstractPluginManager { } @Override - public File getPluginFile(Plugin plugin) { - try { - return RJavaPlugin.getFile(plugin); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException("Error retrieving current plugin file", ex); - } + public Plugin getPlugin(String pluginName) { + return Bukkit.getPluginManager().getPlugin(pluginName); } @Override diff --git a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitTaskManager.java b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitTaskManager.java index 3438ea8..82e043d 100644 --- a/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitTaskManager.java +++ b/Bukkit/src/main/java/net/frankheijden/serverutils/bukkit/managers/BukkitTaskManager.java @@ -3,16 +3,21 @@ package net.frankheijden.serverutils.bukkit.managers; import net.frankheijden.serverutils.bukkit.ServerUtils; import net.frankheijden.serverutils.common.managers.AbstractTaskManager; import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; -public class BukkitTaskManager extends AbstractTaskManager { +public class BukkitTaskManager extends AbstractTaskManager { + + public BukkitTaskManager() { + super(BukkitTask::cancel); + } @Override public void runTask(Runnable runnable) { - Bukkit.getScheduler().runTask(ServerUtils.getInstance(), runnable); + addTask(Bukkit.getScheduler().runTask(ServerUtils.getInstance(), runnable)); } @Override public void runTaskAsynchronously(Runnable runnable) { - Bukkit.getScheduler().runTaskAsynchronously(ServerUtils.getInstance(), runnable); + addTask(Bukkit.getScheduler().runTaskAsynchronously(ServerUtils.getInstance(), runnable)); } } diff --git a/Bukkit/src/main/resources/bukkit-messages.yml b/Bukkit/src/main/resources/bukkit-messages.yml index 31fe0ef..6e55175 100644 --- a/Bukkit/src/main/resources/bukkit-messages.yml +++ b/Bukkit/src/main/resources/bukkit-messages.yml @@ -11,6 +11,11 @@ serverutils: invalid_description: "&cAn error occurred while %action%ing &4%what%&c, plugin doesn't have a valid description!" invalid_plugin: "&cAn error occurred while %action%ing &4%what%&c, plugin is invalid!" unknown_dependency: "&cAn error occurred while %action%ing &4%what%&c, plugin has a dependeny which is not loaded: &4%arg%" + watcher: + start: "&3Started watching &b%what%&3!" + change: "&3Change detected for plugin &b%what%&3, reloading now..." + stopped: "&3Stopped watching &b%what%&3!" + not_watching: "&cWe aren't watching that plugin!" update: available: |- &8&m------------=&r&8[ &b&lServerUtils Update&r &8]&m=-------------- diff --git a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/ServerUtils.java b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/ServerUtils.java index bde1c84..0972d98 100644 --- a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/ServerUtils.java +++ b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/ServerUtils.java @@ -53,10 +53,18 @@ public class ServerUtils extends Plugin { reload(); getProxy().getPluginManager().registerListener(this, new BungeeListener()); + plugin.enable(); + loadClasses(); ServerUtilsApp.tryCheckForUpdates(); } + @Override + public void onDisable() { + super.onDisable(); + plugin.disable(); + } + /** * Loads some classes in memory so they're available during updating. */ diff --git a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/commands/CommandServerUtils.java b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/commands/CommandServerUtils.java index ffdb4d2..6fe08c8 100644 --- a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/commands/CommandServerUtils.java +++ b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/commands/CommandServerUtils.java @@ -20,6 +20,7 @@ import net.frankheijden.serverutils.bungee.managers.BungeePluginManager; import net.frankheijden.serverutils.bungee.reflection.RPluginManager; import net.frankheijden.serverutils.bungee.utils.BungeeUtils; import net.frankheijden.serverutils.common.config.Messenger; +import net.frankheijden.serverutils.common.entities.AbstractResult; import net.frankheijden.serverutils.common.entities.CloseableResult; import net.frankheijden.serverutils.common.entities.Result; import net.frankheijden.serverutils.common.entities.ServerCommandSender; @@ -150,6 +151,35 @@ public class CommandServerUtils extends BaseCommand { } } + /** + * Watches the given plugin and reloads it when a change is detected to the file. + * @param sender The sender of the command. + * @param pluginName The plugin name. + */ + @Subcommand("watchplugin") + @CommandCompletion("@plugins") + @CommandPermission("serverutils.watchplugin") + @Description("Watches the specified plugin for changes.") + public void onWatchPlugin(CommandSender sender, String pluginName) { + ServerCommandSender commandSender = BungeeUtils.wrap(sender); + AbstractResult result = BungeePluginManager.get().watchPlugin(commandSender, pluginName); + result.sendTo(commandSender, "watch", pluginName); + } + + /** + * Stops watching the given plugin. + * @param sender The sender of the command. + * @param pluginName The plugin name. + */ + @Subcommand("unwatchplugin") + @CommandCompletion("@plugins") + @CommandPermission("serverutils.unwatchplugin") + @Description("Stops watching the specified plugin for changes.") + public void onUnwatchPlugin(CommandSender sender, String pluginName) { + AbstractResult result = BungeePluginManager.get().unwatchPlugin(pluginName); + result.sendTo(BungeeUtils.wrap(sender), "unwatch", pluginName); + } + /** * Shows information about the specified plugin. * @param commandSender The sender of the command. diff --git a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeeCommandSender.java b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeeCommandSender.java index 6c09ef4..fbb1a20 100644 --- a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeeCommandSender.java +++ b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeeCommandSender.java @@ -2,6 +2,7 @@ package net.frankheijden.serverutils.bungee.entities; import net.frankheijden.serverutils.common.entities.ServerCommandSender; import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; public class BungeeCommandSender implements ServerCommandSender { @@ -20,4 +21,13 @@ public class BungeeCommandSender implements ServerCommandSender { public boolean hasPermission(String permission) { return sender.hasPermission(permission); } + + /** + * Whether or not the given instance is a player. + * @return Boolean true or false. + */ + @Override + public boolean isPlayer() { + return sender instanceof ProxiedPlayer; + } } diff --git a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeePlugin.java b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeePlugin.java index c4fcd21..97cff29 100644 --- a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeePlugin.java +++ b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/entities/BungeePlugin.java @@ -38,6 +38,7 @@ public class BungeePlugin extends ServerUtilsPlugin { } @Override + @SuppressWarnings("unchecked") public BungeeTaskManager getTaskManager() { return taskManager; } diff --git a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeePluginManager.java b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeePluginManager.java index 0684123..7722841 100644 --- a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeePluginManager.java +++ b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeePluginManager.java @@ -176,6 +176,7 @@ public class BungeePluginManager extends AbstractPluginManager { * @param pluginName The plugin name to search for. * @return The File if the plugin exists with that name. */ + @Override public File getPluginFile(String pluginName) { for (File file : getPluginJars()) { PluginDescription desc; @@ -195,6 +196,11 @@ public class BungeePluginManager extends AbstractPluginManager { return plugin.getFile(); } + @Override + public Plugin getPlugin(String pluginName) { + return proxy.getPluginManager().getPlugin(pluginName); + } + @Override public Set getCommands() { return proxy.getPluginManager().getCommands().stream() diff --git a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeeTaskManager.java b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeeTaskManager.java index b4ee301..0888c31 100644 --- a/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeeTaskManager.java +++ b/Bungee/src/main/java/net/frankheijden/serverutils/bungee/managers/BungeeTaskManager.java @@ -3,8 +3,13 @@ package net.frankheijden.serverutils.bungee.managers; import net.frankheijden.serverutils.bungee.ServerUtils; import net.frankheijden.serverutils.common.managers.AbstractTaskManager; import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.scheduler.ScheduledTask; -public class BungeeTaskManager extends AbstractTaskManager { +public class BungeeTaskManager extends AbstractTaskManager { + + public BungeeTaskManager() { + super(ScheduledTask::cancel); + } @Override public void runTask(Runnable runnable) { diff --git a/Bungee/src/main/resources/bungee-messages.yml b/Bungee/src/main/resources/bungee-messages.yml index fb9010e..551da0f 100644 --- a/Bungee/src/main/resources/bungee-messages.yml +++ b/Bungee/src/main/resources/bungee-messages.yml @@ -11,6 +11,11 @@ serverutils: invalid_description: "&cAn error occurred while %action%ing &4%what%&c, plugin doesn't have a valid description, please check the console!" invalid_plugin: "&cAn error occurred while %action%ing &4%what%&c, plugin is invalid!" unknown_dependency: "&cAn error occurred while %action%ing &4%what%&c, plugin has a dependeny which is not loaded: &4%arg%" + watcher: + start: "&3Started watching &b%what%&3!" + change: "&3Change detected for plugin &b%what%&3, reloading now..." + stopped: "&3Stopped watching &b%what%&3!" + not_watching: "&cWe aren't watching that plugin!" update: available: |- &8&m---------=&r&8[ &b&lServerUtils Bungee Update&r &8]&m=---------- diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/entities/AbstractResult.java b/Common/src/main/java/net/frankheijden/serverutils/common/entities/AbstractResult.java new file mode 100644 index 0000000..fce40a0 --- /dev/null +++ b/Common/src/main/java/net/frankheijden/serverutils/common/entities/AbstractResult.java @@ -0,0 +1,13 @@ +package net.frankheijden.serverutils.common.entities; + +public interface AbstractResult { + + /** + * Retrieves the associated message of the result + * and sends it to a CommandSender. + * @param sender The receiver. + * @param action The action which let to the result. + * @param what An associated variable. + */ + void sendTo(ServerCommandSender sender, String action, String what); +} diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/entities/AbstractTask.java b/Common/src/main/java/net/frankheijden/serverutils/common/entities/AbstractTask.java new file mode 100644 index 0000000..66105b0 --- /dev/null +++ b/Common/src/main/java/net/frankheijden/serverutils/common/entities/AbstractTask.java @@ -0,0 +1,6 @@ +package net.frankheijden.serverutils.common.entities; + +public abstract class AbstractTask implements Runnable { + + public abstract void cancel(); +} diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/entities/Result.java b/Common/src/main/java/net/frankheijden/serverutils/common/entities/Result.java index 85e7c29..293dd86 100644 --- a/Common/src/main/java/net/frankheijden/serverutils/common/entities/Result.java +++ b/Common/src/main/java/net/frankheijden/serverutils/common/entities/Result.java @@ -5,7 +5,7 @@ import net.frankheijden.serverutils.common.config.Messenger; /** * An enum containing possible results. */ -public enum Result { +public enum Result implements AbstractResult { NOT_EXISTS, NOT_ENABLED, ALREADY_LOADED, @@ -44,6 +44,7 @@ public enum Result { * @param action The action which let to the result. * @param what An associated variable. */ + @Override public void sendTo(ServerCommandSender sender, String action, String what) { Messenger.sendMessage(sender, "serverutils." + this.name().toLowerCase(), "%action%", action, diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerCommandSender.java b/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerCommandSender.java index 7ca9bc3..87a0270 100644 --- a/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerCommandSender.java +++ b/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerCommandSender.java @@ -17,4 +17,10 @@ public interface ServerCommandSender { * @return Whether or not they have the permission. */ boolean hasPermission(String permission); + + /** + * Whether or not the given instance is a player. + * @return Boolean true or false. + */ + boolean isPlayer(); } diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerUtilsPlugin.java b/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerUtilsPlugin.java index 731f456..bf11bd3 100644 --- a/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerUtilsPlugin.java +++ b/Common/src/main/java/net/frankheijden/serverutils/common/entities/ServerUtilsPlugin.java @@ -15,7 +15,7 @@ public abstract class ServerUtilsPlugin { public abstract AbstractPluginManager getPluginManager(); - public abstract AbstractTaskManager getTaskManager(); + public abstract AbstractTaskManager getTaskManager(); public abstract ResourceProvider getResourceProvider(); @@ -52,4 +52,12 @@ public abstract class ServerUtilsPlugin { } return file; } + + public void enable() { + + } + + public void disable() { + getTaskManager().cancelAllTasks(); + } } diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/entities/WatchResult.java b/Common/src/main/java/net/frankheijden/serverutils/common/entities/WatchResult.java new file mode 100644 index 0000000..ab9639c --- /dev/null +++ b/Common/src/main/java/net/frankheijden/serverutils/common/entities/WatchResult.java @@ -0,0 +1,24 @@ +package net.frankheijden.serverutils.common.entities; + +import net.frankheijden.serverutils.common.config.Messenger; + +public enum WatchResult implements AbstractResult { + + START, + CHANGE, + NOT_WATCHING, + STOPPED; + + /** + * Retrieves the associated message of the result + * and sends it to a CommandSender. + * @param sender The receiver. + * @param action The action which let to the result. + * @param what An associated variable. + */ + @Override + public void sendTo(ServerCommandSender sender, String action, String what) { + Messenger.sendMessage(sender, "serverutils.watcher." + this.name().toLowerCase(), + "%what%", what); + } +} diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractPluginManager.java b/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractPluginManager.java index 76d15e4..280a856 100644 --- a/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractPluginManager.java +++ b/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractPluginManager.java @@ -2,10 +2,15 @@ package net.frankheijden.serverutils.common.managers; import java.io.File; +import net.frankheijden.serverutils.common.ServerUtilsApp; +import net.frankheijden.serverutils.common.entities.AbstractResult; import net.frankheijden.serverutils.common.entities.CloseableResult; import net.frankheijden.serverutils.common.entities.LoadResult; import net.frankheijden.serverutils.common.entities.Result; +import net.frankheijden.serverutils.common.entities.ServerCommandSender; +import net.frankheijden.serverutils.common.entities.WatchResult; import net.frankheijden.serverutils.common.providers.PluginProvider; +import net.frankheijden.serverutils.common.tasks.PluginWatcherTask; public abstract class AbstractPluginManager extends PluginProvider { @@ -22,4 +27,27 @@ public abstract class AbstractPluginManager extends PluginProvider { public abstract CloseableResult unloadPlugin(String pluginName); public abstract CloseableResult unloadPlugin(T plugin); + + /** + * Starts watching the specified plugin for changes. + * Reloads the plugin if a change is detected. + * @param pluginName The plugin to watch. + * @return The result of the action. + */ + public AbstractResult watchPlugin(ServerCommandSender sender, String pluginName) { + if (getPlugin(pluginName) == null) return Result.NOT_EXISTS; + ServerUtilsApp.getPlugin().getTaskManager() + .runTaskAsynchronously(pluginName, new PluginWatcherTask(sender, pluginName)); + return WatchResult.START; + } + + /** + * Stops watching the plugin for changes. + * @param pluginName The plugin to stop watching. + * @return The result of the action. + */ + public AbstractResult unwatchPlugin(String pluginName) { + if (ServerUtilsApp.getPlugin().getTaskManager().cancelTask(pluginName)) return WatchResult.STOPPED; + return WatchResult.NOT_WATCHING; + } } diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractTaskManager.java b/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractTaskManager.java index 533d0de..2245f5e 100644 --- a/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractTaskManager.java +++ b/Common/src/main/java/net/frankheijden/serverutils/common/managers/AbstractTaskManager.java @@ -1,8 +1,71 @@ package net.frankheijden.serverutils.common.managers; -public abstract class AbstractTaskManager { +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import net.frankheijden.serverutils.common.entities.AbstractTask; + +public abstract class AbstractTaskManager { + + private final List serverTasks; + private final Consumer taskCloser; + private final Map tasks; + + /** + * Constructs a new TaskManager with a consumer which closes a task. + * @param taskCloser The consumer which will close tasks. + */ + public AbstractTaskManager(Consumer taskCloser) { + this.taskCloser = taskCloser; + this.serverTasks = new ArrayList<>(); + this.tasks = new HashMap<>(); + } public abstract void runTask(Runnable runnable); + public void runTask(String key, AbstractTask task) { + tasks.put(key, task); + runTask(task); + } + public abstract void runTaskAsynchronously(Runnable runnable); + + public void runTaskAsynchronously(String key, AbstractTask task) { + tasks.put(key, task); + runTaskAsynchronously(task); + } + + public void addTask(T task) { + serverTasks.add(task); + } + + /** + * Cancels a single task by key. + * @param key The key of the task. + * @return Whether or not the task existed. + */ + public boolean cancelTask(String key) { + AbstractTask task = tasks.remove(key); + if (task == null) return false; + task.cancel(); + return true; + } + + /** + * Cancels all tasks. + */ + public void cancelAllTasks() { + for (AbstractTask task : tasks.values()) { + task.cancel(); + } + tasks.clear(); + + for (T task : serverTasks) { + taskCloser.accept(task); + } + serverTasks.clear(); + } } diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/providers/PluginProvider.java b/Common/src/main/java/net/frankheijden/serverutils/common/providers/PluginProvider.java index 06177de..326264b 100644 --- a/Common/src/main/java/net/frankheijden/serverutils/common/providers/PluginProvider.java +++ b/Common/src/main/java/net/frankheijden/serverutils/common/providers/PluginProvider.java @@ -17,6 +17,10 @@ public abstract class PluginProvider { public abstract File getPluginFile(T plugin); + public abstract File getPluginFile(String pluginName); + + public abstract T getPlugin(String pluginName); + public abstract Set getCommands(); /** diff --git a/Common/src/main/java/net/frankheijden/serverutils/common/tasks/PluginWatcherTask.java b/Common/src/main/java/net/frankheijden/serverutils/common/tasks/PluginWatcherTask.java new file mode 100644 index 0000000..2e7c345 --- /dev/null +++ b/Common/src/main/java/net/frankheijden/serverutils/common/tasks/PluginWatcherTask.java @@ -0,0 +1,97 @@ +package net.frankheijden.serverutils.common.tasks; + +import com.sun.nio.file.SensitivityWatchEventModifier; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import java.util.concurrent.atomic.AtomicBoolean; + +import net.frankheijden.serverutils.common.ServerUtilsApp; +import net.frankheijden.serverutils.common.entities.AbstractTask; +import net.frankheijden.serverutils.common.entities.ServerCommandSender; +import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin; +import net.frankheijden.serverutils.common.entities.WatchResult; +import net.frankheijden.serverutils.common.managers.AbstractPluginManager; +import net.frankheijden.serverutils.common.managers.AbstractTaskManager; +import net.frankheijden.serverutils.common.providers.ChatProvider; + +public class PluginWatcherTask extends AbstractTask { + + private static final WatchEvent.Kind[] EVENTS = new WatchEvent.Kind[] { + StandardWatchEventKinds.ENTRY_CREATE, + StandardWatchEventKinds.ENTRY_MODIFY, + StandardWatchEventKinds.ENTRY_DELETE + }; + + private final ServerUtilsPlugin plugin = ServerUtilsApp.getPlugin(); + + @SuppressWarnings("rawtypes") + private final AbstractPluginManager pluginManager = plugin.getPluginManager(); + private final ChatProvider chatProvider = plugin.getChatProvider(); + @SuppressWarnings("rawtypes") + private final AbstractTaskManager taskManager = plugin.getTaskManager(); + + private final ServerCommandSender sender; + private final String pluginName; + private File file; + private final AtomicBoolean run; + + /** + * Constructs a new PluginWatcherTask for the specified plugin. + * @param pluginName The name of the plugin. + */ + public PluginWatcherTask(ServerCommandSender sender, String pluginName) { + this.sender = sender; + this.pluginName = pluginName; + this.file = pluginManager.getPluginFile(pluginName); + this.run = new AtomicBoolean(true); + } + + @Override + public void run() { + try (WatchService watchService = FileSystems.getDefault().newWatchService()) { + File folder = pluginManager.getPluginsFolder(); + folder.toPath().register(watchService, EVENTS, SensitivityWatchEventModifier.HIGH); + + while (run.get()) { + WatchKey key = watchService.take(); + for (WatchEvent event : key.pollEvents()) { + if (file.getName().equals(event.context().toString())) { + send(WatchResult.CHANGE); + + taskManager.runTask(() -> { + pluginManager.reloadPlugin(pluginName); + file = pluginManager.getPluginFile(pluginName); + }); + } + } + + if (file == null || !key.reset()) { + send(WatchResult.STOPPED); + break; + } + } + } catch (IOException ex) { + ex.printStackTrace(); + } catch (InterruptedException ignored) { + // + } + } + + private void send(WatchResult result) { + result.sendTo(sender, null, pluginName); + if (sender.isPlayer()) { + result.sendTo(chatProvider.getConsoleSender(), null, pluginName); + } + } + + @Override + public void cancel() { + run.set(false); + } +}