Add initial cloud commands + refactors to common

This commit is contained in:
Frank van der Heijden 2021-07-24 02:02:55 +02:00
parent f21306021d
commit 6545d7ffac
No known key found for this signature in database
GPG key ID: B808721C2DD5B5B8
89 changed files with 1959 additions and 1893 deletions

View file

@ -4,10 +4,10 @@ version = rootProject.version
archivesBaseName = rootProject.name + '-Bukkit'
dependencies {
implementation 'co.aikar:acf-paper:0.5.0-SNAPSHOT'
implementation 'com.github.FrankHeijden.cloud:cloud-paper:fea4605277'
implementation 'org.bstats:bstats-bukkit:2.2.1'
implementation project(":Common")
compileOnly 'com.destroystokyo.paper:paper-api:1.16.4-R0.1-SNAPSHOT'
compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
}
processResources {
@ -19,6 +19,4 @@ processResources {
shadowJar {
relocate 'org.bstats', dependencyDir + '.bstats'
relocate 'co.aikar.commands', dependencyDir + '.acf'
relocate 'co.aikar.locales', dependencyDir + '.locales'
}

View file

@ -1,40 +1,25 @@
package net.frankheijden.serverutils.bukkit;
import co.aikar.commands.BukkitCommandCompletionContext;
import co.aikar.commands.CommandCompletions;
import co.aikar.commands.PaperCommandManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.frankheijden.serverutils.bukkit.commands.CommandPlugins;
import net.frankheijden.serverutils.bukkit.commands.CommandServerUtils;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.bukkit.listeners.BukkitListener;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.reflection.RCommandMap;
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.Config;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.utils.StringUtils;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.defaults.PluginsCommand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
public class ServerUtils extends JavaPlugin implements CommandExecutor {
public class ServerUtils extends JavaPlugin {
private static ServerUtils instance;
private static final String CONFIG_RESOURCE = "bukkit-config.yml";
private static final String MESSAGES_RESOURCE = "bukkit-messages.yml";
private BukkitPlugin plugin;
private PaperCommandManager commandManager;
private CommandPlugins commandPlugins;
@Override
public void onEnable() {
@ -45,23 +30,7 @@ public class ServerUtils extends JavaPlugin implements CommandExecutor {
ServerUtilsApp.init(this, plugin);
new Metrics(this, ServerUtilsApp.BSTATS_METRICS_ID);
this.commandManager = new PaperCommandManager(this);
commandManager.registerCommand(new CommandServerUtils(), true);
this.commandPlugins = null;
BukkitPluginManager manager = plugin.getPluginManager();
CommandCompletions<BukkitCommandCompletionContext> completions = commandManager.getCommandCompletions();
completions.registerAsyncCompletion("plugins", context -> manager.getPluginNames());
completions.registerAsyncCompletion("pluginJars", context -> manager.getPluginFileNames());
completions.registerAsyncCompletion("supportedConfigs", context -> CommandServerUtils.getSupportedConfigs());
completions.registerAsyncCompletion("commands", context -> manager.getCommands());
reload();
Bukkit.getPluginManager().registerEvents(new BukkitListener(), this);
plugin.enable();
ServerUtilsApp.tryCheckForUpdates();
}
public static ServerUtils getInstance() {
@ -75,54 +44,20 @@ public class ServerUtils extends JavaPlugin implements CommandExecutor {
@Override
public void onDisable() {
super.onDisable();
commandManager.unregisterCommands();
restoreBukkitPluginCommand();
plugin.disable();
}
private void removeCommands(String... commands) {
Map<String, Command> map;
try {
map = RCommandMap.getKnownCommands(RCraftServer.getCommandMap());
} catch (Exception ex) {
ex.printStackTrace();
return;
}
for (String command : commands) {
map.remove(command);
}
}
public void restoreBukkitPluginCommand() {
RCraftServer.getCommandMap().register("bukkit", new PluginsCommand("plugins"));
}
/**
* Reloads the configurations of the plugin.
* Also makes sure the bukkit /pl command gets restored.
* Retrieves the disabled commands from the configuration.
*/
public void reload() {
if (commandPlugins != null) {
commandManager.unregisterCommand(commandPlugins);
restoreBukkitPluginCommand();
}
new Config("config.yml", CONFIG_RESOURCE);
new Messenger("messages.yml", MESSAGES_RESOURCE);
if (!Config.getInstance().getConfig().getBoolean("settings.disable-plugins-command")) {
this.removeCommands("pl", "plugins");
this.commandPlugins = new CommandPlugins();
commandManager.registerCommand(commandPlugins, true);
}
getPlugin().getTaskManager().runTask(() -> BukkitPluginManager.unregisterExactCommands(getDisabledCommands()));
}
private List<Command> getDisabledCommands() {
public List<Command> getDisabledCommands() {
List<Command> commands = new ArrayList<>();
for (String cmd : Config.getInstance().getConfig().getStringList("disabled-commands")) {
for (String cmd : plugin.getConfigResource().getConfig().getStringList("disabled-commands")) {
String[] split = cmd.split(":");
Command command;
@ -153,8 +88,4 @@ public class ServerUtils extends JavaPlugin implements CommandExecutor {
}
return commands;
}
public PaperCommandManager getCommandManager() {
return commandManager;
}
}

View file

@ -0,0 +1,59 @@
package net.frankheijden.serverutils.bukkit.commands;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.context.CommandContext;
import net.frankheijden.serverutils.bukkit.entities.BukkitCommandSender;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.common.commands.CommandPlugins;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
public class BukkitCommandPlugins extends CommandPlugins<
BukkitPlugin,
Plugin,
BukkitTask,
BukkitCommandSender,
CommandSender
> {
public BukkitCommandPlugins(BukkitPlugin plugin) {
super(plugin);
}
@Override
protected void register(
CommandManager<BukkitCommandSender> manager,
Command.Builder<BukkitCommandSender> builder
) {
manager.command(builder
.flag(parseFlag("version"))
.handler(this::handlePlugins));
}
@Override
protected void handlePlugins(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
boolean hasVersionFlag = context.flags().contains("version");
handlePlugins(sender, plugin.getPluginManager().getPluginsSorted(), bukkitPlugin -> {
PluginDescriptionFile description = bukkitPlugin.getDescription();
String message = plugin.getMessagesResource().getMessage(
"serverutils.plugins.format",
"%plugin%", description.getName()
);
if (hasVersionFlag) {
message += plugin.getMessagesResource().getMessage(
"serverutils.plugins.version",
"%version%", description.getVersion()
);
}
return message;
});
}
}

View file

@ -0,0 +1,208 @@
package net.frankheijden.serverutils.bukkit.commands;
import cloud.commandframework.CommandManager;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.context.CommandContext;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
import net.frankheijden.serverutils.bukkit.entities.BukkitCommandSender;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
import net.frankheijden.serverutils.bukkit.reflection.RDedicatedServer;
import net.frankheijden.serverutils.bukkit.utils.ReloadHandler;
import net.frankheijden.serverutils.bukkit.utils.VersionReloadHandler;
import net.frankheijden.serverutils.common.commands.CommandServerUtils;
import net.frankheijden.serverutils.common.entities.Result;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.ForwardFilter;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
public class BukkitCommandServerUtils extends CommandServerUtils<
BukkitPlugin,
Plugin,
BukkitTask,
BukkitCommandSender,
CommandSender
> {
private static final Map<String, ReloadHandler> supportedConfigs;
static {
supportedConfigs = new HashMap<>();
supportedConfigs.put("bukkit", new VersionReloadHandler(16, RCraftServer::reloadBukkitConfiguration));
supportedConfigs.put("commands.yml", RCraftServer::reloadCommandsConfiguration);
supportedConfigs.put("server-icon.png", new VersionReloadHandler(16, RCraftServer::loadIcon));
supportedConfigs.put("banned-ips.json", new VersionReloadHandler(16, RCraftServer::reloadIpBans));
supportedConfigs.put("banned-players.json", new VersionReloadHandler(16, RCraftServer::reloadProfileBans));
supportedConfigs.put("server.properties", new VersionReloadHandler(
16,
RDedicatedServer::reloadServerProperties
));
}
public BukkitCommandServerUtils(BukkitPlugin plugin) {
super(plugin);
}
@Override
public void register(
CommandManager<BukkitCommandSender> manager,
cloud.commandframework.Command.Builder<BukkitCommandSender> builder
) {
super.register(manager, builder);
final List<String> supportedConfigNames = supportedConfigs.entrySet().stream()
.filter(r -> {
if (r instanceof VersionReloadHandler) {
VersionReloadHandler reloadHandler = ((VersionReloadHandler) r);
return MinecraftReflectionVersion.MINOR <= reloadHandler.getMinecraftVersionMaximum();
}
return true;
})
.map(Map.Entry::getKey)
.collect(Collectors.toList());
addArgument(CommandArgument.<BukkitCommandSender, String>ofType(String.class, "config")
.manager(manager)
.withSuggestionsProvider((context, s) -> supportedConfigNames)
.build());
manager.command(parseSubcommand(builder, "enableplugin")
.argument(getArgument("plugin"))
.handler(this::handleEnablePlugin));
manager.command(parseSubcommand(builder, "disableplugin")
.argument(getArgument("plugin"))
.handler(this::handleDisablePlugin));
manager.command(parseSubcommand(builder, "reloadconfig")
.argument(getArgument("config"))
.handler(this::handleReloadConfig));
}
private void handleEnablePlugin(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
String pluginName = context.get("pluginName");
Result result = plugin.getPluginManager().enablePlugin(pluginName);
result.sendTo(sender, "enabl", pluginName);
}
private void handleDisablePlugin(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
String pluginName = context.get("pluginName");
Result result = plugin.getPluginManager().disablePlugin(pluginName);
result.sendTo(sender, "disabl", pluginName);
}
private void handleReloadConfig(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
String config = context.get("config");
ReloadHandler handler = supportedConfigs.get(config);
if (handler == null) {
plugin.getMessagesResource().sendMessage(
sender,
"serverutils.reloadconfig.not_exists",
"%what%", config
);
return;
}
if (handler instanceof VersionReloadHandler) {
VersionReloadHandler versionReloadHandler = (VersionReloadHandler) handler;
int max = versionReloadHandler.getMinecraftVersionMaximum();
if (MinecraftReflectionVersion.MINOR > max) {
plugin.getMessagesResource().sendMessage(
sender,
"serverutils.reloadconfig.not_supported",
"%what%", config
);
return;
}
}
String[] replacements = new String[]{ "%action%", "reload", "%what%", config };
ForwardFilter filter = new ForwardFilter(plugin.getChatProvider(), sender);
filter.start(Bukkit.getLogger());
try {
handler.handle();
filter.stop(Bukkit.getLogger());
String path = "serverutils." + (filter.hasWarnings() ? "warning" : "success");
plugin.getMessagesResource().sendMessage(sender, path, replacements);
} catch (Exception ex) {
filter.stop(Bukkit.getLogger());
ex.printStackTrace();
plugin.getMessagesResource().sendMessage(sender, "serverutils.error", replacements);
}
}
@Override
protected FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String pluginName
) {
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
PluginDescriptionFile description = plugin.getDescription();
builder.add("Name", plugin.getName())
.add("Full Name", description.getFullName())
.add("Version", description.getVersion())
.add("Website", description.getWebsite())
.add("Authors", listBuilderFunction.apply(b -> b.addAll(description.getAuthors())))
.add("Description", description.getDescription())
.add("Main", description.getMain())
.add("Prefix", description.getPrefix())
.add("Load Order", description.getLoad().name())
.add("Load Before", listBuilderFunction.apply(b -> b.addAll(description.getLoadBefore())))
.add("Depend", listBuilderFunction.apply(b -> b.addAll(description.getDepend())))
.add("Soft Depend", listBuilderFunction.apply(b -> b.addAll(description.getSoftDepend())));
if (MinecraftReflectionVersion.MINOR >= 13) {
builder.add("API Version", description.getAPIVersion());
}
if (MinecraftReflectionVersion.MINOR >= 15) {
builder.add("Provides", listBuilderFunction.apply(b -> b.addAll(description.getProvides())));
}
return builder;
}
@Override
protected FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String commandName
) {
Command cmd = BukkitPluginManager.getCommand(commandName);
builder.add("Name", cmd.getName());
if (cmd instanceof PluginIdentifiableCommand) {
builder.add("Plugin", ((PluginIdentifiableCommand) cmd).getPlugin().getName());
}
return builder.add("Aliases", listBuilderFunction.apply(b -> b.addAll(cmd.getAliases())))
.add("Usage", cmd.getUsage())
.add("Description", cmd.getDescription())
.add("Label", cmd.getLabel())
.add("Permission", cmd.getPermission())
.add("Permission Message", cmd.getPermissionMessage());
}
}

View file

@ -1,49 +0,0 @@
package net.frankheijden.serverutils.bukkit.commands;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.utils.BukkitUtils;
import net.frankheijden.serverutils.common.commands.Plugins;
import net.frankheijden.serverutils.common.config.Messenger;
import org.bukkit.command.CommandSender;
@CommandAlias("pl|plugins")
public class CommandPlugins extends BaseCommand {
private static final BukkitPluginManager manager = BukkitPluginManager.get();
/**
* Sends the plugin list to the sender, without plugin version.
* @param sender The sender of the command.
*/
@Default
@CommandPermission("serverutils.plugins")
@Description("Shows the plugins of this server.")
public void onPlugins(CommandSender sender) {
Plugins.sendPlugins(BukkitUtils.wrap(sender), manager.getPluginsSorted(), pl -> {
String format = "serverutils.plugins.format" + (pl.isEnabled() ? "" : "_disabled");
return Messenger.getMessage(format, "%plugin%", pl.getName());
});
}
/**
* Sends the plugin list to the sender, with plugin version.
* @param sender The sender of the command.
*/
@Subcommand("-v")
@CommandPermission("serverutils.plugins.version")
@Description("Shows the plugins of this server with version.")
public void onPluginsWithVersion(CommandSender sender) {
Plugins.sendPlugins(BukkitUtils.wrap(sender), manager.getPluginsSorted(), pl -> {
String format = "serverutils.plugins.format" + (pl.isEnabled() ? "" : "_disabled");
String version = Messenger.getMessage("serverutils.plugins.version",
"%version%", pl.getDescription().getVersion());
return Messenger.getMessage(format, "%plugin%", pl.getName()) + version;
});
}
}

View file

@ -1,408 +0,0 @@
package net.frankheijden.serverutils.bukkit.commands;
import static net.frankheijden.serverutils.common.config.Messenger.sendMessage;
import static net.frankheijden.serverutils.common.config.Messenger.sendRawMessage;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.RootCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Dependency;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import net.frankheijden.serverutils.bukkit.ServerUtils;
import net.frankheijden.serverutils.bukkit.entities.BukkitLoadResult;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
import net.frankheijden.serverutils.bukkit.reflection.RDedicatedServer;
import net.frankheijden.serverutils.bukkit.utils.BukkitUtils;
import net.frankheijden.serverutils.bukkit.utils.ReloadHandler;
import net.frankheijden.serverutils.bukkit.utils.VersionReloadHandler;
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;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.ForwardFilter;
import net.frankheijden.serverutils.common.utils.HexUtils;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
@CommandAlias("su|serverutils")
public class CommandServerUtils extends BaseCommand {
private static final Map<String, ReloadHandler> supportedConfigs;
static {
supportedConfigs = new HashMap<>();
supportedConfigs.put("bukkit", new VersionReloadHandler(16, RCraftServer::reloadBukkitConfiguration));
supportedConfigs.put("commands.yml", RCraftServer::reloadCommandsConfiguration);
supportedConfigs.put("server-icon.png", new VersionReloadHandler(16, RCraftServer::loadIcon));
supportedConfigs.put("banned-ips.json", new VersionReloadHandler(16, RCraftServer::reloadIpBans));
supportedConfigs.put("banned-players.json", new VersionReloadHandler(16, RCraftServer::reloadProfileBans));
supportedConfigs.put("server.properties", new VersionReloadHandler(
16,
RDedicatedServer::reloadServerProperties
));
}
@Dependency
private ServerUtils plugin;
public static Set<String> getSupportedConfigs() {
return supportedConfigs.keySet();
}
/**
* Shows the help page to the sender.
* @param commandSender The sender of the command.
*/
@Default
@Subcommand("help")
@CommandPermission("serverutils.help")
@Description("Shows a help page with a few commands.")
public void onHelp(CommandSender commandSender) {
ServerCommandSender sender = BukkitUtils.wrap(commandSender);
Messenger.sendMessage(sender, "serverutils.help.header");
FormatBuilder builder = FormatBuilder.create(Messenger.getMessage("serverutils.help.format"))
.orderedKeys("%command%", "%subcommand%", "%help%");
Set<String> rootCommands = new HashSet<>();
for (RootCommand root : plugin.getCommandManager().getRegisteredRootCommands()) {
String rootName = root.getDefCommand().getName();
if (!rootCommands.add(rootName)) continue;
builder.add(rootName, "", root.getDescription());
Set<String> subCommands = new HashSet<>();
for (RegisteredCommand<?> sub : root.getSubCommands().values()) {
String name = sub.getPrefSubCommand().toLowerCase();
if (name.isEmpty()) continue;
if (!subCommands.add(name)) continue;
builder.add(rootName, " " + name, sub.getHelpText());
}
}
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.help.footer");
}
/**
* Reloads the configurations of ServerUtils.
* @param sender The sender of the command.
*/
@Subcommand("reload|r")
@CommandPermission("serverutils.reload")
@Description("Reloads the ServerUtils plugin.")
public void onReload(CommandSender sender) {
plugin.reload();
sendMessage(BukkitUtils.wrap(sender), "serverutils.success",
"%action%", "reload",
"%what%", "ServerUtils configurations");
}
/**
* Reloads a config from a set of configurations of the server.
* @param commandSender The sender of the command.
* @param config The configuration to reload.
*/
@Subcommand("reloadconfig|rc")
@CommandCompletion("@supportedConfigs")
@CommandPermission("serverutils.reloadconfig")
@Description("Reloads individual Server configurations.")
public void onReloadCommands(CommandSender commandSender, String config) {
ServerCommandSender sender = BukkitUtils.wrap(commandSender);
ReloadHandler handler = supportedConfigs.get(config);
if (handler == null) {
this.doHelp(commandSender);
return;
}
if (handler instanceof VersionReloadHandler) {
VersionReloadHandler versionReloadHandler = (VersionReloadHandler) handler;
int max = versionReloadHandler.getMinecraftVersionMaximum();
if (MinecraftReflectionVersion.MINOR > max) {
sendRawMessage(sender, "&cThis command is not supported on your Minecraft version."
+ " This command only support Minecraft versions up to MC1." + max);
return;
}
}
String[] replacements = new String[]{ "%action%", "reload", "%what%", config };
ForwardFilter filter = new ForwardFilter(plugin.getPlugin().getChatProvider(), sender);
filter.start(Bukkit.getLogger());
try {
handler.handle();
filter.stop(Bukkit.getLogger());
String path = "serverutils." + (filter.hasWarnings() ? "warning" : "success");
sendMessage(sender, path, replacements);
} catch (Exception ex) {
filter.stop(Bukkit.getLogger());
ex.printStackTrace();
sendMessage(sender, "serverutils.error", replacements);
}
}
/**
* Loads the specified plugin on the server.
* @param commandSender The sender of the command.
* @param jarFile The filename of the plugin in the plugins/ directory.
*/
@Subcommand("loadplugin|lp")
@CommandCompletion("@pluginJars")
@CommandPermission("serverutils.loadplugin")
@Description("Loads the specified jar file as a plugin.")
public void onLoadPlugin(CommandSender commandSender, String jarFile) {
ServerCommandSender sender = BukkitUtils.wrap(commandSender);
BukkitLoadResult loadResult = BukkitPluginManager.get().loadPlugin(jarFile);
if (!loadResult.isSuccess()) {
loadResult.getResult().sendTo(sender, "load", jarFile);
return;
}
Result result = BukkitPluginManager.get().enablePlugin(loadResult.get());
result.sendTo(sender, "load", jarFile);
}
/**
* Unloads the specified plugin from the server.
* @param commandSender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("unloadplugin|up")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.unloadplugin")
@Description("Disables and unloads the specified plugin.")
public void onUnloadPlugin(CommandSender commandSender, String pluginName) {
ServerCommandSender sender = BukkitUtils.wrap(commandSender);
Result disableResult = BukkitPluginManager.get().disablePlugin(pluginName);
if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) {
disableResult.sendTo(sender, "disabl", pluginName);
return;
}
CloseableResult result = BukkitPluginManager.get().unloadPlugin(pluginName);
result.getResult().sendTo(sender, "unload", pluginName);
result.tryClose();
}
/**
* Reloads the specified plugin on the server.
* @param sender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("reloadplugin|rp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.reloadplugin")
@Description("Reloads a specified plugin.")
public void onReloadPlugin(CommandSender sender, String pluginName) {
// Wacky method to have the resources needed for the reload in memory, in case of a self reload.
HexUtils utils = new HexUtils();
Map<String, Object> section = Messenger.getInstance().getConfig().getMap("serverutils");
String result = BukkitPluginManager.get().reloadPlugin(pluginName).toString();
String msg = (String) section.get(result.toLowerCase());
if (msg != null && !msg.isEmpty()) {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', utils.convertHexString(
msg.replace("%action%", "reload").replace("%what%", pluginName))));
}
}
/**
* Enables the specified plugin on the server.
* @param sender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("enableplugin|ep")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.enableplugin")
@Description("Enables the loaded plugin.")
public void onEnablePlugin(CommandSender sender, String pluginName) {
Result result = BukkitPluginManager.get().enablePlugin(pluginName);
result.sendTo(BukkitUtils.wrap(sender), "enabl", pluginName);
}
/**
* Disables the specified plugin on the server.
* @param sender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("disableplugin|dp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.disableplugin")
@Description("Disables the specified plugin.")
public void onDisablePlugin(CommandSender sender, String pluginName) {
Result result = BukkitPluginManager.get().disablePlugin(pluginName);
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|wp")
@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|uwp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.watchplugin")
@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.
* @param pluginName The plugin name.
*/
@Subcommand("plugininfo|pi")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.plugininfo")
@Description("Shows information about the specified plugin.")
public void onPluginInfo(CommandSender commandSender, String pluginName) {
ServerCommandSender sender = BukkitUtils.wrap(commandSender);
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
if (plugin == null) {
Result.NOT_EXISTS.sendTo(sender, "fetch", pluginName);
return;
}
PluginDescriptionFile description = plugin.getDescription();
String format = Messenger.getMessage("serverutils.plugininfo.format");
String listFormatString = Messenger.getMessage("serverutils.plugininfo.list_format");
String seperator = Messenger.getMessage("serverutils.plugininfo.seperator");
String lastSeperator = Messenger.getMessage("serverutils.plugininfo.last_seperator");
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
Messenger.sendMessage(sender, "serverutils.plugininfo.header");
FormatBuilder builder = FormatBuilder.create(format)
.orderedKeys("%key%", "%value%")
.add("Name", plugin.getName())
.add("Full Name", description.getFullName())
.add("Version", description.getVersion());
if (MinecraftReflectionVersion.MINOR >= 13) builder.add("API Version", description.getAPIVersion());
builder.add("Website", description.getWebsite())
.add("Authors", ListBuilder.create(description.getAuthors())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Description", description.getDescription())
.add("Main", description.getMain())
.add("Prefix", description.getPrefix())
.add("Load Order", description.getLoad().name())
.add("Load Before", ListBuilder.create(description.getLoadBefore())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Depend", ListBuilder.create(description.getDepend())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Soft Depend", ListBuilder.create(description.getSoftDepend())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString());
if (MinecraftReflectionVersion.MINOR >= 15) {
builder.add("Provides", ListBuilder.create(description.getProvides())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString());
}
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.plugininfo.footer");
}
/**
* Shows information about a provided command.
* @param commandSender The sender of the command.
* @param command The command to lookup.
*/
@Subcommand("commandinfo|ci")
@CommandCompletion("@commands")
@CommandPermission("serverutils.commandinfo")
@Description("Shows information about the specified command.")
public void onCommandInfo(CommandSender commandSender, String command) {
ServerCommandSender sender = BukkitUtils.wrap(commandSender);
Command cmd = BukkitPluginManager.getCommand(command);
if (cmd == null) {
Messenger.sendMessage(sender, "serverutils.commandinfo.not_exists");
return;
}
String format = Messenger.getMessage("serverutils.commandinfo.format");
String listFormatString = Messenger.getMessage("serverutils.commandinfo.list_format");
String seperator = Messenger.getMessage("serverutils.commandinfo.seperator");
String lastSeperator = Messenger.getMessage("serverutils.commandinfo.last_seperator");
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
Messenger.sendMessage(sender, "serverutils.commandinfo.header");
FormatBuilder builder = FormatBuilder.create(format)
.orderedKeys("%key%", "%value%")
.add("Name", cmd.getName());
if (cmd instanceof PluginIdentifiableCommand) {
PluginIdentifiableCommand pc = (PluginIdentifiableCommand) cmd;
builder.add("Plugin", pc.getPlugin().getName());
}
builder.add("Usage", cmd.getUsage())
.add("Description", cmd.getDescription())
.add("Aliases", ListBuilder.create(cmd.getAliases())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Label", cmd.getLabel())
.add("Permission", cmd.getPermission())
.add("Permission Message", cmd.getPermissionMessage());
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.commandinfo.footer");
}
}

View file

@ -1,41 +1,28 @@
package net.frankheijden.serverutils.bukkit.entities;
import net.frankheijden.serverutils.bukkit.utils.BukkitUtils;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.providers.ChatProvider;
import net.frankheijden.serverutils.common.utils.HexUtils;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
/**
* Provides basic chat functionality for Bukkit servers.
*/
public class BukkitChatProvider extends ChatProvider {
public class BukkitChatProvider implements ChatProvider<BukkitCommandSender, CommandSender> {
/**
* Retrieves the console sender of a Bukkit instance.
* @return The console sender.
*/
@Override
public ServerCommandSender getConsoleSender() {
return BukkitUtils.wrap(Bukkit.getConsoleSender());
public BukkitCommandSender getConsoleSender() {
return new BukkitCommandSender(Bukkit.getConsoleSender());
}
@Override
public BukkitCommandSender get(CommandSender source) {
return new BukkitCommandSender(source);
}
/**
* Colorizes the given string.
* @param str The string to color.
* @return The colored string.
*/
@Override
public String color(String str) {
return ChatColor.translateAlternateColorCodes('&', HexUtils.convertHexString(str));
}
/**
* Broadcasts a message over a Bukkit instance.
* @param permission The permission the receivers need to have.
* @param message The message to broadcast.
*/
@Override
public void broadcast(String permission, String message) {
Bukkit.broadcast(message, permission);

View file

@ -7,7 +7,7 @@ import org.bukkit.entity.Player;
/**
* A wrap for a Bukkit CommandSender.
*/
public class BukkitCommandSender implements ServerCommandSender {
public class BukkitCommandSender implements ServerCommandSender<CommandSender> {
private final CommandSender sender;
@ -46,4 +46,9 @@ public class BukkitCommandSender implements ServerCommandSender {
public boolean isPlayer() {
return sender instanceof Player;
}
@Override
public CommandSender getSource() {
return sender;
}
}

View file

@ -1,19 +1,34 @@
package net.frankheijden.serverutils.bukkit.entities;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.paper.PaperCommandManager;
import java.io.File;
import java.util.logging.Logger;
import net.frankheijden.serverutils.bukkit.ServerUtils;
import net.frankheijden.serverutils.bukkit.commands.BukkitCommandPlugins;
import net.frankheijden.serverutils.bukkit.commands.BukkitCommandServerUtils;
import net.frankheijden.serverutils.bukkit.listeners.BukkitListener;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.managers.BukkitTaskManager;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
public class BukkitPlugin extends ServerUtilsPlugin {
public class BukkitPlugin extends ServerUtilsPlugin<
Plugin,
BukkitTask,
BukkitCommandSender,
CommandSender
> {
private final ServerUtils plugin;
private final BukkitPluginManager pluginManager;
private final BukkitTaskManager taskManager;
private final BukkitResourceProvider resourceProvider;
private final BukkitChatProvider chatProvider;
private boolean registeredPluginsCommand;
/**
* Creates a new BukkitPlugin instance of ServerUtils.
@ -25,16 +40,34 @@ public class BukkitPlugin extends ServerUtilsPlugin {
this.taskManager = new BukkitTaskManager();
this.resourceProvider = new BukkitResourceProvider(plugin);
this.chatProvider = new BukkitChatProvider();
this.registeredPluginsCommand = false;
}
@Override
protected PaperCommandManager<BukkitCommandSender> newCommandManager() {
try {
return new PaperCommandManager<>(
plugin,
CommandExecutionCoordinator.simpleCoordinator(),
chatProvider::get,
BukkitCommandSender::getSource
);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
@Override
public Platform getPlatform() {
return Platform.BUKKIT;
}
@Override
@SuppressWarnings("unchecked")
public BukkitPluginManager getPluginManager() {
return pluginManager;
}
@Override
@SuppressWarnings("unchecked")
public BukkitTaskManager getTaskManager() {
return taskManager;
}
@ -60,8 +93,23 @@ public class BukkitPlugin extends ServerUtilsPlugin {
}
@Override
@SuppressWarnings("unchecked")
public File fetchUpdaterData() {
return pluginManager.getPluginFile("ServerUtils");
protected void enablePlugin() {
Bukkit.getPluginManager().registerEvents(new BukkitListener(this), plugin);
}
@Override
protected void reloadPlugin() {
if (getConfigResource().getConfig().getBoolean("settings.disable-plugins-command")) {
if (registeredPluginsCommand) {
plugin.restoreBukkitPluginCommand();
this.registeredPluginsCommand = false;
}
} else {
new BukkitCommandPlugins(this).register(commandManager);
this.registeredPluginsCommand = true;
}
new BukkitCommandServerUtils(this).register(commandManager);
taskManager.runTask(() -> BukkitPluginManager.unregisterExactCommands(plugin.getDisabledCommands()));
}
}

View file

@ -16,6 +16,11 @@ public class BukkitResourceProvider implements ResourceProvider {
@Override
public InputStream getResource(String resource) {
return getRawResource(resource + getResourceExtension());
}
@Override
public InputStream getRawResource(String resource) {
return plugin.getResource(resource);
}
@ -28,4 +33,9 @@ public class BukkitResourceProvider implements ResourceProvider {
public ServerUtilsConfig load(File file) {
return new BukkitYamlConfig(file);
}
@Override
public String getResourceExtension() {
return ".yml";
}
}

View file

@ -1,21 +1,35 @@
package net.frankheijden.serverutils.bukkit.listeners;
import net.frankheijden.serverutils.bukkit.utils.BukkitUtils;
import net.frankheijden.serverutils.bukkit.entities.BukkitCommandSender;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.common.listeners.ServerListener;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
public class BukkitListener implements Listener {
public class BukkitListener extends ServerListener<
BukkitPlugin,
Plugin,
BukkitTask,
BukkitCommandSender,
CommandSender
> implements Listener {
public BukkitListener(BukkitPlugin plugin) {
super(plugin);
}
/**
* Called when a player joins the server.
* Used for sending an update message to the player, if enabled and has permission.
* @param event The PlayerJoinEvent.
*/
@EventHandler(priority = EventPriority.LOWEST)
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
ServerListener.handleUpdate(BukkitUtils.wrap(event.getPlayer()));
handleUpdate(plugin.getChatProvider().get(event.getPlayer()));
}
}

View file

@ -39,7 +39,7 @@ import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.UnknownDependencyException;
public class BukkitPluginManager extends AbstractPluginManager<Plugin> {
public class BukkitPluginManager implements AbstractPluginManager<Plugin> {
private static BukkitPluginManager instance;
@ -306,6 +306,25 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin> {
RCraftServer.syncCommands();
}
/**
* Unregisters all the specified commands.
*/
public static void unregisterCommands(String... commands) {
Map<String, Command> map;
try {
map = RCommandMap.getKnownCommands(RCraftServer.getCommandMap());
} catch (Exception ex) {
ex.printStackTrace();
return;
}
for (String command : commands) {
map.remove(command);
}
RCraftServer.syncCommands();
}
/**
* Unregisters all specified commands exactly.
* @param commands The commands to unregister.

View file

@ -1,12 +0,0 @@
package net.frankheijden.serverutils.bukkit.utils;
import net.frankheijden.serverutils.bukkit.entities.BukkitCommandSender;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import org.bukkit.command.CommandSender;
public class BukkitUtils {
public static ServerCommandSender wrap(CommandSender sender) {
return new BukkitCommandSender(sender);
}
}

View file

@ -0,0 +1,26 @@
{
"serverutils": {
"subcommands": {
"enableplugin": {
"main": "enableplugin",
"aliases": ["ep"],
"permission": "serverutils.enableplugin",
"description": "Enables the specified plugin.",
"display-in-help": true
},
"disableplugin": {
"main": "disableplugin",
"aliases": ["dp"],
"permission": "serverutils.disableplugin",
"description": "Disables the specified plugin.",
"display-in-help": true
},
"reloadconfig": {
"main": "reloadconfig",
"aliases": ["rc"],
"permission": "serverutils.reloadconfig",
"description": "Reloads particular server configurations."
}
}
}
}

View file

@ -0,0 +1,6 @@
{
"settings": {
"disable-plugins-command": false
},
"disabled-commands": []
}

View file

@ -1,10 +0,0 @@
settings:
disable-plugins-command: false
check-updates-boot: true
check-updates-login: false
download-updates-boot: false
download-updates-login: false
install-updates-boot: false
install-updates-login: false
disabled-commands: []

View file

@ -0,0 +1,8 @@
{
"serverutils": {
"reloadconfig": {
"not_exists": "&cConfig &4%what% &cdoes not exist.",
"not_supported": "&cConfig &4%what% &cis not supported on your Minecraft version."
}
}
}

View file

@ -1,62 +0,0 @@
serverutils:
success: "&3Successfully %action%ed &b%what%&3!"
warning: "&3Successfully %action%ed &b%what%&3, but with warnings."
error: "&cAn error occurred while %action%ing &4%what%&c, please check the console!"
not_exists: "&cAn error occurred while %action%ing &4%what%&c, plugin does not exist!"
not_enabled: "&cAn error occurred while %action%ing &4%what%&c, plugin is not enabled!"
already_loaded: "&cAn error occurred while %action%ing &4%what%&c, plugin is already loaded!"
already_enabled: "&cAn error occurred while %action%ing &4%what%&c, plugin is already enabled!"
already_disabled: "&cAn error occurred while %action%ing &4%what%&c, plugin is already disabled!"
file_deleted: "&cAccessing the jar file while %action%ing &4%what%&c went wrong, plugin has been deleted!"
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=--------------
&3Current version: &b%old%
&3New version: &b%new%
&3Release info: &b%info%
&8&m-------------------------------------------------
downloading: |-
&8&m------------=&r&8[ &b&lServerUtils Update&r &8]&m=--------------
&3A new version of ServerUtils will be downloaded and installed after a restart!
&3Current version: &b%old%
&3New version: &b%new%
&3Release info: &b%info%
&8&m-------------------------------------------------
download_failed: "&cFailed to download version %new% of ServerUtils. Please update manually."
download_success: "&3ServerUtils has been downloaded and will be installed on the next restart."
help:
header: "&8&m-------------=&r&8[ &b&lServerUtils Help&r &8]&m=---------------"
format: "&8/&3%command%&b%subcommand% &f(&7%help%&f)"
footer: "&8&m-------------------------------------------------"
plugins:
header: "&8&m------------=&r&8[ &b&lServerUtils Plugins&r &8]&m=-------------"
prefix: " &3Plugins &8(&a%count%&8)&b: "
format: "&3%plugin%"
format_disabled: "&c%plugin%"
seperator: "&b, "
last_seperator: " &band "
version: " &8(&a%version%&8)"
footer: "&8&m-------------------------------------------------"
plugininfo:
header: "&8&m-----------=&r&8[ &b&lServerUtils PluginInfo&r &8]&m=-----------"
format: " &3%key%&8: &b%value%"
list_format: "&b%value%"
seperator: "&8, "
last_seperator: " &8and "
footer: "&8&m-------------------------------------------------"
commandinfo:
header: "&8&m-----------=&r&8[ &b&lServerUtils CommandInfo&r &8]&m=----------"
format: " &3%key%&8: &b%value%"
list_format: "&b%value%"
seperator: "&8, "
last_seperator: " &8and "
footer: "&8&m-------------------------------------------------"
not_exists: "&cThat command is not a valid registered command."

View file

@ -4,10 +4,3 @@ version: ${version}
author: FrankHeijden
api-version: '1.13'
softdepend: [ServerUtilsUpdater]
commands:
serverutils:
usage: "/<command>"
aliases:
- "su"

View file

@ -8,10 +8,10 @@ repositories {
}
dependencies {
implementation 'co.aikar:acf-bungee:0.5.0-SNAPSHOT'
implementation 'com.github.FrankHeijden.cloud:cloud-bungee:fea4605277'
implementation 'org.bstats:bstats-bungeecord:2.2.1'
implementation project(":Common")
compileOnly 'net.md-5:bungeecord-api:1.16-R0.5-SNAPSHOT'
compileOnly 'net.md-5:bungeecord-api:1.17-R0.1-SNAPSHOT'
}
processResources {
@ -23,6 +23,4 @@ processResources {
shadowJar {
relocate 'org.bstats', dependencyDir + '.bstats'
relocate 'co.aikar.commands', dependencyDir + '.acf'
relocate 'co.aikar.locales', dependencyDir + '.locales'
}

View file

@ -1,27 +1,15 @@
package net.frankheijden.serverutils.bungee;
import co.aikar.commands.BungeeCommandCompletionContext;
import co.aikar.commands.BungeeCommandManager;
import co.aikar.commands.CommandCompletions;
import net.frankheijden.serverutils.bungee.commands.CommandPlugins;
import net.frankheijden.serverutils.bungee.commands.CommandServerUtils;
import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.bungee.listeners.BungeeListener;
import net.frankheijden.serverutils.bungee.managers.BungeePluginManager;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.Config;
import net.frankheijden.serverutils.common.config.Messenger;
import net.md_5.bungee.api.plugin.Plugin;
import org.bstats.bungeecord.Metrics;
public class ServerUtils extends Plugin {
private static ServerUtils instance;
private static final String CONFIG_RESOURCE = "bungee-config.yml";
private static final String MESSAGES_RESOURCE = "bungee-messages.yml";
private BungeePlugin plugin;
private BungeeCommandManager commandManager;
@Override
public void onEnable() {
@ -32,29 +20,12 @@ public class ServerUtils extends Plugin {
ServerUtilsApp.init(this, plugin);
new Metrics(this, ServerUtilsApp.BSTATS_METRICS_ID);
this.commandManager = new BungeeCommandManager(this);
commandManager.registerCommand(new CommandPlugins());
commandManager.registerCommand(new CommandServerUtils());
BungeePluginManager manager = plugin.getPluginManager();
CommandCompletions<BungeeCommandCompletionContext> commandCompletions = commandManager.getCommandCompletions();
commandCompletions.registerAsyncCompletion("plugins", context -> manager.getPluginNames());
commandCompletions.registerAsyncCompletion("pluginJars", context -> manager.getPluginFileNames());
commandCompletions.registerAsyncCompletion("commands", context -> manager.getCommands());
reload();
getProxy().getPluginManager().registerListener(this, new BungeeListener());
plugin.enable();
ServerUtilsApp.tryCheckForUpdates();
}
@Override
public void onDisable() {
super.onDisable();
commandManager.unregisterCommands();
plugin.disable();
}
@ -65,13 +36,4 @@ public class ServerUtils extends Plugin {
public BungeePlugin getPlugin() {
return plugin;
}
public BungeeCommandManager getCommandManager() {
return commandManager;
}
public void reload() {
new Config("config.yml", CONFIG_RESOURCE);
new Messenger("messages.yml", MESSAGES_RESOURCE);
}
}

View file

@ -0,0 +1,61 @@
package net.frankheijden.serverutils.bungee.commands;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.context.CommandContext;
import net.frankheijden.serverutils.bungee.entities.BungeeCommandSender;
import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.common.commands.CommandPlugins;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
import net.md_5.bungee.api.scheduler.ScheduledTask;
public class BungeeCommandPlugins extends CommandPlugins<
BungeePlugin,
Plugin,
ScheduledTask,
BungeeCommandSender,
CommandSender
> {
public BungeeCommandPlugins(BungeePlugin plugin) {
super(plugin);
}
@Override
protected void register(
CommandManager<BungeeCommandSender> manager,
Command.Builder<BungeeCommandSender> builder
) {
manager.command(builder
.flag(parseFlag("version"))
.flag(parseFlag("modules"))
.handler(this::handlePlugins));
}
@Override
protected void handlePlugins(CommandContext<BungeeCommandSender> context) {
BungeeCommandSender sender = context.getSender();
boolean hasVersionFlag = context.flags().contains("version");
boolean hasModulesFlag = context.flags().contains("modules");
handlePlugins(sender, plugin.getPluginManager().getPluginsSorted(hasModulesFlag), bungeePlugin -> {
PluginDescription description = bungeePlugin.getDescription();
String message = plugin.getMessagesResource().getMessage(
"serverutils.plugins.format",
"%plugin%", description.getName()
);
if (hasVersionFlag) {
message += plugin.getMessagesResource().getMessage(
"serverutils.plugins.version",
"%version%", description.getVersion()
);
}
return message;
});
}
}

View file

@ -0,0 +1,78 @@
package net.frankheijden.serverutils.bungee.commands;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import net.frankheijden.serverutils.bungee.ServerUtils;
import net.frankheijden.serverutils.bungee.entities.BungeeCommandSender;
import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.bungee.reflection.RPluginManager;
import net.frankheijden.serverutils.common.commands.CommandServerUtils;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
import net.md_5.bungee.api.plugin.PluginManager;
import net.md_5.bungee.api.scheduler.ScheduledTask;
public class BungeeCommandServerUtils extends CommandServerUtils<
BungeePlugin,
Plugin,
ScheduledTask,
BungeeCommandSender,
CommandSender
> {
public BungeeCommandServerUtils(BungeePlugin plugin) {
super(plugin);
}
@Override
protected FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String pluginName
) {
Plugin container = plugin.getPluginManager().getPlugin(pluginName);
PluginDescription desc = container.getDescription();
return builder
.add("Name", desc.getName())
.add("Version", desc.getVersion())
.add("Author", desc.getAuthor())
.add("Description", desc.getDescription())
.add("Main", desc.getMain())
.add("File", desc.getFile().getName())
.add("Depend", listBuilderFunction.apply(b -> b.addAll(desc.getDepends())))
.add("Soft Depend", listBuilderFunction.apply(b -> b.addAll(desc.getSoftDepends())));
}
@Override
protected FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String commandName
) {
PluginManager proxyPluginManager = ServerUtils.getInstance().getProxy().getPluginManager();
Map<String, Command> commands;
try {
commands = RPluginManager.getCommands(proxyPluginManager);
} catch (IllegalAccessException ex) {
ex.printStackTrace();
builder.add("Error", "Please check the console.");
return builder;
}
Command cmd = commands.get(commandName);
Plugin plugin = RPluginManager.getPlugin(proxyPluginManager, cmd);
return builder
.add("Name", cmd.getName())
.add("Plugin", plugin == null ? "<UNKNOWN>" : plugin.getDescription().getName())
.add("Aliases", listBuilderFunction.apply(b -> b.addAll(Arrays.asList(cmd.getAliases()))))
.add("Permission", cmd.getPermission());
}
}

View file

@ -1,47 +0,0 @@
package net.frankheijden.serverutils.bungee.commands;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Description;
import net.frankheijden.serverutils.bungee.managers.BungeePluginManager;
import net.frankheijden.serverutils.bungee.utils.BungeeUtils;
import net.frankheijden.serverutils.common.commands.Plugins;
import net.frankheijden.serverutils.common.config.Messenger;
import net.md_5.bungee.api.CommandSender;
@CommandAlias("bpl|bplugins|bungeepl")
public class CommandPlugins extends BaseCommand {
private static final BungeePluginManager manager = BungeePluginManager.get();
/**
* Sends the plugin list to the sender.
* The `-v` flag will output the plugins with version.
* The `-m` flag will also output modules in the plugin list.
* @param sender The sender of the command.
*/
@Default
@CommandCompletion("-v|-m -v|-m")
@CommandPermission("serverutils.plugins")
@Description("Shows the plugins of this proxy.")
public void onPlugins(CommandSender sender, String... args) {
boolean version = contains(args, "-v");
boolean modules = contains(args, "-m");
Plugins.sendPlugins(BungeeUtils.wrap(sender), manager.getPluginsSorted(modules), pl -> {
String ver = version ? Messenger.getMessage("serverutils.plugins.version",
"%version%", pl.getDescription().getVersion()) : "";
return Messenger.getMessage("serverutils.plugins.format",
"%plugin%", pl.getDescription().getName()) + ver;
});
}
private static boolean contains(String[] arr, String val) {
for (String s : arr) {
if (s.equalsIgnoreCase(val)) return true;
}
return false;
}
}

View file

@ -1,292 +0,0 @@
package net.frankheijden.serverutils.bungee.commands;
import static net.frankheijden.serverutils.common.config.Messenger.sendMessage;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.RootCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import net.frankheijden.serverutils.bungee.ServerUtils;
import net.frankheijden.serverutils.bungee.entities.BungeeLoadResult;
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;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.HexUtils;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
@CommandAlias("bsu|bserverutils")
public class CommandServerUtils extends BaseCommand {
private static final ProxyServer proxy = ProxyServer.getInstance();
private static final ServerUtils plugin = ServerUtils.getInstance();
private static final Set<String> ALIASES;
static {
ALIASES = new HashSet<>();
ALIASES.add("bserverutils");
ALIASES.add("bplugins");
ALIASES.add("bungeepl");
}
/**
* Shows the help page to the sender.
* @param commandSender The sender of the command.
*/
@Default
@Subcommand("help")
@CommandPermission("serverutils.help")
@Description("Shows a help page with a few commands.")
public void onHelp(CommandSender commandSender) {
ServerCommandSender sender = BungeeUtils.wrap(commandSender);
Messenger.sendMessage(sender, "serverutils.help.header");
FormatBuilder builder = FormatBuilder.create(Messenger.getMessage("serverutils.help.format"))
.orderedKeys("%command%", "%subcommand%", "%help%");
Set<String> rootCommands = new HashSet<>();
for (RootCommand root : plugin.getCommandManager().getRegisteredRootCommands()) {
String rootName = root.getDefCommand().getName();
if (!rootCommands.add(rootName)) continue;
builder.add(rootName, "", root.getDescription());
Set<String> subCommands = new HashSet<>();
for (RegisteredCommand<?> sub : root.getSubCommands().values()) {
String name = sub.getPrefSubCommand().toLowerCase();
if (name.isEmpty()) continue;
if (!subCommands.add(name)) continue;
builder.add(rootName, " " + name, sub.getHelpText());
}
}
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.help.footer");
}
/**
* Reloads the configurations of ServerUtils.
* @param sender The sender of the command.
*/
@Subcommand("reload")
@CommandPermission("serverutils.reload")
@Description("Reloads the ServerUtils plugin.")
public void onReload(CommandSender sender) {
plugin.reload();
sendMessage(BungeeUtils.wrap(sender), "serverutils.success",
"%action%", "reload",
"%what%", "ServerUtils Bungee configurations");
}
/**
* Loads the specified plugin on the proxy.
* @param commandSender The sender of the command.
* @param jarFile The filename of the plugin in the plugins/ directory.
*/
@Subcommand("loadplugin|lp")
@CommandCompletion("@pluginJars")
@CommandPermission("serverutils.loadplugin")
@Description("Loads the specified jar file as a plugin.")
public void onLoadPlugin(CommandSender commandSender, String jarFile) {
ServerCommandSender sender = BungeeUtils.wrap(commandSender);
BungeeLoadResult loadResult = BungeePluginManager.get().loadPlugin(jarFile);
if (!loadResult.isSuccess()) {
loadResult.getResult().sendTo(sender, "load", jarFile);
return;
}
Plugin plugin = loadResult.get();
Result result = BungeePluginManager.get().enablePlugin(plugin);
result.sendTo(sender, "load", plugin.getDescription().getName());
}
/**
* Unloads the specified plugin from the proxy.
* @param commandSender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("unloadplugin|up")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.unloadplugin")
@Description("Disables and unloads the specified plugin.")
public void onUnloadPlugin(CommandSender commandSender, String pluginName) {
CloseableResult result = BungeePluginManager.get().unloadPlugin(pluginName);
result.getResult().sendTo(BungeeUtils.wrap(commandSender), "unload", pluginName);
result.tryClose();
}
/**
* Reloads the specified plugin on the proxy.
* @param sender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("reloadplugin|rp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.reloadplugin")
@Description("Reloads a specified plugin.")
public void onReloadPlugin(CommandSender sender, String pluginName) {
// Wacky method to have the resources needed for the reload in memory, in case of a self reload.
HexUtils utils = new HexUtils();
Map<String, Object> section = Messenger.getInstance().getConfig().getMap("serverutils");
String result = BungeePluginManager.get().reloadPlugin(pluginName).toString();
String msg = (String) section.get(result.toLowerCase());
if (msg != null && !msg.isEmpty()) {
sender.sendMessage(ChatColor.translateAlternateColorCodes('&', utils.convertHexString(
msg.replace("%action%", "reload").replace("%what%", 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|wp")
@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|uwp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.watchplugin")
@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.
* @param pluginName The plugin name.
*/
@Subcommand("plugininfo|pi")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.plugininfo")
@Description("Shows information about the specified plugin.")
public void onPluginInfo(CommandSender commandSender, String pluginName) {
ServerCommandSender sender = BungeeUtils.wrap(commandSender);
Plugin plugin = ProxyServer.getInstance().getPluginManager().getPlugin(pluginName);
if (plugin == null) {
Result.NOT_EXISTS.sendTo(sender, "fetch", pluginName);
return;
}
PluginDescription desc = plugin.getDescription();
String format = Messenger.getMessage("serverutils.plugininfo.format");
String listFormatString = Messenger.getMessage("serverutils.plugininfo.list_format");
String seperator = Messenger.getMessage("serverutils.plugininfo.seperator");
String lastSeperator = Messenger.getMessage("serverutils.plugininfo.last_seperator");
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
Messenger.sendMessage(sender, "serverutils.plugininfo.header");
FormatBuilder builder = FormatBuilder.create(format)
.orderedKeys("%key%", "%value%")
.add("Name", desc.getName())
.add("Version", desc.getVersion())
.add("Author", desc.getAuthor())
.add("Description", desc.getDescription())
.add("Main", desc.getMain())
.add("File", desc.getFile().getName())
.add("Depend", ListBuilder.create(desc.getDepends())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Soft Depend", ListBuilder.create(desc.getSoftDepends())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString());
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.plugininfo.footer");
}
/**
* Shows information about a provided command.
* @param commandSender The sender of the command.
* @param command The command to lookup.
*/
@Subcommand("commandinfo|ci")
@CommandCompletion("@commands")
@CommandPermission("serverutils.commandinfo")
@Description("Shows information about the specified command.")
public void onCommandInfo(CommandSender commandSender, String command) {
ServerCommandSender sender = BungeeUtils.wrap(commandSender);
Map<String, Command> commands;
try {
commands = RPluginManager.getCommands(proxy.getPluginManager());
} catch (IllegalAccessException ex) {
ex.printStackTrace();
return;
}
Command cmd = commands.get(command);
if (cmd == null) {
Messenger.sendMessage(sender, "serverutils.commandinfo.not_exists");
return;
}
Plugin plugin = RPluginManager.getPlugin(proxy.getPluginManager(), cmd);
if (plugin == null) {
return;
}
String format = Messenger.getMessage("serverutils.commandinfo.format");
String listFormatString = Messenger.getMessage("serverutils.commandinfo.list_format");
String seperator = Messenger.getMessage("serverutils.commandinfo.seperator");
String lastSeperator = Messenger.getMessage("serverutils.commandinfo.last_seperator");
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
Messenger.sendMessage(sender, "serverutils.commandinfo.header");
FormatBuilder builder = FormatBuilder.create(format)
.orderedKeys("%key%", "%value%")
.add("Name", cmd.getName())
.add("Plugin", plugin.getDescription().getName())
.add("Aliases", ListBuilder.create(cmd.getAliases())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Permission", cmd.getPermission());
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.commandinfo.footer");
}
}

View file

@ -1,17 +1,21 @@
package net.frankheijden.serverutils.bungee.entities;
import net.frankheijden.serverutils.bungee.utils.BungeeUtils;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.providers.ChatProvider;
import net.frankheijden.serverutils.common.utils.HexUtils;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
public class BungeeChatProvider extends ChatProvider {
public class BungeeChatProvider implements ChatProvider<BungeeCommandSender, CommandSender> {
@Override
public ServerCommandSender getConsoleSender() {
return BungeeUtils.wrap(ProxyServer.getInstance().getConsole());
public BungeeCommandSender getConsoleSender() {
return new BungeeCommandSender(ProxyServer.getInstance().getConsole());
}
@Override
public BungeeCommandSender get(CommandSender source) {
return new BungeeCommandSender(source);
}
@Override

View file

@ -4,7 +4,7 @@ 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 {
public class BungeeCommandSender implements ServerCommandSender<CommandSender> {
private final CommandSender sender;
@ -30,4 +30,9 @@ public class BungeeCommandSender implements ServerCommandSender {
public boolean isPlayer() {
return sender instanceof ProxiedPlayer;
}
@Override
public CommandSender getSource() {
return sender;
}
}

View file

@ -1,14 +1,26 @@
package net.frankheijden.serverutils.bungee.entities;
import cloud.commandframework.bungee.BungeeCommandManager;
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import java.io.File;
import java.util.logging.Logger;
import net.frankheijden.serverutils.bungee.ServerUtils;
import net.frankheijden.serverutils.bungee.commands.BungeeCommandPlugins;
import net.frankheijden.serverutils.bungee.commands.BungeeCommandServerUtils;
import net.frankheijden.serverutils.bungee.listeners.BungeeServerListener;
import net.frankheijden.serverutils.bungee.managers.BungeePluginManager;
import net.frankheijden.serverutils.bungee.managers.BungeeTaskManager;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.md_5.bungee.api.plugin.PluginDescription;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.scheduler.ScheduledTask;
public class BungeePlugin extends ServerUtilsPlugin {
public class BungeePlugin extends ServerUtilsPlugin<
Plugin,
ScheduledTask,
BungeeCommandSender,
CommandSender
> {
private final ServerUtils plugin;
private final BungeePluginManager pluginManager;
@ -29,13 +41,26 @@ public class BungeePlugin extends ServerUtilsPlugin {
}
@Override
@SuppressWarnings("unchecked")
protected BungeeCommandManager<BungeeCommandSender> newCommandManager() {
return new BungeeCommandManager<>(
plugin,
AsynchronousCommandExecutionCoordinator.<BungeeCommandSender>newBuilder().build(),
chatProvider::get,
BungeeCommandSender::getSource
);
}
@Override
public Platform getPlatform() {
return Platform.BUNGEE;
}
@Override
public BungeePluginManager getPluginManager() {
return pluginManager;
}
@Override
@SuppressWarnings("unchecked")
public BungeeTaskManager getTaskManager() {
return taskManager;
}
@ -61,13 +86,13 @@ public class BungeePlugin extends ServerUtilsPlugin {
}
@Override
@SuppressWarnings("unchecked")
public PluginDescription fetchUpdaterData() {
try {
return BungeePluginManager.getPluginDescription(pluginManager.getPluginFile("ServerUtils"));
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
protected void enablePlugin() {
plugin.getProxy().getPluginManager().registerListener(plugin, new BungeeServerListener(this));
}
@Override
protected void reloadPlugin() {
new BungeeCommandPlugins(this).register(commandManager);
new BungeeCommandServerUtils(this).register(commandManager);
}
}

View file

@ -16,7 +16,7 @@ public class BungeeResourceProvider implements ResourceProvider {
}
@Override
public InputStream getResource(String resource) {
public InputStream getRawResource(String resource) {
return plugin.getResourceAsStream(resource);
}
@ -34,4 +34,9 @@ public class BungeeResourceProvider implements ResourceProvider {
}
return null;
}
@Override
public String getResourceExtension() {
return ".yml";
}
}

View file

@ -1,16 +0,0 @@
package net.frankheijden.serverutils.bungee.listeners;
import net.frankheijden.serverutils.bungee.utils.BungeeUtils;
import net.frankheijden.serverutils.common.listeners.ServerListener;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
public class BungeeListener implements Listener {
@EventHandler
public void onServerConnect(ServerConnectEvent event) {
if (event.getReason() != ServerConnectEvent.Reason.JOIN_PROXY) return;
ServerListener.handleUpdate(BungeeUtils.wrap(event.getPlayer()));
}
}

View file

@ -0,0 +1,30 @@
package net.frankheijden.serverutils.bungee.listeners;
import net.frankheijden.serverutils.bungee.entities.BungeeCommandSender;
import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.common.listeners.ServerListener;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import net.md_5.bungee.event.EventHandler;
public class BungeeServerListener extends ServerListener<
BungeePlugin,
Plugin,
ScheduledTask,
BungeeCommandSender,
CommandSender
> implements Listener {
public BungeeServerListener(BungeePlugin plugin) {
super(plugin);
}
@EventHandler
public void onServerConnect(ServerConnectEvent event) {
if (event.getReason() != ServerConnectEvent.Reason.JOIN_PROXY) return;
handleUpdate(plugin.getChatProvider().get(event.getPlayer()));
}
}

View file

@ -32,7 +32,7 @@ import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
import org.yaml.snakeyaml.Yaml;
public class BungeePluginManager extends AbstractPluginManager<Plugin> {
public class BungeePluginManager implements AbstractPluginManager<Plugin> {
private static final ProxyServer proxy = ProxyServer.getInstance();

View file

@ -1,12 +0,0 @@
package net.frankheijden.serverutils.bungee.utils;
import net.frankheijden.serverutils.bungee.entities.BungeeCommandSender;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.md_5.bungee.api.CommandSender;
public class BungeeUtils {
public static ServerCommandSender wrap(CommandSender sender) {
return new BungeeCommandSender(sender);
}
}

View file

@ -0,0 +1,13 @@
{
"plugins": {
"flags": {
"modules": {
"main": "modules",
"aliases": ["m"],
"permission": "serverutils.plugins.modules",
"description": "Displays the proxy modules.",
"display-in-help": true
}
}
}
}

View file

@ -0,0 +1 @@
{}

View file

@ -1,7 +0,0 @@
settings:
check-updates-boot: true
check-updates-login: false
download-updates-boot: false
download-updates-login: false
install-updates-boot: false
install-updates-login: false

View file

@ -0,0 +1 @@
{}

View file

@ -1,61 +0,0 @@
serverutils:
success: "&3Successfully %action%ed &b%what%&3!"
warning: "&3Successfully %action%ed &b%what%&3, but with warnings."
error: "&cAn error occurred while %action%ing &4%what%&c, please check the console!"
not_exists: "&cAn error occurred while %action%ing &4%what%&c, plugin does not exist!"
not_enabled: "&cAn error occurred while %action%ing &4%what%&c, plugin is not enabled!"
already_loaded: "&cAn error occurred while %action%ing &4%what%&c, plugin is already loaded!"
already_enabled: "&cAn error occurred while %action%ing &4%what%&c, plugin is already enabled!"
already_disabled: "&cAn error occurred while %action%ing &4%what%&c, plugin is already disabled!"
file_deleted: "&cAccessing the jar file while %action%ing &4%what%&c went wrong, plugin has been deleted!"
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=----------
&3Current version: &b%old%
&3New version: &b%new%
&3Release info: &b%info%
&8&m-------------------------------------------------
downloading: |-
&8&m---------=&r&8[ &b&lServerUtils Bungee Update&r &8]&m=----------
&3A new version of ServerUtils will be downloaded and installed after a restart!
&3Current version: &b%old%
&3New version: &b%new%
&3Release info: &b%info%
&8&m-------------------------------------------------
download_failed: "&cFailed to download version %new% of ServerUtils. Please update manually."
download_success: "&3ServerUtils has been downloaded and will be installed on the next restart."
help:
header: "&8&m----------=&r&8[ &b&lServerUtils Bungee Help&r &8]&m=----------"
format: "&8/&3%command%&b%subcommand% &f(&7%help%&f)"
footer: "&8&m-------------------------------------------------"
plugins:
header: "&8&m---------=&r&8[ &b&lServerUtils Bungee Plugins&r &8]&m=--------"
prefix: " &3Plugins &8(&a%count%&8)&b: "
format: "&3%plugin%"
seperator: "&b, "
last_seperator: " &band "
version: " &8(&a%version%&8)"
footer: "&8&m-------------------------------------------------"
plugininfo:
header: "&8&m-------=&r&8[ &b&lServerUtils Bungee PluginInfo&r &8]&m=-------"
format: " &3%key%&8: &b%value%"
list_format: "&b%value%"
seperator: "&8, "
last_seperator: " &8and "
footer: "&8&m-------------------------------------------------"
commandinfo:
header: "&8&m------=&r&8[ &b&lServerUtils Bungee CommandInfo&r &8]&m=-------"
format: " &3%key%&8: &b%value%"
list_format: "&b%value%"
seperator: "&8, "
last_seperator: " &8and "
footer: "&8&m-------------------------------------------------"
not_exists: "&cThat command is not a valid registered command."

View file

@ -1,4 +1,4 @@
name: ServerUtils
main: net.frankheijden.serverutils.bungee.ServerUtils
version: ${version}
author: FrankHeijden
author: FrankHeijden

View file

@ -3,6 +3,7 @@ plugins {
}
group = rootProject.group + '.common'
String dependencyDir = group + '.dependencies'
version = rootProject.version
archivesBaseName = rootProject.name + '-Common'
@ -11,8 +12,8 @@ repositories {
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
compileOnly 'com.github.FrankHeijden:ServerUtilsUpdater:v1.0.0'
compileOnly 'com.google.code.gson:gson:2.8.6'
}
blossom {
@ -24,4 +25,5 @@ shadowJar {
exclude 'net/frankheijden/serverutilsupdater/**'
exclude 'plugin.yml'
exclude 'bungee.yml'
relocate 'com.google.gson', dependencyDir + '.gson'
}

View file

@ -0,0 +1,46 @@
package net.frankheijden.serverutils.common.commands;
import cloud.commandframework.context.CommandContext;
import java.util.List;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
public abstract class CommandPlugins<
U extends ServerUtilsPlugin<P, T, C, S>,
P,
T,
C extends ServerCommandSender<S>,
S
> extends ServerUtilsCommand<U, P, T, C, S> {
protected CommandPlugins(U plugin) {
super(plugin, "plugins");
}
protected abstract void handlePlugins(CommandContext<C> context);
/**
* Sends a plugin list to the receiver.
* @param sender The receiver of the plugin list.
* @param plugins The plugins to be sent.
* @param pluginFormat The format of the plugins to be sent.
* @param <T> The plugin type.
*/
protected void handlePlugins(C sender, List<P> plugins, ListFormat<P> pluginFormat) {
String prefix = plugin.getMessagesResource().getMessage(
"serverutils.plugins.prefix",
"%count%", String.valueOf(plugins.size())
);
if (prefix == null) prefix = "";
plugin.getMessagesResource().sendMessage(sender, "serverutils.plugins.header");
sender.sendMessage(plugin.getChatProvider().color(prefix + ListBuilder.create(plugins)
.seperator(plugin.getMessagesResource().getMessage("serverutils.plugins.seperator"))
.lastSeperator(plugin.getMessagesResource().getMessage("serverutils.plugins.last_seperator"))
.format(pluginFormat)
.toString()));
plugin.getMessagesResource().sendMessage(sender, "serverutils.plugins.footer");
}
}

View file

@ -0,0 +1,240 @@
package net.frankheijden.serverutils.common.commands;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.context.CommandContext;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
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.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
public abstract class CommandServerUtils<
U extends ServerUtilsPlugin<P, T, C, S>,
P,
T,
C extends ServerCommandSender<S>,
S
> extends ServerUtilsCommand<U, P, T, C, S> {
protected CommandServerUtils(
U plugin
) {
super(plugin, "serverutils");
}
@Override
public void register(CommandManager<C> manager, Command.Builder<C> builder) {
final List<String> pluginFileNames = plugin.getPluginManager().getPluginFileNames();
addArgument(CommandArgument.<C, String>ofType(String.class, "jarFile")
.manager(manager)
.withSuggestionsProvider((context, s) -> pluginFileNames)
.build());
final List<String> pluginNames = plugin.getPluginManager().getPluginNames();
addArgument(CommandArgument.<C, String>ofType(String.class, "plugin")
.manager(manager)
.withSuggestionsProvider((context, s) -> pluginNames)
.build());
final List<String> commandNames = new ArrayList<>(plugin.getPluginManager().getCommands());
addArgument(CommandArgument.<C, String>ofType(String.class, "command")
.manager(manager)
.withSuggestionsProvider((context, s) -> commandNames)
.build());
manager.command(builder
.handler(this::handleHelpCommand));
manager.command(parseSubcommand(builder, "help")
.handler(this::handleHelpCommand));
manager.command(parseSubcommand(builder, "reload")
.handler(this::handleReload));
manager.command(parseSubcommand(builder, "loadplugin")
.argument(getArgument("jarFile"))
.handler(this::handleLoadPlugin));
manager.command(parseSubcommand(builder, "unloadplugin")
.argument(getArgument("plugin"))
.handler(this::handleUnloadPlugin));
manager.command(parseSubcommand(builder, "reloadplugin")
.argument(getArgument("plugin"))
.handler(this::handleReloadPlugin));
manager.command(parseSubcommand(builder, "watchplugin")
.argument(getArgument("plugin"))
.handler(this::handleWatchPlugin));
manager.command(parseSubcommand(builder, "unwatchplugin")
.argument(getArgument("plugin"))
.handler(this::handleUnwatchPlugin));
manager.command(parseSubcommand(builder, "plugininfo")
.argument(getArgument("plugin"))
.handler(this::handlePluginInfo));
manager.command(parseSubcommand(builder, "commandinfo")
.argument(getArgument("command"))
.handler(this::handleCommandInfo));
}
private void handleHelpCommand(CommandContext<C> context) {
C sender = context.getSender();
plugin.getMessagesResource().sendMessage(sender, "serverutils.help.header");
FormatBuilder builder = FormatBuilder.create(plugin.getMessagesResource().getMessage("serverutils.help.format"))
.orderedKeys("%command%", "%subcommand%", "%help%");
for (Command<C> command : plugin.getCommands()) {
List<CommandArgument<C, ?>> arguments = command.getArguments();
if (arguments.size() < 2) continue;
String commandName = arguments.get(0).getName();
StringBuilder sb = new StringBuilder();
for (int i = 1; i < arguments.size(); i++) {
CommandArgument<C, ?> argument = arguments.get(i);
sb.append(" ").append(argument.getName());
}
String subcommand = sb.toString();
String description = command.getComponents().get(1).getArgumentDescription().getDescription();
builder.add(commandName, subcommand, description);
}
builder.build().forEach(msg -> plugin.getMessagesResource().sendRawMessage(sender, msg));
plugin.getMessagesResource().sendMessage(sender, "serverutils.help.footer");
}
private void handleReload(CommandContext<C> context) {
C sender = context.getSender();
plugin.reload();
plugin.getMessagesResource().sendMessage(sender, "serverutils.success",
"%action%", "reload",
"%what%", "ServerUtils configurations");
}
private void handleLoadPlugin(CommandContext<C> context) {
C sender = context.getSender();
String jarFile = context.get("jarFile");
AbstractPluginManager<P> pluginManager = plugin.getPluginManager();
LoadResult<P> loadResult = pluginManager.loadPlugin(jarFile);
if (!loadResult.isSuccess()) {
loadResult.getResult().sendTo(sender, "load", jarFile);
return;
}
P loadedPlugin = loadResult.get();
Result result = pluginManager.enablePlugin(loadedPlugin);
result.sendTo(sender, "load", pluginManager.getPluginName(loadedPlugin));
}
private void handleUnloadPlugin(CommandContext<C> context) {
C sender = context.getSender();
String pluginName = context.get("plugin");
CloseableResult result = plugin.getPluginManager().unloadPlugin(pluginName);
result.getResult().sendTo(sender, "unload", pluginName);
result.tryClose();
}
private void handleReloadPlugin(CommandContext<C> context) {
C sender = context.getSender();
String pluginName = context.get("plugin");
Result result = plugin.getPluginManager().reloadPlugin(pluginName);
result.sendTo(sender, "reload", pluginName);
}
private void handleWatchPlugin(CommandContext<C> context) {
C sender = context.getSender();
String pluginName = context.get("plugin");
AbstractResult result = plugin.getPluginManager().watchPlugin(sender, pluginName);
result.sendTo(sender, "watch", pluginName);
}
private void handleUnwatchPlugin(CommandContext<C> context) {
C sender = context.getSender();
String pluginName = context.get("plugin");
AbstractResult result = plugin.getPluginManager().unwatchPlugin(pluginName);
result.sendTo(sender, "unwatch", pluginName);
}
private void handlePluginInfo(CommandContext<C> context) {
C sender = context.getSender();
String pluginName = context.get("plugin");
if (this.plugin.getPluginManager().getPlugin(pluginName) == null) {
Result.NOT_EXISTS.sendTo(sender, "fetch", pluginName);
return;
}
createInfo(sender, "plugininfo", pluginName, this::createPluginInfo);
}
protected abstract FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String pluginName
);
private void handleCommandInfo(CommandContext<C> context) {
C sender = context.getSender();
String commandName = context.get("command");
if (!plugin.getPluginManager().getCommands().contains(commandName)) {
plugin.getMessagesResource().sendMessage(sender, "serverutils.commandinfo.not_exists");
return;
}
createInfo(sender, "commandinfo", commandName, this::createCommandInfo);
}
protected abstract FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String commandName
);
private void createInfo(C sender, String command, String item, InfoCreator creator) {
String messagePrefix = "serverutils." + command;
String format = plugin.getMessagesResource().getMessage(messagePrefix + ".format");
String listFormatString = plugin.getMessagesResource().getMessage(messagePrefix + ".list_format");
String seperator = plugin.getMessagesResource().getMessage(messagePrefix + ".seperator");
String lastSeperator = plugin.getMessagesResource().getMessage(messagePrefix + ".last_seperator");
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
plugin.getMessagesResource().sendMessage(sender, messagePrefix + ".header");
creator.createInfo(
FormatBuilder
.create(format)
.orderedKeys("%key%", "%value%"),
listBuilderConsumer -> {
ListBuilder<String> builder = ListBuilder.<String>create()
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator);
listBuilderConsumer.accept(builder);
return builder.toString();
},
item
).build().forEach(str -> plugin.getMessagesResource().sendRawMessage(sender, str));
plugin.getMessagesResource().sendMessage(sender, messagePrefix + ".footer");
}
private interface InfoCreator {
FormatBuilder createInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String item
);
}
}

View file

@ -1,33 +0,0 @@
package net.frankheijden.serverutils.common.commands;
import java.util.List;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
/**
* Provides some common utility methods for the Plugins command.
*/
public class Plugins {
/**
* Sends a plugin list to the receiver.
* @param sender The receiver of the plugin list.
* @param plugins The plugins to be sent.
* @param pluginFormat The format of the plugins to be sent.
* @param <T> The plugin type.
*/
public static <T> void sendPlugins(ServerCommandSender sender, List<T> plugins, ListFormat<T> pluginFormat) {
Messenger.sendMessage(sender, "serverutils.plugins.header");
String prefix = Messenger.getMessage("serverutils.plugins.prefix",
"%count%", String.valueOf(plugins.size()));
if (prefix == null) prefix = "";
sender.sendMessage(Messenger.color(prefix + ListBuilder.create(plugins)
.seperator(Messenger.getMessage("serverutils.plugins.seperator"))
.lastSeperator(Messenger.getMessage("serverutils.plugins.last_seperator"))
.format(pluginFormat)
.toString()));
Messenger.sendMessage(sender, "serverutils.plugins.footer");
}
}

View file

@ -0,0 +1,106 @@
package net.frankheijden.serverutils.common.commands;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.flags.CommandFlag;
import cloud.commandframework.permission.Permission;
import java.util.HashMap;
import java.util.Map;
import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public abstract class ServerUtilsCommand<U extends ServerUtilsPlugin<P, T, C, S>,
P,
T,
C extends ServerCommandSender<S>,
S
> {
protected final U plugin;
protected final String commandName;
protected final ServerUtilsConfig commandConfig;
protected final Map<String, CommandArgument<C, ?>> arguments;
protected ServerUtilsCommand(
U plugin,
String commandName
) {
this.plugin = plugin;
this.commandName = commandName;
this.commandConfig = (ServerUtilsConfig) plugin.getCommandsResource().getConfig().get(commandName);
this.arguments = new HashMap<>();
}
/**
* Registers commands with the given CommandManager.
*/
public final void register(CommandManager<C> manager) {
register(
manager,
manager.commandBuilder(
applyPrefix(commandConfig.getString("main")),
commandConfig.getStringList("aliases").stream()
.map(this::applyPrefix)
.toArray(String[]::new)
).permission(commandConfig.getString("permission"))
);
}
protected abstract void register(CommandManager<C> manager, Command.Builder<C> builder);
public <A> void addArgument(CommandArgument<C, A> argument) {
this.arguments.put(argument.getName(), argument);
}
public CommandArgument<C, ?> getArgument(String name) {
return this.arguments.get(name).copy();
}
/**
* Parses a subcommand from the config.
*/
public Command.Builder<C> parseSubcommand(Command.Builder<C> builder, String subcommand) {
ServerUtilsConfig subcommandConfig = (ServerUtilsConfig) commandConfig.get("subcommands." + subcommand);
return builder
.literal(
subcommandConfig.getString("main"),
ArgumentDescription.of(subcommandConfig.getString("description")),
subcommandConfig.getStringList("aliases").toArray(new String[0])
)
.permission(subcommandConfig.getString("permission"));
}
/**
* Parses a flag from the config.
*/
public CommandFlag<Void> parseFlag(String flag) {
ServerUtilsConfig flagConfig = (ServerUtilsConfig) commandConfig.get("flags." + flag);
return CommandFlag.newBuilder(flagConfig.getString("main"))
.withAliases(flagConfig.getStringList("aliases").toArray(new String[0]))
.withPermission(Permission.of(flagConfig.getString("permission")))
.withDescription(ArgumentDescription.of(flagConfig.getString("description")))
.build();
}
private String applyPrefix(String str) {
final String prefixChar;
switch (plugin.getPlatform()) {
case BUKKIT:
prefixChar = "";
break;
case BUNGEE:
prefixChar = "b";
break;
case VELOCITY:
prefixChar = "v";
break;
default:
throw new IllegalArgumentException("Unknown platform: " + plugin.getPlatform().name());
}
return str.replace("%prefix%", prefixChar);
}
}

View file

@ -0,0 +1,15 @@
package net.frankheijden.serverutils.common.config;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
/**
* The Commands configuration.
*/
public class CommandsResource extends ServerUtilsResource {
private static final String COMMANDS_RESOURCE = "commands";
public CommandsResource(ServerUtilsPlugin<?, ?, ?, ?> plugin) {
super(plugin, COMMANDS_RESOURCE);
}
}

View file

@ -1,27 +0,0 @@
package net.frankheijden.serverutils.common.config;
/**
* The general common config class.
*/
public class Config extends ServerUtilsResource {
private static Config instance;
/**
* Constructs a new Config with the config file name and the resource name from the jar.
* @param fileName The file name in the data folder.
* @param resource The resource name in the jar file.
*/
public Config(String fileName, String resource) {
super(fileName, resource);
instance = this;
}
/**
* Retrieves the current instance of the Config.
* @return The current instance.
*/
public static Config getInstance() {
return instance;
}
}

View file

@ -0,0 +1,12 @@
package net.frankheijden.serverutils.common.config;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public class ConfigResource extends ServerUtilsResource {
private static final String CONFIG_RESOURCE = "config";
public ConfigResource(ServerUtilsPlugin<?, ?, ?, ?> plugin) {
super(plugin, CONFIG_RESOURCE);
}
}

View file

@ -0,0 +1,154 @@
package net.frankheijden.serverutils.common.config;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class JsonConfig implements ServerUtilsConfig {
protected static final Gson gson = new Gson();
private final JsonObject config;
private File file = null;
public JsonConfig(File file) throws IOException {
this.config = gson.fromJson(Files.newBufferedReader(file.toPath()), JsonObject.class);
this.file = file;
}
public JsonConfig(JsonObject config) {
this.config = config;
}
public JsonObject getConfig() {
return config;
}
private JsonElement getJsonElement(String path) {
JsonElement result = config;
for (String memberName : path.split("\\.")) {
if (result == null) return null;
result = result.getAsJsonObject().get(memberName);
}
return result;
}
/**
* Parses a json element as a java object. Supported constructs are:
* - Primitives (bool, number, string).
* - Simple string lists.
*/
public static Object toObjectValue(JsonElement jsonElement) {
if (jsonElement == null) return null;
if (jsonElement.isJsonPrimitive()) {
JsonPrimitive jsonPrimitive = (JsonPrimitive) jsonElement;
if (jsonPrimitive.isBoolean()) return jsonPrimitive.getAsBoolean();
else if (jsonPrimitive.isNumber()) return jsonPrimitive.getAsNumber();
else if (jsonPrimitive.isString()) return jsonPrimitive.getAsString();
else {
throw new IllegalStateException("Not a JSON Primitive: " + jsonPrimitive);
}
} else if (jsonElement.isJsonArray()) {
JsonArray jsonArray = (JsonArray) jsonElement;
List<String> stringList = new ArrayList<>(jsonArray.size());
for (JsonElement childJsonElement : jsonArray) {
stringList.add(toObjectValue(childJsonElement).toString());
}
return stringList;
}
return null;
}
@Override
public Object get(String path) {
JsonElement result = getJsonElement(path);
if (result != null && result.isJsonObject()) {
return new JsonConfig(result.getAsJsonObject());
}
return result;
}
@Override
public List<String> getStringList(String path) {
Object obj = get(path);
if (!(obj instanceof JsonArray)) throw new IllegalStateException("Not a JSON Array: " + obj);
JsonArray jsonArray = (JsonArray) obj;
List<String> list = new ArrayList<>(jsonArray.size());
for (JsonElement jsonElement : jsonArray) {
list.add(jsonElement.getAsString());
}
return list;
}
@Override
public Map<String, Object> getMap(String path) {
return gson.fromJson(getJsonElement(path), new TypeToken<Map<String, Object>>() {}.getType());
}
@Override
public void set(String path, Object value) {
int lastDotIndex = path.lastIndexOf('.');
String memberName = path;
JsonObject jsonObject = config.getAsJsonObject();
if (lastDotIndex != -1) {
memberName = path.substring(lastDotIndex + 1);
for (String pathSection : path.substring(0, lastDotIndex).split("\\.")) {
JsonElement childMember = jsonObject.get(pathSection);
if (childMember == null) {
childMember = new JsonObject();
}
jsonObject.add(pathSection, childMember);
jsonObject = childMember.getAsJsonObject();
}
}
jsonObject.add(memberName, gson.toJsonTree(value));
}
@Override
public String getString(String path) {
JsonElement element = getJsonElement(path);
if (element == null) return null;
return element.getAsString();
}
@Override
public boolean getBoolean(String path) {
JsonElement element = getJsonElement(path);
if (element == null) return false;
return element.getAsBoolean();
}
@Override
public Collection<? extends String> getKeys() {
return config.keySet();
}
@Override
public void save() throws IOException {
Files.write(
file.toPath(),
gson.toJson(config).getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING
);
}
}

View file

@ -0,0 +1,56 @@
package net.frankheijden.serverutils.common.config;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.utils.StringUtils;
public class MessagesResource extends ServerUtilsResource {
public static final String MESSAGES_RESOURCE = "messages";
public MessagesResource(ServerUtilsPlugin<?, ?, ?, ?> plugin) {
super(plugin, MESSAGES_RESOURCE);
}
/**
* Retrieves a message from the config.
* @param path The yml path to the message.
* @param replacements The replacements to be taken into account.
* @return The config message with translated placeholders.
*/
public String getMessage(String path, String... replacements) {
String message = config.getString(path);
if (message != null) {
return StringUtils.apply(message, replacements);
} else {
plugin.getLogger().severe("Missing locale in messages.yml at path '" + path + "'!");
}
return null;
}
/**
* Sends a message to a player with translated placeholders.
* @param sender The receiver.
* @param msg The message to be sent.
* @param replacements The replacements to be taken into account.
*/
public void sendRawMessage(ServerCommandSender<?> sender, String msg, String... replacements) {
String message = StringUtils.apply(msg, replacements);
if (message != null) {
sender.sendMessage(plugin.getChatProvider().color(message));
}
}
/**
* Sends a message from the specified config path to a player with translated placeholders.
* @param sender The receiver.
* @param path The yml path to the message.
* @param replacements The replacements to be taken into account.
*/
public void sendMessage(ServerCommandSender<?> sender, String path, String... replacements) {
String message = getMessage(path, replacements);
if (message != null) {
sender.sendMessage(plugin.getChatProvider().color(message));
}
}
}

View file

@ -1,84 +0,0 @@
package net.frankheijden.serverutils.common.config;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.utils.StringUtils;
/**
* The general common messenger class.
*/
public class Messenger extends ServerUtilsResource {
private static Messenger instance;
private static final ServerUtilsPlugin plugin = ServerUtilsApp.getPlugin();
/**
* Constructs a new Messenger with the messages file name and the resource name from the jar.
* @param fileName The file name in the data folder.
* @param resource The resource name in the jar file.
*/
public Messenger(String fileName, String resource) {
super(fileName, resource);
instance = this;
}
/**
* Retrieves the current instance of the Messenger.
* @return The current instance.
*/
public static Messenger getInstance() {
return instance;
}
/**
* Retrieves a message from the config.
* @param path The yml path to the message.
* @param replacements The replacements to be taken into account.
* @return The config message with translated placeholders.
*/
public static String getMessage(String path, String... replacements) {
String message = instance.getConfig().getString(path);
if (message != null) {
return StringUtils.apply(message, replacements);
} else {
Messenger.plugin.getLogger().severe("Missing locale in messages.yml at path '" + path + "'!");
}
return null;
}
/**
* Sends a message to a player with translated placeholders.
* @param sender The receiver.
* @param msg The message to be sent.
* @param replacements The replacements to be taken into account.
*/
public static void sendRawMessage(ServerCommandSender sender, String msg, String... replacements) {
String message = StringUtils.apply(msg, replacements);
if (message != null) {
sender.sendMessage(Messenger.plugin.getChatProvider().color(message));
}
}
/**
* Sends a message from the specified config path to a player with translated placeholders.
* @param sender The receiver.
* @param path The yml path to the message.
* @param replacements The replacements to be taken into account.
*/
public static void sendMessage(ServerCommandSender sender, String path, String... replacements) {
String message = getMessage(path, replacements);
if (message != null) {
sender.sendMessage(Messenger.plugin.getChatProvider().color(message));
}
}
/**
* Colorizes the given string.
* @param str The string to color.
* @return The colored string.
*/
public static String color(String str) {
return Messenger.plugin.getChatProvider().color(str);
}
}

View file

@ -1,9 +1,18 @@
package net.frankheijden.serverutils.common.config;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.providers.ResourceProvider;
/**
* A wrap for a Configuration file.
@ -87,6 +96,9 @@ public interface ServerUtilsConfig {
if (value instanceof ServerUtilsConfig) {
addDefaults((ServerUtilsConfig) value, conf, newKey);
} else if (conf.get(newKey) == null) {
if (value instanceof JsonElement) {
value = JsonConfig.toObjectValue((JsonElement) value);
}
conf.set(newKey, value);
}
}
@ -132,4 +144,38 @@ public interface ServerUtilsConfig {
}
return conf;
}
/**
* Loads a resource from the jar file.
*/
static <U extends ServerUtilsPlugin<P, T, C, S>, P, T, C extends ServerCommandSender<S>, S> ServerUtilsConfig load(
U plugin,
Path path,
String resource
) {
ResourceProvider provider = plugin.getResourceProvider();
// Create the platform JsonConfig by merging the platformResource with the common resource
JsonConfig generalConfig = new JsonConfig(JsonConfig.gson.fromJson(
new InputStreamReader(provider.getRawResource(resource + ".json")),
JsonObject.class
));
String platformResource = plugin.getPlatform().name().toLowerCase(Locale.ENGLISH) + '-' + resource;
JsonConfig platformConfig = new JsonConfig(JsonConfig.gson.fromJson(
new InputStreamReader(provider.getRawResource(platformResource + ".json")),
JsonObject.class
));
addDefaults(platformConfig, generalConfig);
if (!Files.exists(path)) {
try {
Files.createFile(path);
} catch (IOException ex) {
ex.printStackTrace();
}
}
return init(generalConfig, provider.load(path.toFile()));
}
}

View file

@ -1,37 +1,30 @@
package net.frankheijden.serverutils.common.config;
import java.io.File;
import java.io.InputStream;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.providers.ResourceProvider;
/**
* A class which provides functionality for loading and setting defaults of Configurations.
*/
public class ServerUtilsResource {
private static final ServerUtilsPlugin plugin = ServerUtilsApp.getPlugin();
protected final ServerUtilsPlugin<?, ?, ?, ?> plugin;
protected final ServerUtilsConfig config;
private final ServerUtilsConfig config;
/**
* Creates a new YamlResource instance.
* Loads the resource from the jar file.
* @param fileName The destination file.
* @param resource The resource from the jar file.
*/
public ServerUtilsResource(String fileName, String resource) {
ResourceProvider provider = plugin.getResourceProvider();
InputStream is = provider.getResource(resource);
File file = plugin.copyResourceIfNotExists(fileName, resource);
config = ServerUtilsConfig.init(provider.load(is), provider.load(file));
protected ServerUtilsResource(ServerUtilsPlugin<?, ?, ?, ?> plugin, ServerUtilsConfig config) {
this.plugin = plugin;
this.config = config;
}
protected ServerUtilsResource(ServerUtilsPlugin<?, ?, ?, ?> plugin, String resourceName) {
this(
plugin,
ServerUtilsConfig.load(
plugin,
plugin.getDataFolder().toPath().resolve(
resourceName + plugin.getResourceProvider().getResourceExtension()
),
resourceName
)
);
}
/**
* Retrieves the YamlConfig of this resource.
* @return The YamlConfig.
*/
public ServerUtilsConfig getConfig() {
return config;
}

View file

@ -9,5 +9,5 @@ public interface AbstractResult {
* @param action The action which let to the result.
* @param what An associated variable.
*/
void sendTo(ServerCommandSender sender, String action, String what);
void sendTo(ServerCommandSender<?> sender, String action, String what);
}

View file

@ -1,6 +1,6 @@
package net.frankheijden.serverutils.common.entities;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.ServerUtilsApp;
/**
* An enum containing possible results.
@ -45,10 +45,13 @@ public enum Result implements AbstractResult {
* @param what An associated variable.
*/
@Override
public void sendTo(ServerCommandSender sender, String action, String what) {
Messenger.sendMessage(sender, "serverutils." + this.name().toLowerCase(),
public void sendTo(ServerCommandSender<?> sender, String action, String what) {
ServerUtilsApp.getPlugin().getMessagesResource().sendMessage(
sender,
"serverutils." + this.name().toLowerCase(),
"%action%", action,
"%what%", what,
"%arg%", arg);
"%arg%", arg
);
}
}

View file

@ -3,7 +3,7 @@ package net.frankheijden.serverutils.common.entities;
/**
* A basic wrapper for a CommandSender.
*/
public interface ServerCommandSender {
public interface ServerCommandSender<C> {
/**
* Sends a message to a CommandSender.
@ -23,4 +23,9 @@ public interface ServerCommandSender {
* @return Boolean true or false.
*/
boolean isPlayer();
/**
* Returns the server specific implementation source.
*/
C getSource();
}

View file

@ -1,8 +1,15 @@
package net.frankheijden.serverutils.common.entities;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.logging.Logger;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.CommandsResource;
import net.frankheijden.serverutils.common.config.ConfigResource;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
import net.frankheijden.serverutils.common.managers.AbstractTaskManager;
import net.frankheijden.serverutils.common.managers.UpdateManager;
@ -10,17 +17,35 @@ import net.frankheijden.serverutils.common.providers.ChatProvider;
import net.frankheijden.serverutils.common.providers.ResourceProvider;
import net.frankheijden.serverutils.common.utils.FileUtils;
public abstract class ServerUtilsPlugin {
public abstract class ServerUtilsPlugin<P, T, C extends ServerCommandSender<S>, S> {
private final UpdateManager updateManager = new UpdateManager();
private CommandsResource commandsResource;
private ConfigResource configResource;
private MessagesResource messagesResource;
protected CommandManager<C> commandManager;
public abstract <T> AbstractPluginManager<T> getPluginManager();
public abstract Platform getPlatform();
public abstract <T> AbstractTaskManager<T> getTaskManager();
public CommandsResource getCommandsResource() {
return commandsResource;
}
public ConfigResource getConfigResource() {
return configResource;
}
public MessagesResource getMessagesResource() {
return messagesResource;
}
public abstract AbstractPluginManager<P> getPluginManager();
public abstract AbstractTaskManager<T> getTaskManager();
public abstract ResourceProvider getResourceProvider();
public abstract ChatProvider getChatProvider();
public abstract ChatProvider<C, S> getChatProvider();
public UpdateManager getUpdateManager() {
return updateManager;
@ -30,7 +55,9 @@ public abstract class ServerUtilsPlugin {
public abstract File getDataFolder();
public abstract <T> T fetchUpdaterData();
public Collection<Command<C>> getCommands() {
return commandManager.getCommands();
}
public void createDataFolderIfNotExists() {
if (getDataFolder().exists()) return;
@ -58,11 +85,48 @@ public abstract class ServerUtilsPlugin {
return file;
}
public void enable() {
protected abstract CommandManager<C> newCommandManager();
/**
* Enables the plugin.
*/
public final void enable() {
reload();
enablePlugin();
ServerUtilsApp.tryCheckForUpdates();
}
protected void enablePlugin() {
}
public void disable() {
public final void disable() {
disablePlugin();
getTaskManager().cancelAllTasks();
}
protected void disablePlugin() {
}
/**
* Reloads the plugin's configurations.
*/
public final void reload() {
this.commandsResource = new CommandsResource(this);
this.configResource = new ConfigResource(this);
this.messagesResource = new MessagesResource(this);
this.commandManager = newCommandManager();
reloadPlugin();
}
protected void reloadPlugin() {
}
public enum Platform {
BUKKIT,
BUNGEE,
VELOCITY,
}
}

View file

@ -1,6 +1,6 @@
package net.frankheijden.serverutils.common.entities;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.ServerUtilsApp;
public enum WatchResult implements AbstractResult {
@ -17,8 +17,11 @@ public enum WatchResult implements AbstractResult {
* @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);
public void sendTo(ServerCommandSender<?> sender, String action, String what) {
ServerUtilsApp.getPlugin().getMessagesResource().sendMessage(
sender,
"serverutils.watcher." + this.name().toLowerCase(),
"%what%", what
);
}
}

View file

@ -1,15 +1,26 @@
package net.frankheijden.serverutils.common.listeners;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.tasks.UpdateCheckerTask;
public class ServerListener {
public abstract class ServerListener<
U extends ServerUtilsPlugin<P, T, C, S>,
P,
T,
C extends ServerCommandSender<S>,
S
> extends ServerUtilsListener<U, P, T, C, S> {
protected ServerListener(U plugin) {
super(plugin);
}
/**
* Handles the update check on the given ServerCommandSender.
* @param sender The sender which triggered the update.
*/
public static void handleUpdate(ServerCommandSender sender) {
protected void handleUpdate(C sender) {
if (sender.hasPermission("serverutils.notification.update")) {
UpdateCheckerTask.tryStart(sender, "login");
}

View file

@ -0,0 +1,19 @@
package net.frankheijden.serverutils.common.listeners;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public abstract class ServerUtilsListener<
U extends ServerUtilsPlugin<P, T, C, S>,
P,
T,
C extends ServerCommandSender<S>,
S
> {
protected final U plugin;
protected ServerUtilsListener(U plugin) {
this.plugin = plugin;
}
}

View file

@ -11,23 +11,23 @@ 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<T> extends PluginProvider<T> {
public interface AbstractPluginManager<P> extends PluginProvider<P> {
public abstract LoadResult<T> loadPlugin(String pluginFile);
LoadResult<P> loadPlugin(String pluginFile);
public abstract LoadResult<T> loadPlugin(File file);
LoadResult<P> loadPlugin(File file);
public abstract Result enablePlugin(T plugin);
Result enablePlugin(P plugin);
public abstract Result disablePlugin(T plugin);
Result disablePlugin(P plugin);
public abstract Result reloadPlugin(String pluginName);
Result reloadPlugin(String pluginName);
public abstract Result reloadPlugin(T plugin);
Result reloadPlugin(P plugin);
public abstract CloseableResult unloadPlugin(String pluginName);
CloseableResult unloadPlugin(String pluginName);
public abstract CloseableResult unloadPlugin(T plugin);
CloseableResult unloadPlugin(P plugin);
/**
* Starts watching the specified plugin for changes.
@ -35,7 +35,7 @@ public abstract class AbstractPluginManager<T> extends PluginProvider<T> {
* @param pluginName The plugin to watch.
* @return The result of the action.
*/
public AbstractResult watchPlugin(ServerCommandSender sender, String pluginName) {
default AbstractResult watchPlugin(ServerCommandSender<?> sender, String pluginName) {
if (getPlugin(pluginName) == null) return Result.NOT_EXISTS;
ServerUtilsApp.getPlugin().getTaskManager()
.runTaskAsynchronously(pluginName, new PluginWatcherTask(sender, pluginName));
@ -47,7 +47,7 @@ public abstract class AbstractPluginManager<T> extends PluginProvider<T> {
* @param pluginName The plugin to stop watching.
* @return The result of the action.
*/
public AbstractResult unwatchPlugin(String pluginName) {
default AbstractResult unwatchPlugin(String pluginName) {
if (ServerUtilsApp.getPlugin().getTaskManager().cancelTask(pluginName)) return WatchResult.STOPPED;
return WatchResult.NOT_WATCHING;
}

View file

@ -18,7 +18,7 @@ public abstract class AbstractTaskManager<T> {
*
* @param taskCloser The consumer which will close tasks.
*/
public AbstractTaskManager(Consumer<T> taskCloser) {
protected AbstractTaskManager(Consumer<T> taskCloser) {
this.taskCloser = taskCloser;
this.serverTasks = new ArrayList<>();
this.tasks = new HashMap<>();

View file

@ -5,25 +5,30 @@ import net.frankheijden.serverutils.common.entities.ServerCommandSender;
/**
* A basic chat provider class.
*/
public abstract class ChatProvider {
public interface ChatProvider<C extends ServerCommandSender<T>, T> {
/**
* Retrieves the console sender of a server instance.
* @return The console sender.
*/
public abstract ServerCommandSender getConsoleSender();
C getConsoleSender();
/**
* Converts the given source (specific to impl) to a ServerCommandSender.
*/
C get(T source);
/**
* Colorizes the given string.
* @param str The string to color.
* @return The colored string.
*/
public abstract String color(String str);
String color(String str);
/**
* Broadcasts a message over a server instance.
* @param permission The permission the receivers need to have.
* @param message The message to broadcast.
*/
public abstract void broadcast(String permission, String message);
void broadcast(String permission, String message);
}

View file

@ -8,30 +8,30 @@ import java.util.Set;
import java.util.stream.Collectors;
import net.frankheijden.serverutils.common.ServerUtilsApp;
public abstract class PluginProvider<T> {
public interface PluginProvider<P> {
public File getPluginsFolder() {
default File getPluginsFolder() {
return ServerUtilsApp.getPlugin().getDataFolder().getParentFile();
}
public abstract List<T> getPlugins();
List<P> getPlugins();
public abstract String getPluginName(T plugin);
String getPluginName(P plugin);
public abstract File getPluginFile(T plugin);
File getPluginFile(P plugin);
public abstract File getPluginFile(String pluginName);
File getPluginFile(String pluginName);
public abstract T getPlugin(String pluginName);
P getPlugin(String pluginName);
public abstract Set<String> getCommands();
Set<String> getCommands();
/**
* Retrieves a list of plugins, sorted by name.
* @return The list of plugins.
*/
public List<T> getPluginsSorted() {
List<T> plugins = getPlugins();
default List<P> getPluginsSorted() {
List<P> plugins = getPlugins();
plugins.sort(Comparator.comparing(this::getPluginName));
return plugins;
}
@ -40,7 +40,7 @@ public abstract class PluginProvider<T> {
* Retrieves a list of plugin names.
* @return The plugin names.
*/
public List<String> getPluginNames() {
default List<String> getPluginNames() {
return getPlugins().stream()
.map(this::getPluginName)
.collect(Collectors.toList());
@ -50,7 +50,7 @@ public abstract class PluginProvider<T> {
* Retrieves all files with a jar extension in the plugins/ folder and returns solely their name.
* @return An list of jar file names.
*/
public List<String> getPluginFileNames() {
default List<String> getPluginFileNames() {
return Arrays.stream(getPluginJars())
.map(File::getName)
.collect(Collectors.toList());
@ -60,7 +60,7 @@ public abstract class PluginProvider<T> {
* Retrieves all files with a jar extension in the plugins/ folder.
* @return An array of jar files.
*/
public File[] getPluginJars() {
default File[] getPluginJars() {
File parent = getPluginsFolder();
if (parent == null || !parent.exists()) return new File[0];
return parent.listFiles(f -> f.getName().endsWith(".jar"));

View file

@ -6,9 +6,15 @@ import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
public interface ResourceProvider {
InputStream getResource(String resource);
default InputStream getResource(String resource) {
return getRawResource(resource + getResourceExtension());
}
InputStream getRawResource(String resource);
ServerUtilsConfig load(InputStream is);
ServerUtilsConfig load(File file);
String getResourceExtension();
}

View file

@ -10,8 +10,6 @@ import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.Config;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
import net.frankheijden.serverutils.common.entities.LoadResult;
import net.frankheijden.serverutils.common.entities.Result;
@ -26,10 +24,11 @@ import net.frankheijden.serverutilsupdater.common.Updater;
public class UpdateCheckerTask implements Runnable {
private static final ServerUtilsPlugin plugin = ServerUtilsApp.getPlugin();
private static final ServerUtilsConfig config = Config.getInstance().getConfig();
@SuppressWarnings("unchecked")
private static final ServerUtilsPlugin<Object, ?, ?, ?> plugin = ServerUtilsApp.getPlugin();
private static final ServerUtilsConfig config = plugin.getConfigResource().getConfig();
private final ServerCommandSender sender;
private final ServerCommandSender<?> sender;
private final boolean download;
private final boolean install;
@ -53,7 +52,7 @@ public class UpdateCheckerTask implements Runnable {
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 UpdateCheckerTask(ServerCommandSender sender, boolean download, boolean install) {
private UpdateCheckerTask(ServerCommandSender<?> sender, boolean download, boolean install) {
this.sender = sender;
this.download = download;
this.install = install;
@ -63,7 +62,7 @@ public class UpdateCheckerTask implements Runnable {
* Checks for updates if enabled per config for the specific action.
* Action must be 'login' or 'boot'.
*/
public static void tryStart(ServerCommandSender sender, String action) {
public static void tryStart(ServerCommandSender<?> sender, String action) {
if (config.getBoolean("settings.check-updates-" + action)) {
start(sender, action);
}
@ -73,7 +72,7 @@ public class UpdateCheckerTask implements Runnable {
* Checks for updates and downloads/installs if configured.
* Action must be 'login' or 'boot'.
*/
public static void start(ServerCommandSender sender, String action) {
public static void start(ServerCommandSender<?> sender, String action) {
plugin.getTaskManager().runTaskAsynchronously(new UpdateCheckerTask(
sender,
config.getBoolean("settings.download-updates-" + action),
@ -113,7 +112,7 @@ public class UpdateCheckerTask implements Runnable {
GitHubAsset pluginAsset = GitHubAsset.from(pluginJson);
if (!download || pluginAsset == null) {
if (sender.isPlayer()) {
Messenger.sendMessage(sender, "serverutils.update.available",
plugin.getMessagesResource().sendMessage(sender, "serverutils.update.available",
"%old%", ServerUtilsApp.VERSION,
"%new%", githubVersion,
"%info%", body);
@ -123,7 +122,7 @@ public class UpdateCheckerTask implements Runnable {
plugin.getLogger().log(Level.INFO, DOWNLOAD_START, pluginAsset.getDownloadUrl());
if (sender.isPlayer()) {
Messenger.sendMessage(sender, "serverutils.update.downloading",
plugin.getMessagesResource().sendMessage(sender, "serverutils.update.downloading",
"%old%", ServerUtilsApp.VERSION,
"%new%", githubVersion,
"%info%", body);
@ -228,7 +227,7 @@ public class UpdateCheckerTask implements Runnable {
}
private void deletePlugin() {
plugin.getPluginManager().getPluginFile((Object) ServerUtilsApp.getPlatformPlugin()).delete();
plugin.getPluginManager().getPluginFile(ServerUtilsApp.getPlatformPlugin()).delete();
}
private void tryReloadPlugin(File pluginFile, File updaterFile) {
@ -254,7 +253,7 @@ public class UpdateCheckerTask implements Runnable {
private void broadcastDownloadStatus(String githubVersion, boolean isError) {
final String path = "serverutils.update." + (isError ? "failed" : "success");
String message = Messenger.getMessage(path, "%new%", githubVersion);
String message = plugin.getMessagesResource().getMessage(path, "%new%", githubVersion);
plugin.getChatProvider().broadcast("serverutils.notification.update", message);
}
}

View file

@ -2,21 +2,17 @@ package net.frankheijden.serverutils.common.utils;
import java.util.ArrayList;
import java.util.List;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
public class FormatBuilder {
private final String format;
private final List<String[]> valueList;
private String[] orderedKeys;
private boolean alwaysSend;
private FormatBuilder(String format) {
this.format = format;
this.valueList = new ArrayList<>();
this.orderedKeys = new String[0];
this.alwaysSend = false;
}
public static FormatBuilder create(String format) {
@ -33,25 +29,27 @@ public class FormatBuilder {
return this;
}
public FormatBuilder alwaysSend(boolean alwaysSend) {
this.alwaysSend = alwaysSend;
return this;
/**
* Builds the current FormatBuilder instance into a list of strings.
*/
public List<String> build() {
List<String> strings = new ArrayList<>();
for (String[] values : valueList) {
String str = format;
for (int i = 0; i < Math.min(values.length, orderedKeys.length); i++) {
String value = values[i];
if (value == null || value.isEmpty()) break;
str = str.replace(orderedKeys[i], value);
}
strings.add(str);
}
return strings;
}
/**
* Builds the format and sends it to the CommandSender.
* @param sender The receiver of the list.
*/
public void sendTo(ServerCommandSender sender) {
valueList.forEach(values -> {
int length = Math.min(values.length, orderedKeys.length);
String message = format;
for (int i = 0; i < length; i++) {
String value = values[i];
if ((value == null || value.isEmpty()) && !alwaysSend) return;
message = message.replace(orderedKeys[i], String.valueOf(value));
}
Messenger.sendRawMessage(sender, message);
});
@Override
public String toString() {
return build().toString();
}
}

View file

@ -12,21 +12,17 @@ public class ListBuilder<T> {
private String seperator;
private String lastSeperator;
private ListBuilder(List<T> list) {
this.list = list;
private ListBuilder() {
this.list = new ArrayList<>();
}
public static <T> ListBuilder<T> create(List<T> list) {
return new ListBuilder<>(list);
}
public static <T> ListBuilder<T> create(Collection<T> list) {
return new ListBuilder<>(new ArrayList<>(list));
public static <T> ListBuilder<T> create(Collection<? extends T> list) {
return new ListBuilder<T>().addAll(list);
}
@SafeVarargs
public static <T> ListBuilder<T> create(T... elements) {
return new ListBuilder<>(Arrays.asList(elements));
return new ListBuilder<T>().addAll(Arrays.asList(elements));
}
/**
@ -56,6 +52,11 @@ public class ListBuilder<T> {
return this;
}
public ListBuilder<T> addAll(Collection<? extends T> collection) {
this.list.addAll(collection);
return this;
}
@Override
public String toString() {
if (list.size() == 1) {

View file

@ -0,0 +1,88 @@
{
"plugins": {
"main": "%prefix%plugins",
"aliases": ["%prefix%pl"],
"permission": "serverutils.plugins",
"display-in-help": true,
"flags": {
"version": {
"main": "version",
"aliases": ["v"],
"permission": "serverutils.plugins.version",
"description": "Displays the plugin versions.",
"display-in-help": true
}
}
},
"serverutils": {
"main": "%prefix%serverutils",
"aliases": ["%prefix%su"],
"permission": "serverutils.help",
"display-in-help": false,
"subcommands": {
"help": {
"main": "help",
"aliases": [],
"permission": "serverutils.help",
"description": "Displays the help page.",
"display-in-help": true
},
"reload": {
"main": "reload",
"aliases": [],
"permission": "serverutils.reload",
"description": "Reloads the ServerUtils plugin.",
"display-in-help": true
},
"loadplugin": {
"main": "loadplugin",
"aliases": ["lp"],
"permission": "serverutils.loadplugin",
"description": "Loads the specified jar file as a plugin.",
"display-in-help": true
},
"unloadplugin": {
"main": "unloadplugin",
"aliases": ["up"],
"permission": "serverutils.unloadplugin",
"description": "Disables and unloads the specified plugin.",
"display-in-help": true
},
"reloadplugin": {
"main": "reloadplugin",
"aliases": ["rp"],
"permission": "serverutils.reloadplugin",
"description": "Reloads the specified plugin.",
"display-in-help": true
},
"watchplugin": {
"main": "watchplugin",
"aliases": ["wp"],
"permission": "serverutils.watchplugin",
"description": "Watches the specified plugin for changes.",
"display-in-help": true
},
"unwatchplugin": {
"main": "unwatchplugin",
"aliases": ["uwp"],
"permission": "serverutils.watchplugin",
"description": "Stops watching the specified plugin for changes.",
"display-in-help": true
},
"plugininfo": {
"main": "plugininfo",
"aliases": ["pi"],
"permission": "serverutils.plugininfo",
"description": "Shows information about the specified plugin.",
"display-in-help": true
},
"commandinfo": {
"main": "commandinfo",
"aliases": ["ci"],
"permission": "serverutils.commandinfo",
"description": "Shows information about the specified command.",
"display-in-help": true
}
}
}
}

View file

@ -0,0 +1,11 @@
{
"settings": {
"disable-plugins-command": false,
"check-updates-boot": true,
"check-updates-login": false,
"download-updates-boot": false,
"download-updates-login": false,
"install-updates-boot": false,
"install-updates-login": false
}
}

View file

@ -0,0 +1,60 @@
{
"serverutils": {
"success": "&3Successfully %action%ed &b%what%&3!",
"warning": "&3Successfully %action%ed &b%what%&3, but with warnings.",
"error": "&cAn error occurred while %action%ing &4%what%&c, please check the console!",
"not_exists": "&cAn error occurred while %action%ing &4%what%&c, plugin does not exist!",
"not_enabled": "&cAn error occurred while %action%ing &4%what%&c, plugin is not enabled!",
"already_loaded": "&cAn error occurred while %action%ing &4%what%&c, plugin is already loaded!",
"already_enabled": "&cAn error occurred while %action%ing &4%what%&c, plugin is already enabled!",
"already_disabled": "&cAn error occurred while %action%ing &4%what%&c, plugin is already disabled!",
"file_deleted": "&cAccessing the jar file while %action%ing &4%what%&c went wrong, plugin has been deleted!",
"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=--------------\n &3Current version: &b%old%\n &3New version: &b%new%\n &3Release info: &b%info%\n&8&m-------------------------------------------------",
"downloading": "&8&m------------=&r&8[ &b&lServerUtils Update&r &8]&m=--------------\n &3A new version of ServerUtils will be downloaded and installed after a restart!\n &3Current version: &b%old%\n &3New version: &b%new%\n &3Release info: &b%info%\n&8&m-------------------------------------------------",
"download_failed": "&cFailed to download version %new% of ServerUtils. Please update manually.",
"download_success": "&3ServerUtils has been downloaded and will be installed on the next restart."
},
"help": {
"header": "&8&m-------------=&r&8[ &b&lServerUtils Help&r &8]&m=---------------",
"format": "&8/&3%command%&b%subcommand% &f(&7%help%&f)",
"footer": "&8&m-------------------------------------------------"
},
"plugins": {
"header": "&8&m------------=&r&8[ &b&lServerUtils Plugins&r &8]&m=-------------",
"prefix": " &3Plugins &8(&a%count%&8)&b: ",
"format": "&3%plugin%",
"format_disabled": "&c%plugin%",
"seperator": "&b, ",
"last_seperator": " &band ",
"version": " &8(&a%version%&8)",
"footer": "&8&m-------------------------------------------------"
},
"plugininfo": {
"header": "&8&m-----------=&r&8[ &b&lServerUtils PluginInfo&r &8]&m=-----------",
"format": " &3%key%&8: &b%value%",
"list_format": "&b%value%",
"seperator": "&8, ",
"last_seperator": " &8and ",
"footer": "&8&m-------------------------------------------------"
},
"commandinfo": {
"header": "&8&m-----------=&r&8[ &b&lServerUtils CommandInfo&r &8]&m=----------",
"format": " &3%key%&8: &b%value%",
"list_format": "&b%value%",
"seperator": "&8, ",
"last_seperator": " &8and ",
"footer": "&8&m-------------------------------------------------",
"not_exists": "&cThat command is not a valid registered command."
}
}
}

View file

@ -13,7 +13,7 @@ repositories {
}
dependencies {
implementation 'com.github.AlexProgrammerDE.commands:acf-velocity:b0792607db'
implementation 'com.github.FrankHeijden.cloud:cloud-velocity:fea4605277'
implementation 'org.bstats:bstats-velocity:2.2.1'
implementation project(":Common")
compileOnly 'com.velocitypowered:velocity-api:3.0.0'
@ -24,8 +24,6 @@ dependencies {
shadowJar {
relocate 'org.bstats', dependencyDir + '.bstats'
relocate 'co.aikar.commands', dependencyDir + '.acf'
relocate 'co.aikar.locales', dependencyDir + '.locales'
}
blossom {

View file

@ -1,8 +1,5 @@
package net.frankheijden.serverutils.velocity;
import co.aikar.commands.CommandCompletions;
import co.aikar.commands.VelocityCommandCompletionContext;
import co.aikar.commands.VelocityCommandManager;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.velocitypowered.api.event.Subscribe;
@ -15,13 +12,8 @@ import com.velocitypowered.api.proxy.ProxyServer;
import java.io.IOException;
import java.nio.file.Path;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.Config;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.velocity.commands.CommandPlugins;
import net.frankheijden.serverutils.velocity.commands.CommandServerUtils;
import net.frankheijden.serverutils.velocity.entities.VelocityPlugin;
import net.frankheijden.serverutils.velocity.managers.VelocityPluginCommandManager;
import net.frankheijden.serverutils.velocity.managers.VelocityPluginManager;
import net.frankheijden.serverutils.velocity.reflection.RVelocityCommandManager;
import org.bstats.velocity.Metrics;
import org.slf4j.Logger;
@ -37,12 +29,9 @@ import org.slf4j.Logger;
public class ServerUtils {
private static ServerUtils instance;
private static final String CONFIG_RESOURCE = "velocity-config.toml";
private static final String MESSAGES_RESOURCE = "velocity-messages.toml";
private static final String PLUGIN_COMMANDS_CACHE = ".pluginCommandsCache.json";
private VelocityPlugin plugin;
private VelocityCommandManager commandManager;
@Inject
private ProxyServer proxy;
@ -95,21 +84,7 @@ public class ServerUtils {
ServerUtilsApp.init(this, plugin);
metricsFactory.make(this, ServerUtilsApp.BSTATS_METRICS_ID);
this.commandManager = new VelocityCommandManager(proxy, this);
commandManager.registerCommand(new CommandPlugins());
commandManager.registerCommand(new CommandServerUtils(this));
VelocityPluginManager manager = plugin.getPluginManager();
CommandCompletions<VelocityCommandCompletionContext> completions = commandManager.getCommandCompletions();
completions.registerAsyncCompletion("plugins", context -> manager.getPluginNames());
completions.registerAsyncCompletion("pluginJars", context -> manager.getPluginFileNames());
completions.registerAsyncCompletion("commands", context -> manager.getCommands());
reload();
plugin.enable();
ServerUtilsApp.tryCheckForUpdates();
}
/**
@ -140,20 +115,15 @@ public class ServerUtils {
return dataDirectory;
}
public VelocityCommandManager getCommandManager() {
return commandManager;
}
public VelocityPlugin getPlugin() {
return plugin;
}
public PluginContainer getPluginContainer() {
return pluginContainer;
}
public VelocityPluginCommandManager getPluginCommandManager() {
return pluginCommandManager;
}
public void reload() {
new Config("config.toml", CONFIG_RESOURCE);
new Messenger("messages.toml", MESSAGES_RESOURCE);
}
}

View file

@ -1,46 +0,0 @@
package net.frankheijden.serverutils.velocity.commands;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Description;
import com.velocitypowered.api.command.CommandSource;
import net.frankheijden.serverutils.common.commands.Plugins;
import net.frankheijden.serverutils.common.config.Messenger;
import net.frankheijden.serverutils.velocity.managers.VelocityPluginManager;
import net.frankheijden.serverutils.velocity.utils.VelocityUtils;
@CommandAlias("vpl|vplugins|velocitypl")
public class CommandPlugins extends BaseCommand {
private static final VelocityPluginManager manager = VelocityPluginManager.get();
/**
* Sends the plugin list to the sender.
* The `-v` flag will output the plugins with version.
* The `-m` flag will also output modules in the plugin list.
* @param sender The sender of the command.
*/
@Default
@CommandCompletion("-v")
@CommandPermission("serverutils.plugins")
@Description("Shows the plugins of this proxy.")
public void onPlugins(CommandSource sender, String... args) {
boolean version = contains(args, "-v");
Plugins.sendPlugins(VelocityUtils.wrap(sender), manager.getPluginsSorted(), pl -> {
String ver = version ? Messenger.getMessage("serverutils.plugins.version",
"%version%", pl.getDescription().getVersion().orElse("<UNKNOWN>")) : "";
return Messenger.getMessage("serverutils.plugins.format",
"%plugin%", pl.getDescription().getId()) + ver;
});
}
private static boolean contains(String[] arr, String val) {
for (String s : arr) {
if (s.equalsIgnoreCase(val)) return true;
}
return false;
}
}

View file

@ -1,275 +0,0 @@
package net.frankheijden.serverutils.velocity.commands;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.RegisteredCommand;
import co.aikar.commands.RootCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
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;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.HexUtils;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
import net.frankheijden.serverutils.velocity.ServerUtils;
import net.frankheijden.serverutils.velocity.entities.VelocityLoadResult;
import net.frankheijden.serverutils.velocity.reflection.RVelocityCommandManager;
import net.frankheijden.serverutils.velocity.utils.VelocityUtils;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@CommandAlias("vsu|vserverutils")
public class CommandServerUtils extends BaseCommand {
private static final Set<String> ALIASES;
static {
ALIASES = new HashSet<>();
ALIASES.add("vserverutils");
ALIASES.add("vplugins");
ALIASES.add("velocitypl");
}
private final ServerUtils plugin;
public CommandServerUtils(ServerUtils plugin) {
this.plugin = plugin;
}
/**
* Shows the help page to the sender.
* @param source The sender of the command.
*/
@Default
@Subcommand("help")
@CommandPermission("serverutils.help")
@Description("Shows a help page with a few commands.")
public void onHelp(CommandSource source) {
ServerCommandSender sender = VelocityUtils.wrap(source);
Messenger.sendMessage(sender, "serverutils.help.header");
FormatBuilder builder = FormatBuilder.create(Messenger.getMessage("serverutils.help.format"))
.orderedKeys("%command%", "%subcommand%", "%help%");
Set<String> rootCommands = new HashSet<>();
for (RootCommand root : plugin.getCommandManager().getRegisteredRootCommands()) {
String rootName = root.getDefCommand().getName();
if (!rootCommands.add(rootName)) continue;
builder.add(rootName, "", root.getDescription());
Set<String> subCommands = new HashSet<>();
for (RegisteredCommand<?> sub : root.getSubCommands().values()) {
String name = sub.getPrefSubCommand().toLowerCase();
if (name.isEmpty()) continue;
if (!subCommands.add(name)) continue;
builder.add(rootName, " " + name, sub.getHelpText());
}
}
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.help.footer");
}
/**
* Reloads the configurations of ServerUtils.
* @param sender The sender of the command.
*/
@Subcommand("reload")
@CommandPermission("serverutils.reload")
@Description("Reloads the ServerUtils plugin.")
public void onReload(CommandSource sender) {
plugin.reload();
Messenger.sendMessage(VelocityUtils.wrap(sender), "serverutils.success",
"%action%", "reload",
"%what%", "ServerUtils Bungee configurations");
}
/**
* Loads the specified plugin on the proxy.
* @param source The sender of the command.
* @param jarFile The filename of the plugin in the plugins/ directory.
*/
@Subcommand("loadplugin|lp")
@CommandCompletion("@pluginJars")
@CommandPermission("serverutils.loadplugin")
@Description("Loads the specified jar file as a plugin.")
public void onLoadPlugin(CommandSource source, String jarFile) {
ServerCommandSender sender = VelocityUtils.wrap(source);
VelocityLoadResult loadResult = plugin.getPlugin().getPluginManager().loadPlugin(jarFile);
if (!loadResult.isSuccess()) {
loadResult.getResult().sendTo(sender, "load", jarFile);
return;
}
PluginContainer container = loadResult.get();
Result result = plugin.getPlugin().getPluginManager().enablePlugin(container);
result.sendTo(sender, "load", container.getDescription().getId());
}
/**
* Unloads the specified plugin from the proxy.
* @param source The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("unloadplugin|up")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.unloadplugin")
@Description("Disables and unloads the specified plugin.")
public void onUnloadPlugin(CommandSource source, String pluginName) {
CloseableResult result = plugin.getPlugin().getPluginManager().unloadPlugin(pluginName);
result.getResult().sendTo(VelocityUtils.wrap(source), "unload", pluginName);
result.tryClose();
}
/**
* Reloads the specified plugin on the proxy.
* @param sender The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("reloadplugin|rp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.reloadplugin")
@Description("Reloads a specified plugin.")
public void onReloadPlugin(CommandSource sender, String pluginName) {
// Wacky method to have the resources needed for the reload in memory, in case of a self reload.
HexUtils utils = new HexUtils();
Map<String, Object> section = Messenger.getInstance().getConfig().getMap("serverutils");
String result = plugin.getPlugin().getPluginManager().reloadPlugin(pluginName).toString();
String msg = (String) section.get(result.toLowerCase());
if (msg != null && !msg.isEmpty()) {
sender.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(utils.convertHexString(
msg.replace("%action%", "reload").replace("%what%", pluginName))));
}
}
/**
* Watches the given plugin and reloads it when a change is detected to the file.
* @param source The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("watchplugin|wp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.watchplugin")
@Description("Watches the specified plugin for changes.")
public void onWatchPlugin(CommandSource source, String pluginName) {
ServerCommandSender sender = VelocityUtils.wrap(source);
AbstractResult result = plugin.getPlugin().getPluginManager().watchPlugin(sender, pluginName);
result.sendTo(sender, "watch", pluginName);
}
/**
* Stops watching the given plugin.
* @param source The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("unwatchplugin|uwp")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.watchplugin")
@Description("Stops watching the specified plugin for changes.")
public void onUnwatchPlugin(CommandSource source, String pluginName) {
AbstractResult result = plugin.getPlugin().getPluginManager().unwatchPlugin(pluginName);
result.sendTo(VelocityUtils.wrap(source), "unwatch", pluginName);
}
/**
* Shows information about the specified plugin.
* @param source The sender of the command.
* @param pluginName The plugin name.
*/
@Subcommand("plugininfo|pi")
@CommandCompletion("@plugins")
@CommandPermission("serverutils.plugininfo")
@Description("Shows information about the specified plugin.")
public void onPluginInfo(CommandSource source, String pluginName) {
ServerCommandSender sender = VelocityUtils.wrap(source);
Optional<PluginContainer> container = plugin.getProxy().getPluginManager().getPlugin(pluginName);
if (!container.isPresent()) {
Result.NOT_EXISTS.sendTo(sender, "fetch", pluginName);
return;
}
PluginDescription desc = container.get().getDescription();
String format = Messenger.getMessage("serverutils.plugininfo.format");
String listFormatString = Messenger.getMessage("serverutils.plugininfo.list_format");
String seperator = Messenger.getMessage("serverutils.plugininfo.seperator");
String lastSeperator = Messenger.getMessage("serverutils.plugininfo.last_seperator");
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
Messenger.sendMessage(sender, "serverutils.plugininfo.header");
FormatBuilder builder = FormatBuilder.create(format)
.orderedKeys("%key%", "%value%")
.add("Id", desc.getId())
.add("Name", desc.getName().orElse(null))
.add("Version", desc.getVersion().orElse("<UNKNOWN>"))
.add("Author" + (desc.getAuthors().size() == 1 ? "" : "s"), ListBuilder.create(desc.getAuthors())
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString())
.add("Description", desc.getDescription().orElse(null))
.add("URL", desc.getUrl().orElse(null))
.add("Source", desc.getSource().map(Path::toString).orElse(null))
.add("Dependencies", ListBuilder.create(desc.getDependencies())
.format(d -> listFormat.format(d.getId()))
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString());
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.plugininfo.footer");
}
/**
* Shows information about a provided command.
* @param source The sender of the command.
* @param command The command to lookup.
*/
@Subcommand("commandinfo|ci")
@CommandCompletion("@commands")
@CommandPermission("serverutils.commandinfo")
@Description("Shows information about the specified command.")
public void onCommandInfo(CommandSource source, String command) {
ServerCommandSender sender = VelocityUtils.wrap(source);
CommandDispatcher<CommandSource> dispatcher = RVelocityCommandManager.getDispatcher(
plugin.getProxy().getCommandManager()
);
CommandNode<CommandSource> node = dispatcher.getRoot().getChild(command);
if (node == null) {
Messenger.sendMessage(sender, "serverutils.commandinfo.not_exists");
return;
}
String format = Messenger.getMessage("serverutils.commandinfo.format");
Messenger.sendMessage(sender, "serverutils.commandinfo.header");
FormatBuilder builder = FormatBuilder.create(format)
.orderedKeys("%key%", "%value%")
.add("Name", node.getName())
.add("Plugin", plugin.getPluginCommandManager().findPluginId(command).orElse("<UNKNOWN>"));
builder.sendTo(sender);
Messenger.sendMessage(sender, "serverutils.commandinfo.footer");
}
}

View file

@ -0,0 +1,59 @@
package net.frankheijden.serverutils.velocity.commands;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.context.CommandContext;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import com.velocitypowered.api.scheduler.ScheduledTask;
import net.frankheijden.serverutils.common.commands.CommandPlugins;
import net.frankheijden.serverutils.velocity.entities.VelocityCommandSender;
import net.frankheijden.serverutils.velocity.entities.VelocityPlugin;
public class VelocityCommandPlugins extends CommandPlugins<
VelocityPlugin,
PluginContainer,
ScheduledTask,
VelocityCommandSender,
CommandSource
> {
public VelocityCommandPlugins(VelocityPlugin plugin) {
super(plugin);
}
@Override
protected void register(
CommandManager<VelocityCommandSender> manager,
Command.Builder<VelocityCommandSender> builder
) {
manager.command(builder
.flag(parseFlag("version"))
.handler(this::handlePlugins));
}
@Override
protected void handlePlugins(CommandContext<VelocityCommandSender> context) {
VelocityCommandSender sender = context.getSender();
boolean hasVersionFlag = context.flags().contains("version");
handlePlugins(sender, plugin.getPluginManager().getPluginsSorted(), container -> {
PluginDescription description = container.getDescription();
String message = plugin.getMessagesResource().getMessage(
"serverutils.plugins.format",
"%plugin%", description.getId()
);
if (hasVersionFlag) {
message += plugin.getMessagesResource().getMessage(
"serverutils.plugins.version",
"%version%", description.getVersion().orElse("<UNKNOWN>")
);
}
return message;
});
}
}

View file

@ -0,0 +1,76 @@
package net.frankheijden.serverutils.velocity.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import com.velocitypowered.api.plugin.meta.PluginDependency;
import com.velocitypowered.api.scheduler.ScheduledTask;
import java.nio.file.Path;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.frankheijden.serverutils.common.commands.CommandServerUtils;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.velocity.ServerUtils;
import net.frankheijden.serverutils.velocity.entities.VelocityCommandSender;
import net.frankheijden.serverutils.velocity.entities.VelocityPlugin;
import net.frankheijden.serverutils.velocity.reflection.RVelocityCommandManager;
public class VelocityCommandServerUtils extends CommandServerUtils<
VelocityPlugin,
PluginContainer,
ScheduledTask,
VelocityCommandSender,
CommandSource
> {
public VelocityCommandServerUtils(VelocityPlugin plugin) {
super(plugin);
}
@Override
protected FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String pluginName
) {
PluginContainer container = plugin.getPluginManager().getPlugin(pluginName);
PluginDescription desc = container.getDescription();
return builder
.add("Id", desc.getId())
.add("Name", desc.getName().orElse(null))
.add("Version", desc.getVersion().orElse("<UNKNOWN>"))
.add(
"Author" + (desc.getAuthors().size() == 1 ? "" : "s"),
listBuilderFunction.apply(b -> b.addAll(desc.getAuthors()))
)
.add("Description", desc.getDescription().orElse(null))
.add("URL", desc.getUrl().orElse(null))
.add("Source", desc.getSource().map(Path::toString).orElse(null))
.add(
"Dependencies",
listBuilderFunction.apply(b -> b.addAll(desc.getDependencies().stream()
.map(PluginDependency::getId)
.collect(Collectors.toList())))
);
}
@Override
protected FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
String commandName
) {
ServerUtils plugin = ServerUtils.getInstance();
CommandDispatcher<CommandSource> dispatcher = RVelocityCommandManager.getDispatcher(
plugin.getProxy().getCommandManager()
);
return builder
.add("Name", dispatcher.getRoot().getChild(commandName).getName())
.add("Plugin", plugin.getPluginCommandManager().findPluginId(commandName).orElse("<UNKNOWN>"));
}
}

View file

@ -1,14 +1,13 @@
package net.frankheijden.serverutils.velocity.entities;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import com.velocitypowered.api.command.CommandSource;
import net.frankheijden.serverutils.common.providers.ChatProvider;
import net.frankheijden.serverutils.common.utils.HexUtils;
import net.frankheijden.serverutils.velocity.ServerUtils;
import net.frankheijden.serverutils.velocity.utils.VelocityUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class VelocityChatProvider extends ChatProvider {
public class VelocityChatProvider implements ChatProvider<VelocityCommandSender, CommandSource> {
private final ServerUtils plugin;
@ -17,8 +16,13 @@ public class VelocityChatProvider extends ChatProvider {
}
@Override
public ServerCommandSender getConsoleSender() {
return VelocityUtils.wrap(plugin.getProxy().getConsoleCommandSource());
public VelocityCommandSender getConsoleSender() {
return new VelocityCommandSender(plugin.getProxy().getConsoleCommandSource());
}
@Override
public VelocityCommandSender get(CommandSource source) {
return new VelocityCommandSender(source);
}
@Override

View file

@ -5,7 +5,7 @@ import com.velocitypowered.api.proxy.Player;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class VelocityCommandSender implements ServerCommandSender {
public class VelocityCommandSender implements ServerCommandSender<CommandSource> {
private final CommandSource source;
@ -31,4 +31,9 @@ public class VelocityCommandSender implements ServerCommandSender {
public boolean isPlayer() {
return source instanceof Player;
}
@Override
public CommandSource getSource() {
return source;
}
}

View file

@ -1,16 +1,25 @@
package net.frankheijden.serverutils.velocity.entities;
import com.velocitypowered.api.plugin.PluginDescription;
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.velocity.VelocityCommandManager;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.scheduler.ScheduledTask;
import java.io.File;
import java.nio.file.Path;
import java.util.logging.Logger;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.velocity.ServerUtils;
import net.frankheijden.serverutils.velocity.commands.VelocityCommandPlugins;
import net.frankheijden.serverutils.velocity.commands.VelocityCommandServerUtils;
import net.frankheijden.serverutils.velocity.managers.VelocityPluginManager;
import net.frankheijden.serverutils.velocity.managers.VelocityTaskManager;
import net.frankheijden.serverutils.velocity.reflection.RJavaPluginLoader;
public class VelocityPlugin extends ServerUtilsPlugin {
public class VelocityPlugin extends ServerUtilsPlugin<
PluginContainer,
ScheduledTask,
VelocityCommandSender,
CommandSource
> {
private final ServerUtils plugin;
private final VelocityPluginManager pluginManager;
@ -31,25 +40,39 @@ public class VelocityPlugin extends ServerUtilsPlugin {
}
@Override
@SuppressWarnings("unchecked")
public VelocityPluginManager getPluginManager() {
return pluginManager;
protected VelocityCommandManager<VelocityCommandSender> newCommandManager() {
return new VelocityCommandManager<>(
plugin.getPluginContainer(),
plugin.getProxy(),
AsynchronousCommandExecutionCoordinator.<VelocityCommandSender>newBuilder().build(),
chatProvider::get,
VelocityCommandSender::getSource
);
}
@Override
public VelocityPluginManager getPluginManager() {
return this.pluginManager;
}
@Override
@SuppressWarnings("unchecked")
public VelocityTaskManager getTaskManager() {
return taskManager;
return this.taskManager;
}
@Override
public Platform getPlatform() {
return Platform.VELOCITY;
}
@Override
public VelocityResourceProvider getResourceProvider() {
return resourceProvider;
return this.resourceProvider;
}
@Override
public VelocityChatProvider getChatProvider() {
return chatProvider;
return this.chatProvider;
}
@Override
@ -59,14 +82,12 @@ public class VelocityPlugin extends ServerUtilsPlugin {
@Override
public File getDataFolder() {
return plugin.getDataDirectory().toFile();
return this.plugin.getDataDirectory().toFile();
}
@Override
@SuppressWarnings("unchecked")
public PluginDescription fetchUpdaterData() {
Path pluginPath = pluginManager.getPluginFile("ServerUtils").toPath();
Object javaPluginLoader = RJavaPluginLoader.newInstance(plugin.getProxy(), pluginPath.getParent());
return RJavaPluginLoader.loadPluginDescription(javaPluginLoader, pluginPath);
protected void reloadPlugin() {
new VelocityCommandPlugins(this).register(commandManager);
new VelocityCommandServerUtils(this).register(commandManager);
}
}

View file

@ -19,7 +19,7 @@ public class VelocityResourceProvider implements ResourceProvider {
}
@Override
public InputStream getResource(String resource) {
public InputStream getRawResource(String resource) {
return plugin.getClass().getClassLoader().getResourceAsStream(resource);
}
@ -43,4 +43,9 @@ public class VelocityResourceProvider implements ResourceProvider {
public ServerUtilsConfig load(File file) {
return new VelocityTomlConfig(file);
}
@Override
public String getResourceExtension() {
return ".toml";
}
}

View file

@ -8,6 +8,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
@ -21,10 +22,10 @@ public class VelocityTomlConfig implements ServerUtilsConfig {
* Creates a new VelocityTomlConfig instance.
*/
public VelocityTomlConfig(File file) {
CommentedFileConfig config = CommentedFileConfig.of(file, TomlFormat.instance());
config.load();
CommentedFileConfig conf = CommentedFileConfig.of(file, TomlFormat.instance());
conf.load();
this.config = config;
this.config = conf;
this.file = file;
}
@ -56,7 +57,11 @@ public class VelocityTomlConfig implements ServerUtilsConfig {
@Override
public void set(String path, Object value) {
config.set(path, value);
if (value == null) {
config.remove(path);
} else {
config.set(path, value);
}
}
@Override
@ -71,7 +76,7 @@ public class VelocityTomlConfig implements ServerUtilsConfig {
@Override
public Collection<? extends String> getKeys() {
return config.valueMap().keySet();
return new HashSet<>(config.valueMap().keySet());
}
@Override

View file

@ -39,7 +39,7 @@ import net.frankheijden.serverutils.velocity.reflection.RVelocityPluginContainer
import net.frankheijden.serverutils.velocity.reflection.RVelocityPluginManager;
import net.frankheijden.serverutils.velocity.reflection.RVelocityScheduler;
public class VelocityPluginManager extends AbstractPluginManager<PluginContainer> {
public class VelocityPluginManager implements AbstractPluginManager<PluginContainer> {
private static VelocityPluginManager instance;
private final ProxyServer proxy;

View file

@ -1,12 +0,0 @@
package net.frankheijden.serverutils.velocity.utils;
import com.velocitypowered.api.command.CommandSource;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.velocity.entities.VelocityCommandSender;
public class VelocityUtils {
public static ServerCommandSender wrap(CommandSource source) {
return new VelocityCommandSender(source);
}
}

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1 @@
{}

View file

@ -1,7 +0,0 @@
[settings]
check-updates-boot = true
check-updates-login = false
download-updates-boot = false
download-updates-login = false
install-updates-boot = false
install-updates-login = false

View file

@ -0,0 +1 @@
{}

View file

@ -1,67 +0,0 @@
[serverutils]
success = "&3Successfully %action%ed &b%what%&3!"
warning = "&3Successfully %action%ed &b%what%&3, but with warnings."
error = "&cAn error occurred while %action%ing &4%what%&c, please check the console!"
not_exists = "&cAn error occurred while %action%ing &4%what%&c, plugin does not exist!"
not_enabled = "&cAn error occurred while %action%ing &4%what%&c, plugin is not enabled!"
already_loaded = "&cAn error occurred while %action%ing &4%what%&c, plugin is already loaded!"
already_enabled = "&cAn error occurred while %action%ing &4%what%&c, plugin is already enabled!"
already_disabled = "&cAn error occurred while %action%ing &4%what%&c, plugin is already disabled!"
file_deleted = "&cAccessing the jar file while %action%ing &4%what%&c went wrong, plugin has been deleted!"
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%"
[serverutils.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!"
[serverutils.update]
available = """
&8&m--------=&r&8[ &b&lServerUtils Velocity Update&r &8]&m=---------
&3Current version: &b%old%
&3New version: &b%new%
&3Release info: &b%info%
&8&m-------------------------------------------------"""
downloading = """
&8&m--------=&r&8[ &b&lServerUtils Velocity Update&r &8]&m=----------
&3A new version of ServerUtils will be downloaded and installed after a restart!
&3Current version: &b%old%
&3New version: &b%new%
&3Release info: &b%info%
&8&m-------------------------------------------------"""
download_failed = "&cFailed to download version %new% of ServerUtils. Please update manually."
download_success = "&3ServerUtils has been downloaded and will be installed on the next restart."
[serverutils.help]
header = "&8&m---------=&r&8[ &b&lServerUtils Velocity Help&r &8]&m=---------"
format = "&8/&3%command%&b%subcommand% &f(&7%help%&f)"
footer = "&8&m-------------------------------------------------"
[serverutils.plugins]
header = "&8&m--------=&r&8[ &b&lServerUtils Velocity Plugins&r &8]&m=-------"
prefix = " &3Plugins &8(&a%count%&8)&b: "
format = "&3%plugin%"
seperator = "&b, "
last_seperator = " &band "
version = " &8(&a%version%&8)"
footer = "&8&m-------------------------------------------------"
[serverutils.plugininfo]
header = "&8&m------=&r&8[ &b&lServerUtils Velocity PluginInfo&r &8]&m=------"
format = " &3%key%&8: &b%value%"
list_format = "&b%value%"
seperator = "&8, "
last_seperator = " &8and "
footer = "&8&m-------------------------------------------------"
[serverutils.commandinfo]
header = "&8&m-----=&r&8[ &b&lServerUtils Velocity CommandInfo&r &8]&m=------"
format = " &3%key%&8: &b%value%"
list_format = "&b%value%"
seperator = "&8, "
last_seperator = " &8and "
footer = "&8&m-------------------------------------------------"
not_exists = "&cThat command is not a valid registered command."

View file

@ -20,10 +20,12 @@ subprojects {
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url 'https://repo.aikar.co/content/groups/aikar/' }
maven { url 'https://repo.incendo.org/content/repositories/snapshots' }
maven { url 'https://papermc.io/repo/repository/maven-public/' }
}
dependencies {
implementation 'com.github.FrankHeijden.cloud:cloud-core:fea4605277'
implementation 'com.github.FrankHeijden:MinecraftReflection:1.0.0'
testCompile 'org.assertj:assertj-core:3.18.1'
@ -51,6 +53,13 @@ subprojects {
maxWarnings = 0
}
shadowJar {
exclude 'com/mojang/**'
relocate 'dev.frankheijden.minecraftreflection', dependencyDir + '.minecraftreflection'
relocate 'cloud.commandframework', dependencyDir + '.cloud'
relocate 'io.leangen.geantyref', dependencyDir + '.typetoken'
}
shadowJar.dependsOn checkstyleMain, checkstyleTest, test
}