Add /su restart
This commit is contained in:
parent
5bfba17e35
commit
ae0005a82a
7 changed files with 118 additions and 27 deletions
|
|
@ -7,6 +7,7 @@ import cloud.commandframework.context.CommandContext;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
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.ServerUtilsAudience;
|
||||||
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
|
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
|
||||||
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
|
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.ListComponentBuilder;
|
||||||
import net.frankheijden.serverutils.common.utils.KeyValueComponentBuilder;
|
import net.frankheijden.serverutils.common.utils.KeyValueComponentBuilder;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
@ -58,6 +60,8 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
|
||||||
.handler(this::handleHelpCommand));
|
.handler(this::handleHelpCommand));
|
||||||
manager.command(buildSubcommand(builder, "reload")
|
manager.command(buildSubcommand(builder, "reload")
|
||||||
.handler(this::handleReload));
|
.handler(this::handleReload));
|
||||||
|
manager.command(buildSubcommand(builder, "restart")
|
||||||
|
.handler(this::handleRestart));
|
||||||
manager.command(buildSubcommand(builder, "loadplugin")
|
manager.command(buildSubcommand(builder, "loadplugin")
|
||||||
.argument(getArgument("jarFiles"))
|
.argument(getArgument("jarFiles"))
|
||||||
.handler(this::handleLoadPlugin));
|
.handler(this::handleLoadPlugin));
|
||||||
|
|
@ -169,6 +173,16 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
|
||||||
plugin.getMessagesResource().get(MessageKey.RELOAD).sendTo(sender);
|
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) {
|
private void handleLoadPlugin(CommandContext<C> context) {
|
||||||
C sender = context.getSender();
|
C sender = context.getSender();
|
||||||
List<File> jarFiles = Arrays.asList(context.get("jarFiles"));
|
List<File> jarFiles = Arrays.asList(context.get("jarFiles"));
|
||||||
|
|
@ -214,8 +228,12 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (checkServerUtils(context, sender, plugins)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PluginResults<P> reloadResults = plugin.getPluginManager().reloadPlugins(plugins);
|
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) {
|
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;
|
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) {
|
private void handleWatchPlugin(CommandContext<C> context) {
|
||||||
C sender = context.getSender();
|
C sender = context.getSender();
|
||||||
List<P> plugins = Arrays.asList(context.get("plugins"));
|
List<P> plugins = Arrays.asList(context.get("plugins"));
|
||||||
|
|
@ -268,6 +303,10 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (checkServerUtils(context, sender, plugins)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PluginWatchResults watchResults = plugin.getWatchManager().watchPlugins(sender, plugins);
|
PluginWatchResults watchResults = plugin.getWatchManager().watchPlugins(sender, plugins);
|
||||||
watchResults.sendTo(sender);
|
watchResults.sendTo(sender);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,23 @@ public class CommandsResource extends ServerUtilsResource {
|
||||||
return Collections.emptySet();
|
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
|
@Override
|
||||||
public void migrate(int currentConfigVersion) {
|
public void migrate(int currentConfigVersion) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ public enum MessageKey implements PlaceholderConfigKey {
|
||||||
RELOAD("reload", false),
|
RELOAD("reload", false),
|
||||||
LOADPLUGIN("loadplugin"),
|
LOADPLUGIN("loadplugin"),
|
||||||
UNLOADPLUGIN("unloadplugin"),
|
UNLOADPLUGIN("unloadplugin"),
|
||||||
RELOADPLUGIN("reloadplugin"),
|
SERVERUTILS_UPDATER("serverutils-updater", false),
|
||||||
|
RELOADPLUGIN_SUCCESS("reloadplugin.success"),
|
||||||
|
RELOADPLUGIN_SERVERUTILS("reloadplugin.serverutils"),
|
||||||
GENERIC_PREFIX("generic.prefix", false),
|
GENERIC_PREFIX("generic.prefix", false),
|
||||||
GENERIC_ERROR("generic.error", false),
|
GENERIC_ERROR("generic.error", false),
|
||||||
GENERIC_NOT_EXISTS("generic.not-exists"),
|
GENERIC_NOT_EXISTS("generic.not-exists"),
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
|
||||||
fileNameToWatchEntryMap.clear();
|
fileNameToWatchEntryMap.clear();
|
||||||
|
|
||||||
PluginResults<P> reloadResults = pluginManager.reloadPlugins(plugins);
|
PluginResults<P> reloadResults = pluginManager.reloadPlugins(plugins);
|
||||||
reloadResults.sendTo(sender, MessageKey.RELOADPLUGIN);
|
reloadResults.sendTo(sender, MessageKey.RELOADPLUGIN_SUCCESS);
|
||||||
|
|
||||||
for (PluginResult<P> reloadResult : reloadResults) {
|
for (PluginResult<P> reloadResult : reloadResults) {
|
||||||
if (!reloadResult.isSuccess()) continue;
|
if (!reloadResult.isSuccess()) continue;
|
||||||
|
|
|
||||||
|
|
@ -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 UPDATE_CHECK_START = "Checking for updates...";
|
||||||
private static final String RATE_LIMIT = "Received ratelimit from GitHub.";
|
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 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 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 UNAVAILABLE = GENERAL_ERROR + ": ({0}) {1} (no update available)";
|
||||||
private static final String UPDATE_AVAILABLE = "ServerUtils {0} is available!";
|
private static final String UPDATE_AVAILABLE = "ServerUtils {0} is available!";
|
||||||
private static final String RELEASE_INFO = "Release info: {0}";
|
private static final String RELEASE_INFO = "Release info: {0}";
|
||||||
private static final String DOWNLOAD_START = "Started downloading from \"{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 {0} version v{1}.";
|
||||||
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 UP_TO_DATE = "We are up-to-date!";
|
private static final String UP_TO_DATE = "We are up-to-date!";
|
||||||
|
|
||||||
private UpdateCheckerTask(U plugin, ServerUtilsAudience<?> sender, boolean download, boolean install) {
|
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
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
UpdateManager updateManager = plugin.getUpdateManager();
|
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());
|
File pluginTarget = new File(plugin.getPluginManager().getPluginsFolder(), pluginAsset.getName());
|
||||||
download(githubVersion, pluginAsset.getDownloadUrl(), pluginTarget);
|
download(pluginAsset.getDownloadUrl(), pluginTarget);
|
||||||
updateManager.setDownloadedVersion(githubVersion);
|
updateManager.setDownloadedVersion(githubVersion);
|
||||||
if (!install) {
|
if (!install) {
|
||||||
deletePlugin();
|
deletePlugin();
|
||||||
if (sender.isPlayer()) {
|
if (sender.isPlayer()) {
|
||||||
broadcastDownloadStatus(githubVersion, false);
|
broadcastDownloadStatus(githubVersion, false);
|
||||||
} else {
|
} else {
|
||||||
plugin.getLogger().log(Level.INFO, DOWNLOADED, githubVersion);
|
plugin.getLogger().log(Level.INFO, DOWNLOADED, new Object[]{ "ServerUtils", githubVersion });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downloadUpdaterAndReload(pluginTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the updater and restarts the plugin.
|
||||||
|
*/
|
||||||
|
public void downloadUpdaterAndReload(File pluginTarget) {
|
||||||
GitHubResponse updaterResponse = getResponse(GITHUB_UPDATER_LINK);
|
GitHubResponse updaterResponse = getResponse(GITHUB_UPDATER_LINK);
|
||||||
if (updaterResponse == null) return;
|
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());
|
plugin.getLogger().log(Level.INFO, DOWNLOAD_START, updaterAsset.getDownloadUrl());
|
||||||
File updaterTarget = new File(plugin.getPluginManager().getPluginsFolder(), updaterAsset.getName());
|
File updaterTarget = new File(plugin.getPluginManager().getPluginsFolder(), updaterAsset.getName());
|
||||||
download(githubVersion, updaterAsset.getDownloadUrl(), updaterTarget);
|
download(updaterAsset.getDownloadUrl(), updaterTarget);
|
||||||
plugin.getLogger().log(Level.INFO, DOWNLOADED_RESTART, githubVersion);
|
plugin.getLogger().log(Level.INFO, DOWNLOADED, new Object[]{ "ServerUtilsUpdater", getVersion(updaterJson) });
|
||||||
|
|
||||||
deletePlugin();
|
if (!pluginTarget.equals(getPluginFile())) {
|
||||||
|
deletePlugin();
|
||||||
|
}
|
||||||
tryReloadPlugin(pluginTarget, updaterTarget);
|
tryReloadPlugin(pluginTarget, updaterTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,12 +238,7 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
|
||||||
return jsonObject.getAsJsonPrimitive("tag_name").getAsString().replace("v", "");
|
return jsonObject.getAsJsonPrimitive("tag_name").getAsString().replace("v", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void download(String githubVersion, String downloadLink, File target) {
|
private void download(String downloadLink, File target) {
|
||||||
if (downloadLink == null) {
|
|
||||||
broadcastDownloadStatus(githubVersion, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GitHubResponse response = GitHubUtils.stream(downloadLink);
|
GitHubResponse response = GitHubUtils.stream(downloadLink);
|
||||||
if (response.getRateLimit().isRateLimited()) {
|
if (response.getRateLimit().isRateLimited()) {
|
||||||
|
|
@ -238,32 +248,35 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
|
||||||
|
|
||||||
GitHubUtils.download(response, target);
|
GitHubUtils.download(response, target);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
broadcastDownloadStatus(githubVersion, true);
|
ex.printStackTrace();
|
||||||
throw new RuntimeException(DOWNLOAD_ERROR, ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private File getPluginFile() {
|
||||||
|
return plugin.getPluginManager().getPluginFile(plugin.getPlugin());
|
||||||
|
}
|
||||||
|
|
||||||
private void deletePlugin() {
|
private void deletePlugin() {
|
||||||
plugin.getPluginManager().getPluginFile(plugin.getPlugin()).delete();
|
getPluginFile().delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryReloadPlugin(File pluginFile, File updaterFile) {
|
private void tryReloadPlugin(File pluginFile, File updaterFile) {
|
||||||
plugin.getTaskManager().runTask(() -> {
|
plugin.getTaskManager().runTask(() -> {
|
||||||
PluginResult<P> loadResult = plugin.getPluginManager().loadPlugin(updaterFile);
|
PluginResult<P> loadResult = plugin.getPluginManager().loadPlugin(updaterFile);
|
||||||
if (!loadResult.isSuccess()) {
|
if (!loadResult.isSuccess()) {
|
||||||
plugin.getLogger().log(Level.INFO, UPDATER_LOAD_ERROR, loadResult.getResult().name());
|
loadResult.sendTo(sender, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginResult<P> enableResult = plugin.getPluginManager().enablePlugin(loadResult.getPlugin());
|
PluginResult<P> enableResult = plugin.getPluginManager().enablePlugin(loadResult.getPlugin());
|
||||||
if (!enableResult.isSuccess() && enableResult.getResult() != Result.ALREADY_ENABLED) {
|
if (!enableResult.isSuccess() && enableResult.getResult() != Result.ALREADY_ENABLED) {
|
||||||
plugin.getLogger().log(Level.INFO, UPDATER_ENABLE_ERROR, enableResult.getResult().name());
|
loadResult.sendTo(sender, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Updater updater = (Updater) plugin.getPluginManager().getInstance(enableResult.getPlugin());
|
Updater updater = (Updater) plugin.getPluginManager().getInstance(enableResult.getPlugin());
|
||||||
|
sender.sendMessage(plugin.getMessagesResource().get(MessageKey.SERVERUTILS_UPDATER).toComponent());
|
||||||
updater.update(pluginFile);
|
updater.update(pluginFile);
|
||||||
updaterFile.delete();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,22 @@
|
||||||
"description": "Reloads the ServerUtils plugin.",
|
"description": "Reloads the ServerUtils plugin.",
|
||||||
"display-in-help": true
|
"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": {
|
"loadplugin": {
|
||||||
"main": "loadplugin",
|
"main": "loadplugin",
|
||||||
"aliases": ["lp"],
|
"aliases": ["lp"],
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,13 @@
|
||||||
"file-deleted": "<red>File of plugin <dark_red><plugin></dark_red> has been deleted!"
|
"file-deleted": "<red>File of plugin <dark_red><plugin></dark_red> has been deleted!"
|
||||||
},
|
},
|
||||||
"reload": "<dark_aqua>Successfully reloaded <aqua>ServerUtils configurations</aqua>!",
|
"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>!",
|
"loadplugin": "<dark_aqua>Successfully loaded <aqua><plugin></aqua>!",
|
||||||
"unloadplugin": "<dark_aqua>Successfully unloaded <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": {
|
"depending-plugins": {
|
||||||
"prefix": "<red>Plugin <dark_red><plugin></dark_red> has depending plugins: ",
|
"prefix": "<red>Plugin <dark_red><plugin></dark_red> has depending plugins: ",
|
||||||
"format": "<dark_red><plugin>",
|
"format": "<dark_red><plugin>",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue