Add /su restart

This commit is contained in:
Frank van der Heijden 2021-08-04 00:42:38 +02:00
parent 5bfba17e35
commit ae0005a82a
No known key found for this signature in database
GPG key ID: B808721C2DD5B5B8
7 changed files with 118 additions and 27 deletions

View file

@ -7,6 +7,7 @@ import cloud.commandframework.context.CommandContext;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
@ -26,6 +27,7 @@ import net.frankheijden.serverutils.common.entities.results.Result;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
import net.frankheijden.serverutils.common.tasks.UpdateCheckerTask;
import net.frankheijden.serverutils.common.utils.ListComponentBuilder;
import net.frankheijden.serverutils.common.utils.KeyValueComponentBuilder;
import net.kyori.adventure.text.Component;
@ -58,6 +60,8 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
.handler(this::handleHelpCommand));
manager.command(buildSubcommand(builder, "reload")
.handler(this::handleReload));
manager.command(buildSubcommand(builder, "restart")
.handler(this::handleRestart));
manager.command(buildSubcommand(builder, "loadplugin")
.argument(getArgument("jarFiles"))
.handler(this::handleLoadPlugin));
@ -169,6 +173,16 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
plugin.getMessagesResource().get(MessageKey.RELOAD).sendTo(sender);
}
private void handleRestart(CommandContext<C> context) {
C sender = context.getSender();
if (checkDependingPlugins(context, sender, Collections.singletonList(plugin.getPlugin()), "restart")) {
return;
}
UpdateCheckerTask.restart(sender);
}
private void handleLoadPlugin(CommandContext<C> context) {
C sender = context.getSender();
List<File> jarFiles = Arrays.asList(context.get("jarFiles"));
@ -214,8 +228,12 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
return;
}
if (checkServerUtils(context, sender, plugins)) {
return;
}
PluginResults<P> reloadResults = plugin.getPluginManager().reloadPlugins(plugins);
reloadResults.sendTo(sender, MessageKey.RELOADPLUGIN);
reloadResults.sendTo(sender, MessageKey.RELOADPLUGIN_SUCCESS);
}
protected boolean checkDependingPlugins(CommandContext<C> context, C sender, List<P> plugins, String subcommand) {
@ -260,6 +278,23 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
return hasDependingPlugins;
}
protected boolean checkServerUtils(CommandContext<C> context, C sender, List<P> plugins) {
for (P loadedPlugin : plugins) {
if (plugin.getPlugin() == loadedPlugin) {
String restartCommand = plugin.getCommandsResource().getAllAliases(getRawPath("restart")).stream()
.min(Comparator.comparingInt(String::length))
.orElse("restart");
Component component = plugin.getMessagesResource().get(MessageKey.RELOADPLUGIN_SERVERUTILS).toComponent(
Template.of("command", context.getRawInput().peekFirst() + " " + restartCommand)
);
sender.sendMessage(component);
return true;
}
}
return false;
}
private void handleWatchPlugin(CommandContext<C> context) {
C sender = context.getSender();
List<P> plugins = Arrays.asList(context.get("plugins"));
@ -268,6 +303,10 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
return;
}
if (checkServerUtils(context, sender, plugins)) {
return;
}
PluginWatchResults watchResults = plugin.getWatchManager().watchPlugins(sender, plugins);
watchResults.sendTo(sender);
}

View file

@ -36,6 +36,23 @@ public class CommandsResource extends ServerUtilsResource {
return Collections.emptySet();
}
/**
* Retrieves all aliases for the given path.
*/
public Set<String> getAllAliases(String path) {
Object object = getConfig().get(path);
if (object instanceof ServerUtilsConfig) {
ServerUtilsConfig config = (ServerUtilsConfig) object;
Set<String> aliases = new HashSet<>();
aliases.add(config.getString("main"));
aliases.addAll(config.getStringList("aliases"));
return aliases;
}
return Collections.emptySet();
}
@Override
public void migrate(int currentConfigVersion) {

View file

@ -7,7 +7,9 @@ public enum MessageKey implements PlaceholderConfigKey {
RELOAD("reload", false),
LOADPLUGIN("loadplugin"),
UNLOADPLUGIN("unloadplugin"),
RELOADPLUGIN("reloadplugin"),
SERVERUTILS_UPDATER("serverutils-updater", false),
RELOADPLUGIN_SUCCESS("reloadplugin.success"),
RELOADPLUGIN_SERVERUTILS("reloadplugin.serverutils"),
GENERIC_PREFIX("generic.prefix", false),
GENERIC_ERROR("generic.error", false),
GENERIC_NOT_EXISTS("generic.not-exists"),

View file

@ -167,7 +167,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
fileNameToWatchEntryMap.clear();
PluginResults<P> reloadResults = pluginManager.reloadPlugins(plugins);
reloadResults.sendTo(sender, MessageKey.RELOADPLUGIN);
reloadResults.sendTo(sender, MessageKey.RELOADPLUGIN_SUCCESS);
for (PluginResult<P> reloadResult : reloadResults) {
if (!reloadResult.isSuccess()) continue;

View file

@ -39,18 +39,14 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
private static final String UPDATE_CHECK_START = "Checking for updates...";
private static final String RATE_LIMIT = "Received ratelimit from GitHub.";
private static final String GENERAL_ERROR = "Error fetching new version of ServerUtils";
private static final String GENERAL_ERROR = "Error fetching GitHub";
private static final String TRY_LATER = GENERAL_ERROR + ", please try again later!";
private static final String CONNECTION_ERROR = GENERAL_ERROR + ": ({0}) {1} (maybe check your connection?)";
private static final String UNAVAILABLE = GENERAL_ERROR + ": ({0}) {1} (no update available)";
private static final String UPDATE_AVAILABLE = "ServerUtils {0} is available!";
private static final String RELEASE_INFO = "Release info: {0}";
private static final String DOWNLOAD_START = "Started downloading from \"{0}\"...";
private static final String DOWNLOAD_ERROR = "Error downloading a new version of ServerUtils";
private static final String DOWNLOADED = "Downloaded ServerUtils version v{0}.";
private static final String DOWNLOADED_RESTART = DOWNLOADED + " Restarting plugin now...";
private static final String UPDATER_LOAD_ERROR = "Failed to load ServerUtilsUpdater: {0}";
private static final String UPDATER_ENABLE_ERROR = "Failed to enable ServerUtilsUpdater: {0}";
private static final String DOWNLOADED = "Downloaded {0} version v{1}.";
private static final String UP_TO_DATE = "We are up-to-date!";
private UpdateCheckerTask(U plugin, ServerUtilsAudience<?> sender, boolean download, boolean install) {
@ -93,6 +89,16 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
));
}
/**
* Restarts the plugin.
*/
public static <P> void restart(ServerUtilsAudience<?> sender) {
ServerUtilsApp.getPlugin().getTaskManager().runTaskAsynchronously(() -> {
UpdateCheckerTask<?, P> task = new UpdateCheckerTask<>(ServerUtilsApp.getPlugin(), sender, true, true);
task.downloadUpdaterAndReload(task.plugin.getPluginManager().getPluginFile(task.plugin.getPlugin()));
});
}
@Override
public void run() {
UpdateManager updateManager = plugin.getUpdateManager();
@ -146,18 +152,25 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
}
File pluginTarget = new File(plugin.getPluginManager().getPluginsFolder(), pluginAsset.getName());
download(githubVersion, pluginAsset.getDownloadUrl(), pluginTarget);
download(pluginAsset.getDownloadUrl(), pluginTarget);
updateManager.setDownloadedVersion(githubVersion);
if (!install) {
deletePlugin();
if (sender.isPlayer()) {
broadcastDownloadStatus(githubVersion, false);
} else {
plugin.getLogger().log(Level.INFO, DOWNLOADED, githubVersion);
plugin.getLogger().log(Level.INFO, DOWNLOADED, new Object[]{ "ServerUtils", githubVersion });
}
return;
}
downloadUpdaterAndReload(pluginTarget);
}
/**
* Downloads the updater and restarts the plugin.
*/
public void downloadUpdaterAndReload(File pluginTarget) {
GitHubResponse updaterResponse = getResponse(GITHUB_UPDATER_LINK);
if (updaterResponse == null) return;
@ -169,10 +182,12 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
plugin.getLogger().log(Level.INFO, DOWNLOAD_START, updaterAsset.getDownloadUrl());
File updaterTarget = new File(plugin.getPluginManager().getPluginsFolder(), updaterAsset.getName());
download(githubVersion, updaterAsset.getDownloadUrl(), updaterTarget);
plugin.getLogger().log(Level.INFO, DOWNLOADED_RESTART, githubVersion);
download(updaterAsset.getDownloadUrl(), updaterTarget);
plugin.getLogger().log(Level.INFO, DOWNLOADED, new Object[]{ "ServerUtilsUpdater", getVersion(updaterJson) });
deletePlugin();
if (!pluginTarget.equals(getPluginFile())) {
deletePlugin();
}
tryReloadPlugin(pluginTarget, updaterTarget);
}
@ -223,12 +238,7 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
return jsonObject.getAsJsonPrimitive("tag_name").getAsString().replace("v", "");
}
private void download(String githubVersion, String downloadLink, File target) {
if (downloadLink == null) {
broadcastDownloadStatus(githubVersion, true);
return;
}
private void download(String downloadLink, File target) {
try {
GitHubResponse response = GitHubUtils.stream(downloadLink);
if (response.getRateLimit().isRateLimited()) {
@ -238,32 +248,35 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
GitHubUtils.download(response, target);
} catch (IOException ex) {
broadcastDownloadStatus(githubVersion, true);
throw new RuntimeException(DOWNLOAD_ERROR, ex);
ex.printStackTrace();
}
}
private File getPluginFile() {
return plugin.getPluginManager().getPluginFile(plugin.getPlugin());
}
private void deletePlugin() {
plugin.getPluginManager().getPluginFile(plugin.getPlugin()).delete();
getPluginFile().delete();
}
private void tryReloadPlugin(File pluginFile, File updaterFile) {
plugin.getTaskManager().runTask(() -> {
PluginResult<P> loadResult = plugin.getPluginManager().loadPlugin(updaterFile);
if (!loadResult.isSuccess()) {
plugin.getLogger().log(Level.INFO, UPDATER_LOAD_ERROR, loadResult.getResult().name());
loadResult.sendTo(sender, null);
return;
}
PluginResult<P> enableResult = plugin.getPluginManager().enablePlugin(loadResult.getPlugin());
if (!enableResult.isSuccess() && enableResult.getResult() != Result.ALREADY_ENABLED) {
plugin.getLogger().log(Level.INFO, UPDATER_ENABLE_ERROR, enableResult.getResult().name());
loadResult.sendTo(sender, null);
return;
}
Updater updater = (Updater) plugin.getPluginManager().getInstance(enableResult.getPlugin());
sender.sendMessage(plugin.getMessagesResource().get(MessageKey.SERVERUTILS_UPDATER).toComponent());
updater.update(pluginFile);
updaterFile.delete();
});
}

View file

@ -37,6 +37,22 @@
"description": "Reloads the ServerUtils plugin.",
"display-in-help": true
},
"restart": {
"main": "restart",
"aliases": [],
"permission": "serverutils.restart",
"description": "Restart the ServerUtils plugin.",
"display-in-help": true,
"flags": {
"force": {
"main": "force",
"aliases": ["f"],
"permission": "serverutils.restart",
"description": "Force restart of the ServerUtils plugin.",
"display-in-help": false
}
}
},
"loadplugin": {
"main": "loadplugin",
"aliases": ["lp"],

View file

@ -15,9 +15,13 @@
"file-deleted": "<red>File of plugin <dark_red><plugin></dark_red> has been deleted!"
},
"reload": "<dark_aqua>Successfully reloaded <aqua>ServerUtils configurations</aqua>!",
"serverutils-updater": "<dark_aqua>Loaded and enabled ServerUtilsUpdater. Completion can be monitored from the console, attempting restart now...",
"loadplugin": "<dark_aqua>Successfully loaded <aqua><plugin></aqua>!",
"unloadplugin": "<dark_aqua>Successfully unloaded <aqua><plugin></aqua>!",
"reloadplugin": "<dark_aqua>Successfully reloaded <aqua><plugin></aqua>!",
"reloadplugin": {
"success": "<dark_aqua>Successfully reloaded <aqua><plugin></aqua>!",
"serverutils": "<red>Sorry, but you can't reload ServerUtils this way. Please restart using <dark_red>/<command></dark_red>."
},
"depending-plugins": {
"prefix": "<red>Plugin <dark_red><plugin></dark_red> has depending plugins: ",
"format": "<dark_red><plugin>",