Add MiniMessage

This commit is contained in:
Frank van der Heijden 2021-08-03 02:07:39 +02:00
parent bb5c642f31
commit 083012abfe
No known key found for this signature in database
GPG key ID: B808721C2DD5B5B8
74 changed files with 1328 additions and 1078 deletions

View file

@ -1,10 +1,13 @@
group = rootProject.group + '.bukkit'
String rootDependencyDir = rootProject.group + '.dependencies'
String dependencyDir = group + '.dependencies'
version = rootProject.version
archivesBaseName = rootProject.name + '-Bukkit'
dependencies {
implementation "com.github.FrankHeijden.cloud:cloud-paper:${rootProject.cloudVersion}"
implementation 'net.kyori:adventure-api:4.8.1'
implementation 'net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT'
implementation 'org.bstats:bstats-bukkit:2.2.1'
implementation project(":Common")
compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
@ -19,4 +22,6 @@ processResources {
shadowJar {
relocate 'org.bstats', dependencyDir + '.bstats'
relocate 'net.kyori.adventure', rootDependencyDir + '.adventure'
relocate 'net.kyori.examination', rootDependencyDir + '.examination'
}

View file

@ -3,13 +3,18 @@ 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.BukkitAudience;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.common.commands.CommandPlugins;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
public class BukkitCommandPlugins extends CommandPlugins<BukkitPlugin, Plugin, BukkitCommandSender> {
public class BukkitCommandPlugins extends CommandPlugins<BukkitPlugin, Plugin, BukkitAudience> {
public BukkitCommandPlugins(BukkitPlugin plugin) {
super(plugin);
@ -17,8 +22,8 @@ public class BukkitCommandPlugins extends CommandPlugins<BukkitPlugin, Plugin, B
@Override
protected void register(
CommandManager<BukkitCommandSender> manager,
Command.Builder<BukkitCommandSender> builder
CommandManager<BukkitAudience> manager,
Command.Builder<BukkitAudience> builder
) {
manager.command(builder
.flag(parseFlag("version"))
@ -26,26 +31,25 @@ public class BukkitCommandPlugins extends CommandPlugins<BukkitPlugin, Plugin, B
}
@Override
protected void handlePlugins(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
protected void handlePlugins(CommandContext<BukkitAudience> context) {
BukkitAudience sender = context.getSender();
boolean hasVersionFlag = context.flags().contains("version");
MessagesResource messages = plugin.getMessagesResource();
handlePlugins(sender, plugin.getPluginManager().getPluginsSorted(), bukkitPlugin -> {
PluginDescriptionFile description = bukkitPlugin.getDescription();
String message = plugin.getMessagesResource().getMessage(
"serverutils.plugins.format",
"%plugin%", description.getName()
);
TextComponent.Builder builder = Component.text();
builder.append(messages.get(MessageKey.PLUGINS_FORMAT).toComponent(
Template.of("plugin", description.getName())
));
if (hasVersionFlag) {
message += plugin.getMessagesResource().getMessage(
"serverutils.plugins.version",
"%version%", description.getVersion()
);
builder.append(messages.get(MessageKey.PLUGINS_FORMAT).toComponent(
Template.of("version", description.getVersion())
));
}
return message;
return builder.build();
});
}
}

View file

@ -11,7 +11,8 @@ 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.config.BukkitMessageKey;
import net.frankheijden.serverutils.bukkit.entities.BukkitAudience;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
@ -20,17 +21,21 @@ 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.commands.arguments.PluginsArgument;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.common.entities.results.PluginResults;
import net.frankheijden.serverutils.common.utils.FormatBuilder;
import net.frankheijden.serverutils.common.utils.KeyValueComponentBuilder;
import net.frankheijden.serverutils.common.utils.ForwardFilter;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListComponentBuilder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Template;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, Plugin, BukkitCommandSender> {
public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, Plugin, BukkitAudience> {
private static final Map<String, ReloadHandler> supportedConfigs;
@ -53,8 +58,8 @@ public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, P
@Override
public void register(
CommandManager<BukkitCommandSender> manager,
cloud.commandframework.Command.Builder<BukkitCommandSender> builder
CommandManager<BukkitAudience> manager,
cloud.commandframework.Command.Builder<BukkitAudience> builder
) {
super.register(manager, builder);
@ -68,7 +73,7 @@ public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, P
})
.map(Map.Entry::getKey)
.collect(Collectors.toList());
addArgument(CommandArgument.<BukkitCommandSender, String>ofType(String.class, "config")
addArgument(CommandArgument.<BukkitAudience, String>ofType(String.class, "config")
.manager(manager)
.withSuggestionsProvider((context, s) -> supportedConfigNames)
.build());
@ -88,36 +93,36 @@ public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, P
.handler(this::handleReloadConfig));
}
private void handleEnablePlugin(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
private void handleEnablePlugin(CommandContext<BukkitAudience> context) {
BukkitAudience sender = context.getSender();
List<Plugin> plugins = Arrays.asList(context.get("plugins"));
PluginResults<Plugin> result = plugin.getPluginManager().enablePlugins(plugins);
result.sendTo(sender, "enabl");
PluginResults<Plugin> enableResults = plugin.getPluginManager().enablePlugins(plugins);
sender.sendMessage(enableResults.toComponent(BukkitMessageKey.ENABLEPLUGIN));
}
private void handleDisablePlugin(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
private void handleDisablePlugin(CommandContext<BukkitAudience> context) {
BukkitAudience sender = context.getSender();
List<Plugin> plugins = Arrays.asList(context.get("plugins"));
if (checkDependingPlugins(context, sender, plugins, "disableplugin")) {
return;
}
PluginResults<Plugin> result = plugin.getPluginManager().disablePlugins(plugins);
result.sendTo(sender, "disabl");
PluginResults<Plugin> disableResults = plugin.getPluginManager().disablePlugins(plugins);
sender.sendMessage(disableResults.toComponent(BukkitMessageKey.DISABLEPLUGIN));
}
private void handleReloadConfig(CommandContext<BukkitCommandSender> context) {
BukkitCommandSender sender = context.getSender();
private void handleReloadConfig(CommandContext<BukkitAudience> context) {
BukkitAudience sender = context.getSender();
String config = context.get("config");
MessagesResource messages = plugin.getMessagesResource();
ReloadHandler handler = supportedConfigs.get(config);
if (handler == null) {
plugin.getMessagesResource().sendMessage(
messages.get(BukkitMessageKey.RELOADCONFIG_NOT_EXISTS).sendTo(
sender,
"serverutils.reloadconfig.not_exists",
"%what%", config
Template.of("config", config)
);
return;
}
@ -127,37 +132,36 @@ public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, P
int max = versionReloadHandler.getMinecraftVersionMaximum();
if (MinecraftReflectionVersion.MINOR > max) {
plugin.getMessagesResource().sendMessage(
messages.get(BukkitMessageKey.RELOADCONFIG_NOT_SUPPORTED).sendTo(
sender,
"serverutils.reloadconfig.not_supported",
"%what%", config
Template.of("config", config)
);
return;
}
}
String[] replacements = new String[]{ "%action%", "reload", "%what%", config };
ForwardFilter filter = new ForwardFilter(plugin.getChatProvider(), sender);
ForwardFilter filter = new ForwardFilter(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);
BukkitMessageKey key = filter.hasWarnings()
? BukkitMessageKey.RELOADCONFIG_WARNINGS
: BukkitMessageKey.RELOADCONFIG_SUCCESS;
plugin.getMessagesResource().get(key).sendTo(sender, Template.of("config", config));
} catch (Exception ex) {
filter.stop(Bukkit.getLogger());
ex.printStackTrace();
plugin.getMessagesResource().sendMessage(sender, "serverutils.error", replacements);
plugin.getMessagesResource().get(MessageKey.GENERIC_ERROR).sendTo(sender);
}
}
@Override
protected FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected KeyValueComponentBuilder createPluginInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
Plugin bukkitPlugin
) {
PluginDescriptionFile description = bukkitPlugin.getDescription();
@ -187,9 +191,9 @@ public class BukkitCommandServerUtils extends CommandServerUtils<BukkitPlugin, P
}
@Override
protected FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected KeyValueComponentBuilder createCommandInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
String commandName
) {
Command cmd = BukkitPluginManager.getCommand(commandName);

View file

@ -0,0 +1,41 @@
package net.frankheijden.serverutils.bukkit.config;
import java.util.Locale;
import net.frankheijden.serverutils.common.config.PlaceholderConfigKey;
public enum BukkitMessageKey implements PlaceholderConfigKey {
RELOADCONFIG_SUCCESS("reloadconfig.success"),
RELOADCONFIG_WARNINGS("reloadconfig.warnings"),
RELOADCONFIG_NOT_EXISTS("reloadconfig.not-exists"),
RELOADCONFIG_NOT_SUPPORTED("reloadconfig.not-supported"),
ENABLEPLUGIN("enableplugin"),
DISABLEPLUGIN("disableplugin"),
;
private final String path;
private final boolean hasPlaceholders;
BukkitMessageKey(String path) {
this(path, true);
}
BukkitMessageKey(String path, boolean hasPlaceholders) {
this.path = path;
this.hasPlaceholders = hasPlaceholders;
}
public static BukkitMessageKey fromPath(String path) {
return BukkitMessageKey.valueOf(path.replaceAll("\\.|-", "_").toUpperCase(Locale.ENGLISH));
}
@Override
public String getPath() {
return path;
}
@Override
public boolean hasPlaceholders() {
return hasPlaceholders;
}
}

View file

@ -0,0 +1,23 @@
package net.frankheijden.serverutils.bukkit.entities;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.audience.Audience;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class BukkitAudience extends ServerUtilsAudience<CommandSender> {
public BukkitAudience(Audience audience, CommandSender source) {
super(audience, source);
}
@Override
public boolean isPlayer() {
return source instanceof Player;
}
@Override
public boolean hasPermission(String permission) {
return source.hasPermission(permission);
}
}

View file

@ -0,0 +1,39 @@
package net.frankheijden.serverutils.bukkit.entities;
import net.frankheijden.serverutils.bukkit.ServerUtils;
import net.frankheijden.serverutils.common.providers.ServerUtilsAudienceProvider;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.bukkit.command.CommandSender;
public class BukkitAudienceProvider implements ServerUtilsAudienceProvider<CommandSender> {
private final BukkitAudiences audiences;
private final BukkitAudience consoleServerAudience;
/**
* Constructs a new BukkitAudienceProvider.
*/
public BukkitAudienceProvider(ServerUtils plugin, BukkitAudiences audiences) {
this.audiences = audiences;
this.consoleServerAudience = new BukkitAudience(
audiences.console(),
plugin.getServer().getConsoleSender()
);
}
@Override
public BukkitAudience getConsoleServerAudience() {
return this.consoleServerAudience;
}
@Override
public BukkitAudience get(CommandSender source) {
return new BukkitAudience(audiences.sender(source), source);
}
@Override
public void broadcast(Component component, String permission) {
audiences.filter(sender -> sender.hasPermission(permission)).sendMessage(component);
}
}

View file

@ -1,30 +0,0 @@
package net.frankheijden.serverutils.bukkit.entities;
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;
public class BukkitChatProvider implements ChatProvider<BukkitCommandSender, CommandSender> {
@Override
public BukkitCommandSender getConsoleSender() {
return new BukkitCommandSender(Bukkit.getConsoleSender());
}
@Override
public BukkitCommandSender get(CommandSender source) {
return new BukkitCommandSender(source);
}
@Override
public String color(String str) {
return ChatColor.translateAlternateColorCodes('&', HexUtils.convertHexString(str));
}
@Override
public void broadcast(String permission, String message) {
Bukkit.broadcast(message, permission);
}
}

View file

@ -1,54 +0,0 @@
package net.frankheijden.serverutils.bukkit.entities;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
/**
* A wrap for a Bukkit CommandSender.
*/
public class BukkitCommandSender implements ServerCommandSender<CommandSender> {
private final CommandSender sender;
/**
* Constructs a new CommandSender instance.
* @param sender The sender to wrap.
*/
public BukkitCommandSender(CommandSender sender) {
this.sender = sender;
}
/**
* Sends a message to a CommandSender.
* @param message The message to send.
*/
@Override
public void sendMessage(String message) {
sender.sendMessage(message);
}
/**
* Checks if the CommandSender has a permission.
* @param permission The permission to check.
* @return Whether or not they have the permission.
*/
@Override
public boolean hasPermission(String permission) {
return sender.hasPermission(permission);
}
/**
* Whether or not the given instance is a player.
* @return Boolean true or false.
*/
@Override
public boolean isPlayer() {
return sender instanceof Player;
}
@Override
public CommandSender getSource() {
return sender;
}
}

View file

@ -4,26 +4,30 @@ import cloud.commandframework.bukkit.CloudBukkitCapabilities;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.paper.PaperCommandManager;
import java.io.File;
import java.util.Arrays;
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.config.BukkitMessageKey;
import net.frankheijden.serverutils.bukkit.listeners.BukkitPlayerListener;
import net.frankheijden.serverutils.bukkit.managers.BukkitPluginManager;
import net.frankheijden.serverutils.bukkit.managers.BukkitTaskManager;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
public class BukkitPlugin extends ServerUtilsPlugin<Plugin, BukkitTask, BukkitCommandSender, CommandSender, BukkitPluginDescription> {
public class BukkitPlugin extends ServerUtilsPlugin<Plugin, BukkitTask, BukkitAudience, CommandSender, BukkitPluginDescription> {
private final ServerUtils plugin;
private final BukkitPluginManager pluginManager;
private final BukkitTaskManager taskManager;
private final BukkitResourceProvider resourceProvider;
private final BukkitChatProvider chatProvider;
private final BukkitAudiences audiences;
private final BukkitAudienceProvider chatProvider;
private boolean registeredPluginsCommand;
/**
@ -35,19 +39,20 @@ public class BukkitPlugin extends ServerUtilsPlugin<Plugin, BukkitTask, BukkitCo
this.pluginManager = new BukkitPluginManager();
this.taskManager = new BukkitTaskManager();
this.resourceProvider = new BukkitResourceProvider(plugin);
this.chatProvider = new BukkitChatProvider();
this.audiences = BukkitAudiences.create(plugin);
this.chatProvider = new BukkitAudienceProvider(plugin, this.audiences);
this.registeredPluginsCommand = false;
}
@Override
protected PaperCommandManager<BukkitCommandSender> newCommandManager() {
PaperCommandManager<BukkitCommandSender> commandManager;
protected PaperCommandManager<BukkitAudience> newCommandManager() {
PaperCommandManager<BukkitAudience> commandManager;
try {
commandManager = new PaperCommandManager<>(
plugin,
CommandExecutionCoordinator.simpleCoordinator(),
chatProvider::get,
BukkitCommandSender::getSource
BukkitAudience::getSource
);
} catch (Exception ex) {
throw new RuntimeException(ex);
@ -91,7 +96,7 @@ public class BukkitPlugin extends ServerUtilsPlugin<Plugin, BukkitTask, BukkitCo
}
@Override
public BukkitChatProvider getChatProvider() {
public BukkitAudienceProvider getChatProvider() {
return chatProvider;
}
@ -110,8 +115,14 @@ public class BukkitPlugin extends ServerUtilsPlugin<Plugin, BukkitTask, BukkitCo
Bukkit.getPluginManager().registerEvents(new BukkitPlayerListener(this), plugin);
}
@Override
protected void disablePlugin() {
this.audiences.close();
}
@Override
protected void reloadPlugin() {
this.messagesResource.load(Arrays.asList(BukkitMessageKey.values()));
if (getConfigResource().getConfig().getBoolean("settings.disable-plugins-command")) {
if (registeredPluginsCommand) {
BukkitPluginManager.unregisterCommands("pl", "plugins");

View file

@ -1,6 +1,6 @@
package net.frankheijden.serverutils.bukkit.listeners;
import net.frankheijden.serverutils.bukkit.entities.BukkitCommandSender;
import net.frankheijden.serverutils.bukkit.entities.BukkitAudience;
import net.frankheijden.serverutils.bukkit.entities.BukkitPlugin;
import net.frankheijden.serverutils.common.listeners.PlayerListener;
import org.bukkit.event.EventHandler;
@ -10,7 +10,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
public class BukkitPlayerListener
extends PlayerListener<BukkitPlugin, Plugin, BukkitCommandSender>
extends PlayerListener<BukkitPlugin, Plugin, BukkitAudience>
implements Listener {
public BukkitPlayerListener(BukkitPlugin plugin) {

View file

@ -31,6 +31,7 @@ import net.frankheijden.serverutils.common.entities.results.Result;
import net.frankheijden.serverutils.common.entities.exceptions.InvalidPluginDescriptionException;
import net.frankheijden.serverutils.common.events.PluginEvent;
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
import net.kyori.adventure.text.minimessage.Template;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.PluginCommand;
@ -67,7 +68,9 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
} catch (InvalidDescriptionException ex) {
return pluginResults.addResult(pluginId, Result.INVALID_DESCRIPTION);
} catch (UnknownDependencyException ex) {
return pluginResults.addResult(pluginId, Result.UNKNOWN_DEPENDENCY.arg(ex.getMessage()));
return pluginResults.addResult(pluginId, Result.UNKNOWN_DEPENDENCY,
Template.of("dependency", ex.getMessage())
);
} catch (InvalidPluginException ex) {
if (ex.getCause() instanceof IllegalArgumentException) {
IllegalArgumentException e = (IllegalArgumentException) ex.getCause();

View file

@ -1,8 +1,12 @@
{
"serverutils": {
"messages": {
"reloadconfig": {
"not_exists": "&cConfig &4%what% &cdoes not exist.",
"not_supported": "&cConfig &4%what% &cis not supported on your Minecraft version."
}
"success": "<dark_aqua>Successfully reloaded <aqua><config></aqua>!",
"warnings": "<red>There were warnings while reloading <dark_red><config></dark_red>, please check the console!",
"not-exists": "<red>Config <dark_red><config></dark_red> does not exist.",
"not-supported": "<red>Config <dark_red><config></dark_red> is not supported on your Minecraft version."
},
"disableplugin": "<dark_aqua>Successfully disabled <aqua><plugin></aqua>!",
"enableplugin": "<dark_aqua>Successfully enabled <aqua><plugin></aqua>!"
}
}

View file

@ -1,4 +1,5 @@
group = rootProject.group + '.bungee'
String rootDependencyDir = rootProject.group + '.dependencies'
String dependencyDir = group + '.dependencies'
version = rootProject.version
archivesBaseName = rootProject.name + '-Bungee'
@ -9,6 +10,8 @@ repositories {
dependencies {
implementation "com.github.FrankHeijden.cloud:cloud-bungee:${rootProject.cloudVersion}"
implementation 'net.kyori:adventure-api:4.8.1'
implementation 'net.kyori:adventure-platform-bungeecord:4.0.0-SNAPSHOT'
implementation 'org.bstats:bstats-bungeecord:2.2.1'
implementation project(":Common")
compileOnly 'net.md-5:bungeecord-api:1.17-R0.1-SNAPSHOT'
@ -23,4 +26,6 @@ processResources {
shadowJar {
relocate 'org.bstats', dependencyDir + '.bstats'
relocate 'net.kyori.adventure', rootDependencyDir + '.adventure'
relocate 'net.kyori.examination', rootDependencyDir + '.examination'
}

View file

@ -3,13 +3,18 @@ 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.BungeeAudience;
import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.common.commands.CommandPlugins;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.api.plugin.PluginDescription;
public class BungeeCommandPlugins extends CommandPlugins<BungeePlugin, Plugin, BungeeCommandSender> {
public class BungeeCommandPlugins extends CommandPlugins<BungeePlugin, Plugin, BungeeAudience> {
public BungeeCommandPlugins(BungeePlugin plugin) {
super(plugin);
@ -17,8 +22,8 @@ public class BungeeCommandPlugins extends CommandPlugins<BungeePlugin, Plugin, B
@Override
protected void register(
CommandManager<BungeeCommandSender> manager,
Command.Builder<BungeeCommandSender> builder
CommandManager<BungeeAudience> manager,
Command.Builder<BungeeAudience> builder
) {
manager.command(builder
.flag(parseFlag("version"))
@ -27,27 +32,26 @@ public class BungeeCommandPlugins extends CommandPlugins<BungeePlugin, Plugin, B
}
@Override
protected void handlePlugins(CommandContext<BungeeCommandSender> context) {
BungeeCommandSender sender = context.getSender();
protected void handlePlugins(CommandContext<BungeeAudience> context) {
BungeeAudience sender = context.getSender();
boolean hasVersionFlag = context.flags().contains("version");
boolean hasModulesFlag = context.flags().contains("modules");
MessagesResource messages = plugin.getMessagesResource();
handlePlugins(sender, plugin.getPluginManager().getPluginsSorted(hasModulesFlag), bungeePlugin -> {
PluginDescription description = bungeePlugin.getDescription();
String message = plugin.getMessagesResource().getMessage(
"serverutils.plugins.format",
"%plugin%", description.getName()
);
TextComponent.Builder builder = Component.text();
builder.append(messages.get(MessageKey.PLUGINS_FORMAT).toComponent(
Template.of("plugin", description.getName())
));
if (hasVersionFlag) {
message += plugin.getMessagesResource().getMessage(
"serverutils.plugins.version",
"%version%", description.getVersion()
);
builder.append(messages.get(MessageKey.PLUGINS_FORMAT).toComponent(
Template.of("version", description.getVersion())
));
}
return message;
return builder.build();
});
}
}

View file

@ -5,27 +5,28 @@ 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.BungeeAudience;
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.frankheijden.serverutils.common.utils.KeyValueComponentBuilder;
import net.frankheijden.serverutils.common.utils.ListComponentBuilder;
import net.kyori.adventure.text.Component;
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;
public class BungeeCommandServerUtils extends CommandServerUtils<BungeePlugin, Plugin, BungeeCommandSender> {
public class BungeeCommandServerUtils extends CommandServerUtils<BungeePlugin, Plugin, BungeeAudience> {
public BungeeCommandServerUtils(BungeePlugin plugin) {
super(plugin, Plugin[]::new);
}
@Override
protected FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected KeyValueComponentBuilder createPluginInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
Plugin bungeePlugin
) {
PluginDescription desc = bungeePlugin.getDescription();
@ -42,9 +43,9 @@ public class BungeeCommandServerUtils extends CommandServerUtils<BungeePlugin, P
}
@Override
protected FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected KeyValueComponentBuilder createCommandInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
String commandName
) {
PluginManager proxyPluginManager = ServerUtils.getInstance().getProxy().getPluginManager();

View file

@ -0,0 +1,23 @@
package net.frankheijden.serverutils.bungee.entities;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.audience.Audience;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class BungeeAudience extends ServerUtilsAudience<CommandSender> {
protected BungeeAudience(Audience audience, CommandSender source) {
super(audience, source);
}
@Override
public boolean isPlayer() {
return source instanceof ProxiedPlayer;
}
@Override
public boolean hasPermission(String permission) {
return source.hasPermission(permission);
}
}

View file

@ -0,0 +1,39 @@
package net.frankheijden.serverutils.bungee.entities;
import net.frankheijden.serverutils.bungee.ServerUtils;
import net.frankheijden.serverutils.common.providers.ServerUtilsAudienceProvider;
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
import net.kyori.adventure.text.Component;
import net.md_5.bungee.api.CommandSender;
public class BungeeAudienceProvider implements ServerUtilsAudienceProvider<CommandSender> {
private final BungeeAudiences audiences;
private final BungeeAudience consoleServerAudience;
/**
* Constructs a new BungeeAudienceProvider.
*/
public BungeeAudienceProvider(ServerUtils plugin, BungeeAudiences audiences) {
this.audiences = audiences;
this.consoleServerAudience = new BungeeAudience(
audiences.console(),
plugin.getProxy().getConsole()
);
}
@Override
public BungeeAudience getConsoleServerAudience() {
return consoleServerAudience;
}
@Override
public BungeeAudience get(CommandSender source) {
return new BungeeAudience(audiences.sender(source), source);
}
@Override
public void broadcast(Component component, String permission) {
audiences.filter(sender -> sender.hasPermission(permission)).sendMessage(component);
}
}

View file

@ -1,32 +0,0 @@
package net.frankheijden.serverutils.bungee.entities;
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 implements ChatProvider<BungeeCommandSender, CommandSender> {
@Override
public BungeeCommandSender getConsoleSender() {
return new BungeeCommandSender(ProxyServer.getInstance().getConsole());
}
@Override
public BungeeCommandSender get(CommandSender source) {
return new BungeeCommandSender(source);
}
@Override
public String color(String str) {
return ChatColor.translateAlternateColorCodes('&', HexUtils.convertHexString(str));
}
@Override
public void broadcast(String permission, String message) {
ProxyServer.getInstance().getPlayers().stream()
.filter(p -> p.hasPermission(permission))
.forEach(p -> p.sendMessage(message));
}
}

View file

@ -1,38 +0,0 @@
package net.frankheijden.serverutils.bungee.entities;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class BungeeCommandSender implements ServerCommandSender<CommandSender> {
private final CommandSender sender;
public BungeeCommandSender(CommandSender sender) {
this.sender = sender;
}
@Override
public void sendMessage(String message) {
sender.sendMessage(message);
}
@Override
public boolean hasPermission(String permission) {
return sender.hasPermission(permission);
}
/**
* Whether or not the given instance is a player.
* @return Boolean true or false.
*/
@Override
public boolean isPlayer() {
return sender instanceof ProxiedPlayer;
}
@Override
public CommandSender getSource() {
return sender;
}
}

View file

@ -11,17 +11,19 @@ import net.frankheijden.serverutils.bungee.listeners.BungeePlayerListener;
import net.frankheijden.serverutils.bungee.managers.BungeePluginManager;
import net.frankheijden.serverutils.bungee.managers.BungeeTaskManager;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
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<Plugin, ScheduledTask, BungeeCommandSender, CommandSender, BungeePluginDescription> {
public class BungeePlugin extends ServerUtilsPlugin<Plugin, ScheduledTask, BungeeAudience, CommandSender, BungeePluginDescription> {
private final ServerUtils plugin;
private final BungeePluginManager pluginManager;
private final BungeeTaskManager taskManager;
private final BungeeResourceProvider resourceProvider;
private final BungeeChatProvider chatProvider;
private final BungeeAudiences audiences;
private final BungeeAudienceProvider chatProvider;
/**
* Creates a new BungeePlugin instance of ServerUtils.
@ -32,16 +34,17 @@ public class BungeePlugin extends ServerUtilsPlugin<Plugin, ScheduledTask, Bunge
this.pluginManager = new BungeePluginManager();
this.taskManager = new BungeeTaskManager();
this.resourceProvider = new BungeeResourceProvider(plugin);
this.chatProvider = new BungeeChatProvider();
this.audiences = BungeeAudiences.create(plugin);
this.chatProvider = new BungeeAudienceProvider(plugin, audiences);
}
@Override
protected BungeeCommandManager<BungeeCommandSender> newCommandManager() {
protected BungeeCommandManager<BungeeAudience> newCommandManager() {
return new BungeeCommandManager<>(
plugin,
AsynchronousCommandExecutionCoordinator.<BungeeCommandSender>newBuilder().build(),
AsynchronousCommandExecutionCoordinator.<BungeeAudience>newBuilder().build(),
chatProvider::get,
BungeeCommandSender::getSource
BungeeAudience::getSource
);
}
@ -71,7 +74,7 @@ public class BungeePlugin extends ServerUtilsPlugin<Plugin, ScheduledTask, Bunge
}
@Override
public BungeeChatProvider getChatProvider() {
public BungeeAudienceProvider getChatProvider() {
return chatProvider;
}
@ -90,6 +93,11 @@ public class BungeePlugin extends ServerUtilsPlugin<Plugin, ScheduledTask, Bunge
plugin.getProxy().getPluginManager().registerListener(plugin, new BungeePlayerListener(this));
}
@Override
protected void disablePlugin() {
this.audiences.close();
}
@Override
protected void reloadPlugin() {
new BungeeCommandPlugins(this).register(commandManager);

View file

@ -1,6 +1,6 @@
package net.frankheijden.serverutils.bungee.listeners;
import net.frankheijden.serverutils.bungee.entities.BungeeCommandSender;
import net.frankheijden.serverutils.bungee.entities.BungeeAudience;
import net.frankheijden.serverutils.bungee.entities.BungeePlugin;
import net.frankheijden.serverutils.common.listeners.PlayerListener;
import net.md_5.bungee.api.event.ServerConnectEvent;
@ -8,8 +8,7 @@ import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
public class BungeePlayerListener
extends PlayerListener<BungeePlugin, Plugin, BungeeCommandSender>
public class BungeePlayerListener extends PlayerListener<BungeePlugin, Plugin, BungeeAudience>
implements Listener {
public BungeePlayerListener(BungeePlugin plugin) {

View file

@ -11,7 +11,10 @@ repositories {
}
dependencies {
compileOnly 'net.kyori:adventure-platform-api:4.0.0-SNAPSHOT'
compileOnly 'com.github.FrankHeijden:ServerUtilsUpdater:v1.0.0'
testImplementation 'net.kyori:adventure-text-serializer-plain:4.8.1'
}
blossom {

View file

@ -7,11 +7,12 @@ import java.util.Optional;
import net.frankheijden.serverutils.common.entities.ServerUtilsPluginDescription;
import net.frankheijden.serverutils.common.entities.results.CloseablePluginResult;
import net.frankheijden.serverutils.common.entities.results.PluginResult;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.tasks.UpdateCheckerTask;
import net.kyori.adventure.text.Component;
public class ServerUtilsApp<U extends ServerUtilsPlugin<P, T, C, S, D>, P, T, C extends ServerCommandSender<S>, S, D extends ServerUtilsPluginDescription> {
public class ServerUtilsApp<U extends ServerUtilsPlugin<P, T, C, S, D>, P, T, C extends ServerUtilsAudience<S>, S, D extends ServerUtilsPluginDescription> {
public static final int BSTATS_METRICS_ID = 7790;
public static final String VERSION = "{version}";
@ -31,7 +32,7 @@ public class ServerUtilsApp<U extends ServerUtilsPlugin<P, T, C, S, D>, P, T, C
U extends ServerUtilsPlugin<P, T, C, S, D>,
P,
T,
C extends ServerCommandSender<S>,
C extends ServerUtilsAudience<S>,
S,
D extends ServerUtilsPluginDescription
> void init(
@ -45,7 +46,7 @@ public class ServerUtilsApp<U extends ServerUtilsPlugin<P, T, C, S, D>, P, T, C
* Tries checking for updates if enabled by the config.
*/
public static void tryCheckForUpdates() {
UpdateCheckerTask.tryStart(getPlugin(), getPlugin().getChatProvider().getConsoleSender(), "boot");
UpdateCheckerTask.tryStart(getPlugin(), getPlugin().getChatProvider().getConsoleServerAudience(), "boot");
}
/**
@ -65,13 +66,15 @@ public class ServerUtilsApp<U extends ServerUtilsPlugin<P, T, C, S, D>, P, T, C
File file = plugin.getPluginManager().getPluginFile(updaterPlugin);
PluginResult<P> disableResult = plugin.getPluginManager().disablePlugin(updaterPlugin);
if (!disableResult.isSuccess()) {
disableResult.getResult().sendTo(plugin.getChatProvider().getConsoleSender(), "disabl", updaterName);
Component component = disableResult.toComponent(null);
plugin.getChatProvider().getConsoleServerAudience().sendMessage(component);
return;
}
CloseablePluginResult<P> unloadResult = plugin.getPluginManager().unloadPlugin(disableResult.getPlugin());
if (!unloadResult.isSuccess()) {
unloadResult.getResult().sendTo(plugin.getChatProvider().getConsoleSender(), "unload", updaterName);
Component component = unloadResult.toComponent(null);
plugin.getChatProvider().getConsoleServerAudience().sendMessage(component);
return;
}
@ -96,7 +99,7 @@ public class ServerUtilsApp<U extends ServerUtilsPlugin<P, T, C, S, D>, P, T, C
U extends ServerUtilsPlugin<P, T, C, S, D>,
P,
T,
C extends ServerCommandSender<S>,
C extends ServerUtilsAudience<S>,
S,
D extends ServerUtilsPluginDescription
> U getPlugin() {

View file

@ -2,12 +2,15 @@ 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.config.MessageKey;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.utils.ListBuilder;
import net.frankheijden.serverutils.common.utils.ListFormat;
import net.frankheijden.serverutils.common.utils.ListComponentBuilder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Template;
public abstract class CommandPlugins<U extends ServerUtilsPlugin<P, ?, C, ?, ?>, P, C extends ServerCommandSender<?>>
public abstract class CommandPlugins<U extends ServerUtilsPlugin<P, ?, C, ?, ?>, P, C extends ServerUtilsAudience<?>>
extends ServerUtilsCommand<U, C> {
protected CommandPlugins(U plugin) {
@ -21,21 +24,22 @@ public abstract class CommandPlugins<U extends ServerUtilsPlugin<P, ?, C, ?, ?>,
* @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");
protected void handlePlugins(C sender, List<P> plugins, ListComponentBuilder.Format<P> pluginFormat) {
MessagesResource messages = plugin.getMessagesResource();
sender.sendMessage(Component.text()
.append(messages.get(MessageKey.PLUGINS_HEADER).toComponent())
.append(Component.newline())
.append(messages.get(MessageKey.PLUGINS_PREFIX).toComponent(
Template.of("count", String.valueOf(plugins.size()))
))
.append(ListComponentBuilder.create(plugins)
.separator(messages.get(MessageKey.PLUGINS_SEPARATOR).toComponent())
.lastSeparator(messages.get(MessageKey.PLUGINS_LAST_SEPARATOR).toComponent())
.format(pluginFormat)
.build())
.append(Component.newline())
.append(messages.get(MessageKey.PLUGININFO_FOOTER).toComponent())
.build());
}
}

View file

@ -15,21 +15,24 @@ import java.util.function.IntFunction;
import net.frankheijden.serverutils.common.commands.arguments.JarFilesArgument;
import net.frankheijden.serverutils.common.commands.arguments.PluginArgument;
import net.frankheijden.serverutils.common.commands.arguments.PluginsArgument;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
import net.frankheijden.serverutils.common.entities.results.CloseablePluginResults;
import net.frankheijden.serverutils.common.entities.results.PluginResult;
import net.frankheijden.serverutils.common.entities.results.PluginResults;
import net.frankheijden.serverutils.common.entities.results.PluginWatchResults;
import net.frankheijden.serverutils.common.entities.results.Result;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.entities.results.WatchResult;
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;
import net.frankheijden.serverutils.common.utils.ListComponentBuilder;
import net.frankheijden.serverutils.common.utils.KeyValueComponentBuilder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?, ?>, P, C extends ServerCommandSender<?>>
public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?, ?>, P, C extends ServerUtilsAudience<?>>
extends ServerUtilsCommand<U, C> {
protected final IntFunction<P[]> arrayCreator;
@ -92,10 +95,13 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
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%", "%help%");
MessagesResource messages = plugin.getMessagesResource();
TextComponent.Builder builder = Component.text()
.append(messages.get(MessageKey.HELP_HEADER).toComponent())
.append(Component.newline());
MessagesResource.Message helpFormatMessage = messages.get(MessageKey.HELP_FORMAT);
ServerUtilsConfig config = (ServerUtilsConfig) plugin.getCommandsResource().getConfig().get("commands");
for (String commandName : config.getKeys()) {
@ -104,7 +110,10 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
String shortestCommandAlias = determineShortestAlias(commandElement);
if (commandElement.shouldDisplayInHelp()) {
builder.add(shortestCommandAlias, commandElement.getDescription().getDescription());
builder.append(helpFormatMessage.toComponent(
Template.of("command", shortestCommandAlias),
Template.of("help", commandElement.getDescription().getDescription())
)).append(Component.newline());
}
Object subcommandsObject = commandConfig.get("subcommands");
@ -116,10 +125,10 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
CommandElement subcommandElement = parseElement(subcommandConfig);
if (subcommandElement.shouldDisplayInHelp()) {
String shortestSubcommandAlias = determineShortestAlias(subcommandElement);
builder.add(
shortestCommandAlias + ' ' + shortestSubcommandAlias,
subcommandElement.getDescription().getDescription()
);
builder.append(helpFormatMessage.toComponent(
Template.of("command", shortestCommandAlias + ' ' + shortestSubcommandAlias),
Template.of("help", subcommandElement.getDescription().getDescription())
)).append(Component.newline());
}
}
}
@ -134,16 +143,17 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
if (flagElement.shouldDisplayInHelp()) {
String shortestFlagAlias = determineShortestAlias(flagElement);
String flagPrefix = "-" + (flagElement.getMain().equals(shortestFlagAlias) ? "_" : "");
builder.add(
shortestCommandAlias + ' ' + flagPrefix + shortestFlagAlias,
flagElement.getDescription().getDescription()
);
builder.append(helpFormatMessage.toComponent(
Template.of("command", shortestCommandAlias + ' ' + flagPrefix + shortestFlagAlias),
Template.of("help", flagElement.getDescription().getDescription())
)).append(Component.newline());
}
}
}
}
builder.build().forEach(msg -> plugin.getMessagesResource().sendRawMessage(sender, msg));
plugin.getMessagesResource().sendMessage(sender, "serverutils.help.footer");
builder.append(messages.get(MessageKey.HELP_FOOTER).toComponent());
sender.sendMessage(builder.build());
}
private String determineShortestAlias(CommandElement element) {
@ -159,9 +169,7 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
private void handleReload(CommandContext<C> context) {
C sender = context.getSender();
plugin.reload();
plugin.getMessagesResource().sendMessage(sender, "serverutils.success",
"%action%", "reload",
"%what%", "ServerUtils configurations");
plugin.getMessagesResource().get(MessageKey.RELOAD).sendTo(sender);
}
private void handleLoadPlugin(CommandContext<C> context) {
@ -172,12 +180,12 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
PluginResults<P> loadResults = pluginManager.loadPlugins(jarFiles);
if (!loadResults.isSuccess()) {
PluginResult<P> failedResult = loadResults.last();
failedResult.getResult().sendTo(sender, "load", failedResult.getPluginId());
sender.sendMessage(failedResult.toComponent(null));
return;
}
PluginResults<P> enableResults = pluginManager.enablePlugins(loadResults.getPlugins());
enableResults.sendTo(sender, "load");
sender.sendMessage(enableResults.toComponent(MessageKey.LOADPLUGIN));
}
private void handleUnloadPlugin(CommandContext<C> context) {
@ -191,14 +199,14 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
PluginResults<P> disableResults = plugin.getPluginManager().disablePlugins(plugins);
for (PluginResult<P> disableResult : disableResults.getResults()) {
if (!disableResult.isSuccess() && disableResult.getResult() != Result.ALREADY_DISABLED) {
disableResult.getResult().sendTo(sender, "disabl", disableResult.getPluginId());
sender.sendMessage(disableResult.toComponent(null));
return;
}
}
CloseablePluginResults<P> unloadResults = plugin.getPluginManager().unloadPlugins(plugins);
unloadResults.tryClose();
unloadResults.sendTo(sender, "unload");
sender.sendMessage(unloadResults.toComponent(MessageKey.UNLOADPLUGIN));
}
private void handleReloadPlugin(CommandContext<C> context) {
@ -209,8 +217,8 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
return;
}
PluginResults<P> reloadResult = plugin.getPluginManager().reloadPlugins(plugins);
reloadResult.sendTo(sender, "reload");
PluginResults<P> reloadResults = plugin.getPluginManager().reloadPlugins(plugins);
sender.sendMessage(reloadResults.toComponent(MessageKey.RELOADPLUGIN));
}
protected boolean checkDependingPlugins(CommandContext<C> context, C sender, List<P> plugins, String subcommand) {
@ -219,26 +227,27 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
AbstractPluginManager<P, ?> pluginManager = plugin.getPluginManager();
MessagesResource messages = plugin.getMessagesResource();
TextComponent.Builder builder = Component.text();
boolean hasDependingPlugins = false;
for (P plugin : plugins) {
String pluginId = pluginManager.getPluginId(plugin);
List<P> dependingPlugins = pluginManager.getPluginsDependingOn(pluginId);
if (!dependingPlugins.isEmpty()) {
String prefixString = messages.getMessage(
"serverutils.depending_plugins.prefix",
"%what%", pluginId
);
builder.append(messages.get(MessageKey.DEPENDING_PLUGINS_PREFIX).toComponent(
Template.of("plugin", pluginId)
));
String dependingPluginsString = ListBuilder.create(dependingPlugins)
.format(p -> messages.getMessage(
"serverutils.depending_plugins.format",
"%plugin%", pluginManager.getPluginId(p)
MessagesResource.Message dependingPluginsFormat = messages.get(MessageKey.DEPENDING_PLUGINS_FORMAT);
builder.append(ListComponentBuilder.create(dependingPlugins)
.format(p -> dependingPluginsFormat.toComponent(
Template.of("plugin", pluginManager.getPluginId(p))
))
.seperator(messages.getMessage("serverutils.depending_plugins.separator"))
.lastSeperator(messages.getMessage("serverutils.depending_plugins.last_separator"))
.toString();
messages.sendRawMessage(sender, prefixString + dependingPluginsString);
.separator(messages.get(MessageKey.DEPENDING_PLUGINS_SEPARATOR).toComponent())
.lastSeparator(messages.get(MessageKey.DEPENDING_PLUGINS_LAST_SEPARATOR).toComponent())
.build());
builder.append(Component.newline());
hasDependingPlugins = true;
}
}
@ -249,12 +258,13 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
.min(Comparator.comparingInt(String::length))
.orElse("-f");
messages.sendMessage(sender,
"serverutils.depending_plugins.override",
"%command%", context.getRawInputJoined() + " " + forceFlag
);
builder.append(messages.get(MessageKey.DEPENDING_PLUGINS_OVERRIDE).toComponent(
Template.of("command", context.getRawInputJoined() + " " + forceFlag)
));
}
sender.sendMessage(builder.build());
return hasDependingPlugins;
}
@ -266,8 +276,8 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
return;
}
WatchResult result = plugin.getWatchManager().watchPlugins(sender, plugins);
result.sendTo(sender);
PluginWatchResults watchResults = plugin.getWatchManager().watchPlugins(sender, plugins);
watchResults.sendTo(sender);
}
private void handleUnwatchPlugin(CommandContext<C> context) {
@ -275,8 +285,8 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
P pluginArg = context.get("plugin");
String pluginId = plugin.getPluginManager().getPluginId(pluginArg);
WatchResult result = plugin.getWatchManager().unwatchPluginsAssociatedWith(pluginId);
result.sendTo(sender);
PluginWatchResults watchResults = plugin.getWatchManager().unwatchPluginsAssociatedWith(pluginId);
watchResults.sendTo(sender);
}
private void handlePluginInfo(CommandContext<C> context) {
@ -286,9 +296,9 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
createInfo(sender, "plugininfo", pluginArg, this::createPluginInfo);
}
protected abstract FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected abstract KeyValueComponentBuilder createPluginInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
P pluginArg
);
@ -297,51 +307,54 @@ public abstract class CommandServerUtils<U extends ServerUtilsPlugin<P, ?, C, ?,
String commandName = context.get("command");
if (!plugin.getPluginManager().getCommands().contains(commandName)) {
plugin.getMessagesResource().sendMessage(sender, "serverutils.commandinfo.not_exists");
plugin.getMessagesResource().get(MessageKey.COMMANDINFO_NOT_EXISTS).sendTo(sender);
return;
}
createInfo(sender, "commandinfo", commandName, this::createCommandInfo);
}
protected abstract FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected abstract KeyValueComponentBuilder createCommandInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
String commandName
);
private <T> void createInfo(C sender, String command, T item, InfoCreator<T> 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");
MessagesResource messages = plugin.getMessagesResource();
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
String messagePrefix = "messages." + command;
MessagesResource.Message formatMessage = messages.get(messagePrefix + ".format");
MessagesResource.Message listFormatMessage = messages.get(messagePrefix + ".list-format");
Component separator = messages.get(messagePrefix + ".list-separator").toComponent();
Component lastSeparator = messages.get(messagePrefix + ".list-last-separator").toComponent();
TextComponent.Builder builder = Component.text()
.append(messages.get(messagePrefix + ".header").toComponent())
.append(Component.newline());
plugin.getMessagesResource().sendMessage(sender, messagePrefix + ".header");
creator.createInfo(
FormatBuilder
.create(format)
.orderedKeys("%key%", "%value%"),
KeyValueComponentBuilder.create(formatMessage, "key", "value"),
listBuilderConsumer -> {
ListBuilder<String> builder = ListBuilder.<String>create()
.format(listFormat)
.seperator(seperator)
.lastSeperator(lastSeperator);
listBuilderConsumer.accept(builder);
return builder.toString();
ListComponentBuilder<String> listBuilder = ListComponentBuilder.<String>create()
.format(str -> listFormatMessage.toComponent(Template.of("value", str)))
.separator(separator)
.lastSeparator(lastSeparator);
listBuilderConsumer.accept(listBuilder);
return listBuilder.build();
},
item
).build().forEach(str -> plugin.getMessagesResource().sendRawMessage(sender, str));
plugin.getMessagesResource().sendMessage(sender, messagePrefix + ".footer");
);
builder.append(messages.get(messagePrefix + ".footer").toComponent());
sender.sendMessage(builder.build());
}
private interface InfoCreator<T> {
FormatBuilder createInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
KeyValueComponentBuilder createInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
T item
);
}

View file

@ -12,10 +12,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public abstract class ServerUtilsCommand<U extends ServerUtilsPlugin<?, ?, C, ?, ?>, C extends ServerCommandSender<?>> {
public abstract class ServerUtilsCommand<U extends ServerUtilsPlugin<?, ?, C, ?, ?>, C extends ServerUtilsAudience<?>> {
protected final U plugin;
protected final String commandName;

View file

@ -11,10 +11,10 @@ import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public class JarFilesArgument<C extends ServerCommandSender<?>> extends CommandArgument<C, File[]> {
public class JarFilesArgument<C extends ServerUtilsAudience<?>> extends CommandArgument<C, File[]> {
/**
* Constructs a Jar Files argument.
@ -30,7 +30,7 @@ public class JarFilesArgument<C extends ServerCommandSender<?>> extends CommandA
);
}
public static final class JarFilesParser<C extends ServerCommandSender<?>> implements ArgumentParser<C, File[]> {
public static final class JarFilesParser<C extends ServerUtilsAudience<?>> implements ArgumentParser<C, File[]> {
private final ServerUtilsPlugin<?, ?, C, ?, ?> plugin;

View file

@ -9,10 +9,10 @@ import io.leangen.geantyref.TypeToken;
import java.util.List;
import java.util.Optional;
import java.util.Queue;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public class PluginArgument<C extends ServerCommandSender<?>, P> extends CommandArgument<C, P> {
public class PluginArgument<C extends ServerUtilsAudience<?>, P> extends CommandArgument<C, P> {
/**
* Constructs a Plugin argument.
@ -28,7 +28,7 @@ public class PluginArgument<C extends ServerCommandSender<?>, P> extends Command
);
}
public static final class PluginParser<C extends ServerCommandSender<?>, P> implements ArgumentParser<C, P> {
public static final class PluginParser<C extends ServerUtilsAudience<?>, P> implements ArgumentParser<C, P> {
private final ServerUtilsPlugin<P, ?, C, ?, ?> plugin;

View file

@ -12,10 +12,10 @@ import java.util.Optional;
import java.util.Queue;
import java.util.Set;
import java.util.function.IntFunction;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public class PluginsArgument<C extends ServerCommandSender<?>, P> extends CommandArgument<C, P[]> {
public class PluginsArgument<C extends ServerUtilsAudience<?>, P> extends CommandArgument<C, P[]> {
/**
* Constructs a Plugins argument.
@ -35,7 +35,7 @@ public class PluginsArgument<C extends ServerCommandSender<?>, P> extends Comman
);
}
public static final class PluginsParser<C extends ServerCommandSender<?>, P> implements ArgumentParser<C, P[]> {
public static final class PluginsParser<C extends ServerUtilsAudience<?>, P> implements ArgumentParser<C, P[]> {
private final ServerUtilsPlugin<P, ?, C, ?, ?> plugin;
private final IntFunction<P[]> arrayCreator;

View file

@ -5,9 +5,9 @@ import com.mojang.brigadier.arguments.StringArgumentType;
import io.leangen.geantyref.TypeToken;
import net.frankheijden.serverutils.common.commands.arguments.JarFilesArgument;
import net.frankheijden.serverutils.common.commands.arguments.PluginsArgument;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
public class BrigadierHandler<C extends ServerCommandSender<?>, P> {
public class BrigadierHandler<C extends ServerUtilsAudience<?>, P> {
private final CloudBrigadierManager<C, ?> brigadierManager;

View file

@ -0,0 +1,7 @@
package net.frankheijden.serverutils.common.config;
public interface ConfigKey {
String getPath();
}

View file

@ -0,0 +1,89 @@
package net.frankheijden.serverutils.common.config;
import java.util.Locale;
public enum MessageKey implements PlaceholderConfigKey {
RELOAD("reload", false),
LOADPLUGIN("loadplugin"),
UNLOADPLUGIN("unloadplugin"),
RELOADPLUGIN("reloadplugin"),
GENERIC_PREFIX("generic.prefix", false),
GENERIC_ERROR("generic.error", false),
GENERIC_NOT_EXISTS("generic.not-exists"),
GENERIC_NOT_ENABLED("generic.not-enabled"),
GENERIC_ALREADY_LOADED("generic.already-loaded"),
GENERIC_ALREADY_ENABLED("generic.already-enabled"),
GENERIC_ALREADY_DISABLED("generic.already-disabled"),
GENERIC_INVALID_PLUGIN("generic.invalid-plugin"),
GENERIC_INVALID_DESCRIPTION("generic.invalid-description"),
GENERIC_UNKNOWN_DEPENDENCY("generic.unknown-dependency"),
GENERIC_FILE_DELETED("generic.file-deleted"),
DEPENDING_PLUGINS_PREFIX("depending-plugins.prefix"),
DEPENDING_PLUGINS_FORMAT("depending-plugins.format"),
DEPENDING_PLUGINS_SEPARATOR("depending-plugins.separator", false),
DEPENDING_PLUGINS_LAST_SEPARATOR("depending-plugins.last-separator", false),
DEPENDING_PLUGINS_OVERRIDE("depending-plugins.override"),
WATCHPLUGIN_START("watchplugin.start"),
WATCHPLUGIN_CHANGE("watchplugin.change", false),
WATCHPLUGIN_STOPPED("watchplugin.stopped"),
WATCHPLUGIN_FILE_DELETED("watchplugin.file-deleted"),
WATCHPLUGIN_DELETED_FILE_IS_CREATED("watchplugin.deleted-file-is-created"),
WATCHPLUGIN_ALREADY_WATCHING("watchplugin.already-watching"),
WATCHPLUGIN_NOT_WATCHING("watchplugin.not-watching"),
UPDATE_AVAILABLE("update.available"),
UPDATE_DOWNLOADING("update.downloading"),
UPDATE_DOWNLOAD_FAILED("update.download-failed"),
UPDATE_DOWNLOAD_SUCCESS("update.download-success", false),
HELP_HEADER("help.header", false),
HELP_FORMAT("help.format"),
HELP_FOOTER("help.footer", false),
PLUGINS_HEADER("plugins.header", false),
PLUGINS_PREFIX("plugins.prefix"),
PLUGINS_FORMAT("plugins.format"),
PLUGINS_FORMAT_DISABLED("plugins.format-disabled"),
PLUGINS_SEPARATOR("plugins.separator", false),
PLUGINS_LAST_SEPARATOR("plugins.last-separator", false),
PLUGINS_VERSION("plugins.version"),
PLUGINS_FOOTER("plugins.footer", false),
PLUGININFO_HEADER("plugininfo.header", false),
PLUGININFO_FORMAT("plugininfo.format"),
PLUGININFO_LIST_FORMAT("plugininfo.list-format"),
PLUGININFO_LIST_SEPARATOR("plugininfo.list-separator", false),
PLUGININFO_LIST_LAST_SEPARATOR("plugininfo.list-last-separator", false),
PLUGININFO_FOOTER("plugininfo.footer", false),
COMMANDINFO_HEADER("commandinfo.header", false),
COMMANDINFO_FORMAT("commandinfo.format"),
COMMANDINFO_LIST_FORMAT("commandinfo.list-format"),
COMMANDINFO_LIST_SEPARATOR("commandinfo.list-separator", false),
COMMANDINFO_LIST_LAST_SEPARATOR("commandinfo.list-last-separator", false),
COMMANDINFO_FOOTER("commandinfo.footer", false),
COMMANDINFO_NOT_EXISTS("commandinfo.not-exists", false),
;
private final String path;
private final boolean hasPlaceholders;
MessageKey(String path) {
this(path, true);
}
MessageKey(String path, boolean hasPlaceholders) {
this.path = path;
this.hasPlaceholders = hasPlaceholders;
}
public static MessageKey fromPath(String path) {
return MessageKey.valueOf(path.replaceAll("\\.|-", "_").toUpperCase(Locale.ENGLISH));
}
@Override
public String getPath() {
return path;
}
@Override
public boolean hasPlaceholders() {
return hasPlaceholders;
}
}

View file

@ -1,56 +1,83 @@
package net.frankheijden.serverutils.common.config;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.utils.StringUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.Template;
public class MessagesResource extends ServerUtilsResource {
public static final String MESSAGES_RESOURCE = "messages";
private final Map<ConfigKey, Message> messageMap;
private final MiniMessage miniMessage;
/**
* Constructs a new MessagesResource.
*/
public MessagesResource(ServerUtilsPlugin<?, ?, ?, ?, ?> plugin) {
super(plugin, MESSAGES_RESOURCE);
this.messageMap = new HashMap<>();
this.miniMessage = MiniMessage.get();
}
public Message get(String path) {
return get(MessageKey.fromPath(path));
}
public Message get(ConfigKey key) {
return messageMap.get(key);
}
/**
* 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.
* Loads message keys and pre-compiles them if possible.
*/
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));
public void load(Collection<? extends PlaceholderConfigKey> keys) {
for (PlaceholderConfigKey key : keys) {
this.messageMap.put(key, new Message(key));
}
}
/**
* 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));
public class Message {
private final PlaceholderConfigKey key;
private final String messageString;
private final Component component;
/**
* Constructs a new Message.
*/
public Message(PlaceholderConfigKey key) {
this.key = key;
this.messageString = getConfig().getString("messages." + key.getPath());
this.component = key.hasPlaceholders() ? null : miniMessage.parse(messageString);
}
/**
* Creates a {@link Component}.
*/
public Component toComponent(Template... placeholders) {
if (this.component == null) {
if (placeholders.length == 0) {
throw new IllegalArgumentException("Message '" + key + "' has placeholders"
+ " but none were provided!");
}
return miniMessage.parse(messageString, placeholders);
} else if (placeholders.length != 0) {
throw new IllegalArgumentException("Message '" + key + "' does not have placeholders"
+ " but the following placeholders were provided: " + Arrays.toString(placeholders));
} else {
return this.component;
}
}
public void sendTo(ServerUtilsAudience<?> serverAudience, Template... placeholders) {
serverAudience.sendMessage(toComponent(placeholders));
}
}

View file

@ -0,0 +1,7 @@
package net.frankheijden.serverutils.common.config;
public interface PlaceholderConfigKey extends ConfigKey {
boolean hasPlaceholders();
}

View file

@ -1,31 +0,0 @@
package net.frankheijden.serverutils.common.entities;
/**
* A basic wrapper for a CommandSender.
*/
public interface ServerCommandSender<C> {
/**
* Sends a message to a CommandSender.
* @param message The message to send.
*/
void sendMessage(String message);
/**
* Checks if the CommandSender has a permission.
* @param permission The permission to check.
* @return Whether or not they have the permission.
*/
boolean hasPermission(String permission);
/**
* Whether or not the given instance is a player.
* @return Boolean true or false.
*/
boolean isPlayer();
/**
* Returns the server specific implementation source.
*/
C getSource();
}

View file

@ -0,0 +1,27 @@
package net.frankheijden.serverutils.common.entities;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
public abstract class ServerUtilsAudience<C> {
protected final Audience audience;
protected final C source;
protected ServerUtilsAudience(Audience audience, C source) {
this.audience = audience;
this.source = source;
}
public abstract boolean isPlayer();
public abstract boolean hasPermission(String permission);
public void sendMessage(Component component) {
audience.sendMessage(component);
}
public C getSource() {
return this.source;
}
}

View file

@ -7,28 +7,30 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Logger;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.commands.brigadier.BrigadierHandler;
import net.frankheijden.serverutils.common.config.CommandsResource;
import net.frankheijden.serverutils.common.config.ConfigResource;
import net.frankheijden.serverutils.common.config.MessageKey;
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;
import net.frankheijden.serverutils.common.managers.WatchManager;
import net.frankheijden.serverutils.common.providers.ChatProvider;
import net.frankheijden.serverutils.common.providers.ResourceProvider;
import net.frankheijden.serverutils.common.providers.ServerUtilsAudienceProvider;
import net.frankheijden.serverutils.common.utils.FileUtils;
public abstract class ServerUtilsPlugin<P, T, C extends ServerCommandSender<S>, S, D extends ServerUtilsPluginDescription> {
public abstract class ServerUtilsPlugin<P, T, C extends ServerUtilsAudience<S>, S, D extends ServerUtilsPluginDescription> {
private final UpdateManager updateManager = new UpdateManager();
private final WatchManager<P, T> watchManager = new WatchManager<>(this);
private CommandsResource commandsResource;
private ConfigResource configResource;
private MessagesResource messagesResource;
protected MessagesResource messagesResource;
protected CommandManager<C> commandManager;
public abstract Platform getPlatform();
@ -53,7 +55,7 @@ public abstract class ServerUtilsPlugin<P, T, C extends ServerCommandSender<S>,
public abstract ResourceProvider getResourceProvider();
public abstract ChatProvider<C, S> getChatProvider();
public abstract ServerUtilsAudienceProvider<S> getChatProvider();
public UpdateManager getUpdateManager() {
return updateManager;
@ -143,6 +145,7 @@ public abstract class ServerUtilsPlugin<P, T, C extends ServerCommandSender<S>,
this.commandsResource = new CommandsResource(this);
this.configResource = new ConfigResource(this);
this.messagesResource = new MessagesResource(this);
this.messagesResource.load(Arrays.asList(MessageKey.values()));
this.commandManager = newCommandManager();
reloadPlugin();
}

View file

@ -1,15 +1,9 @@
package net.frankheijden.serverutils.common.entities.results;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.config.ConfigKey;
public interface AbstractResult {
/**
* Retrieves the associated message of the result
* and sends it to a CommandSender.
* @param sender The receiver.
* @param action The action which let to the result.
* @param what An associated variable.
*/
void sendTo(ServerCommandSender<?> sender, String action, String what);
ConfigKey getKey();
}

View file

@ -4,6 +4,7 @@ import java.io.Closeable;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import net.kyori.adventure.text.minimessage.Template;
public class CloseablePluginResult<T> extends PluginResult<T> implements Closeable {
@ -14,8 +15,14 @@ public class CloseablePluginResult<T> extends PluginResult<T> implements Closeab
this.closeables = Collections.emptyList();
}
public CloseablePluginResult(String pluginId, T plugin, Result result, List<Closeable> closeables) {
super(pluginId, plugin, result);
public CloseablePluginResult(
String pluginId,
T plugin,
Result result,
List<Closeable> closeables,
Template... templates
) {
super(pluginId, plugin, result, templates);
this.closeables = closeables;
}

View file

@ -3,6 +3,7 @@ package net.frankheijden.serverutils.common.entities.results;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import net.kyori.adventure.text.minimessage.Template;
public class CloseablePluginResults<T> extends PluginResults<T> implements Closeable {
@ -16,25 +17,31 @@ public class CloseablePluginResults<T> extends PluginResults<T> implements Close
}
@Override
public CloseablePluginResults<T> addResult(String pluginId, Result result) {
super.addResult(pluginId, result);
public CloseablePluginResults<T> addResult(String pluginId, Result result, Template... templates) {
super.addResult(pluginId, result, templates);
return this;
}
@Override
public CloseablePluginResults<T> addResult(String pluginId, T plugin) {
super.addResult(pluginId, plugin);
public CloseablePluginResults<T> addResult(String pluginId, T plugin, Template... templates) {
super.addResult(pluginId, plugin, templates);
return this;
}
@Override
protected CloseablePluginResults<T> addResult(String pluginId, T plugin, Result result) {
super.addResult(pluginId, plugin, result);
protected CloseablePluginResults<T> addResult(String pluginId, T plugin, Result result, Template... templates
) {
super.addResult(pluginId, plugin, result, templates);
return this;
}
public CloseablePluginResults<T> addResult(String pluginId, T plugin, List<Closeable> closeables) {
return addResult(new CloseablePluginResult<>(pluginId, plugin, Result.SUCCESS, closeables));
public CloseablePluginResults<T> addResult(
String pluginId,
T plugin,
List<Closeable> closeables,
Template... templates
) {
return addResult(new CloseablePluginResult<>(pluginId, plugin, Result.SUCCESS, closeables, templates));
}
@Override

View file

@ -1,10 +1,16 @@
package net.frankheijden.serverutils.common.entities.results;
public class PluginResult<T> {
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.ConfigKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Template;
public class PluginResult<T> implements AbstractResult {
private final String pluginId;
private final T plugin;
private final Result result;
private final Template[] templates;
public PluginResult(String pluginId, Result result) {
this(pluginId, null, result);
@ -13,10 +19,13 @@ public class PluginResult<T> {
/**
* Constructs a new PluginResult.
*/
public PluginResult(String pluginId, T plugin, Result result) {
public PluginResult(String pluginId, T plugin, Result result, Template... templates) {
this.pluginId = pluginId;
this.plugin = plugin;
this.result = result;
this.templates = new Template[templates.length + 1];
this.templates[0] = Template.of("plugin", pluginId);
System.arraycopy(templates, 0, this.templates, 1, templates.length);
}
public String getPluginId() {
@ -31,7 +40,21 @@ public class PluginResult<T> {
return result;
}
public Template[] getTemplates() {
return templates;
}
public boolean isSuccess() {
return plugin != null && result == Result.SUCCESS;
}
public Component toComponent(ConfigKey successKey) {
ConfigKey key = isSuccess() ? successKey : result.getKey();
return ServerUtilsApp.getPlugin().getMessagesResource().get(key).toComponent(templates);
}
@Override
public ConfigKey getKey() {
return result.getKey();
}
}

View file

@ -3,7 +3,10 @@ package net.frankheijden.serverutils.common.entities.results;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.config.ConfigKey;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
public class PluginResults<T> implements Iterable<PluginResult<T>> {
@ -13,18 +16,18 @@ public class PluginResults<T> implements Iterable<PluginResult<T>> {
this.results = new ArrayList<>();
}
public PluginResults<T> addResult(String pluginId, Result result) {
addResult(pluginId, null, result);
public PluginResults<T> addResult(String pluginId, Result result, Template... templates) {
addResult(pluginId, null, result, templates);
return this;
}
public PluginResults<T> addResult(String pluginId, T plugin) {
addResult(pluginId, plugin, Result.SUCCESS);
public PluginResults<T> addResult(String pluginId, T plugin, Template... templates) {
addResult(pluginId, plugin, Result.SUCCESS, templates);
return this;
}
protected PluginResults<T> addResult(String pluginId, T plugin, Result result) {
addResult(new PluginResult<>(pluginId, plugin, result));
protected PluginResults<T> addResult(String pluginId, T plugin, Result result, Template... templates) {
addResult(new PluginResult<>(pluginId, plugin, result, templates));
return this;
}
@ -65,12 +68,14 @@ public class PluginResults<T> implements Iterable<PluginResult<T>> {
}
/**
* Sends the results to given receiver.
* Creates a {@link Component}.
*/
public void sendTo(ServerCommandSender<?> sender, String action) {
public Component toComponent(ConfigKey successKey) {
TextComponent.Builder builder = Component.text();
for (PluginResult<T> result : results) {
result.getResult().sendTo(sender, action, result.getPluginId());
builder.append(result.toComponent(successKey));
}
return builder.build();
}
@Override

View file

@ -0,0 +1,28 @@
package net.frankheijden.serverutils.common.entities.results;
import net.frankheijden.serverutils.common.config.ConfigKey;
import net.kyori.adventure.text.minimessage.Template;
public class PluginWatchResult implements AbstractResult {
private final WatchResult result;
private final Template[] templates;
public PluginWatchResult(WatchResult result, Template... templates) {
this.result = result;
this.templates = templates;
}
public WatchResult getResult() {
return result;
}
public Template[] getTemplates() {
return templates;
}
@Override
public ConfigKey getKey() {
return null;
}
}

View file

@ -0,0 +1,47 @@
package net.frankheijden.serverutils.common.entities.results;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
public class PluginWatchResults implements Iterable<PluginWatchResult> {
private final List<PluginWatchResult> watchResults;
public PluginWatchResults() {
this.watchResults = new ArrayList<>();
}
public PluginWatchResults add(WatchResult result, Template... templates) {
return add(new PluginWatchResult(result, templates));
}
public PluginWatchResults add(PluginWatchResult watchResult) {
this.watchResults.add(watchResult);
return this;
}
/**
* Sends the result(s) to the given sender.
*/
public void sendTo(ServerUtilsAudience<?> sender) {
MessagesResource messages = ServerUtilsApp.getPlugin().getMessagesResource();
TextComponent.Builder builder = Component.text();
for (PluginWatchResult watchResult : watchResults) {
builder.append(messages.get(watchResult.getKey()).toComponent(watchResult.getTemplates()));
}
sender.sendMessage(builder.build());
}
@Override
public Iterator<PluginWatchResult> iterator() {
return watchResults.iterator();
}
}

View file

@ -1,58 +1,31 @@
package net.frankheijden.serverutils.common.entities.results;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.config.MessageKey;
/**
* An enum containing possible results.
*/
public enum Result implements AbstractResult {
NOT_EXISTS,
NOT_ENABLED,
ALREADY_LOADED,
ALREADY_ENABLED,
ALREADY_DISABLED,
FILE_DELETED,
INVALID_DESCRIPTION,
INVALID_PLUGIN,
UNKNOWN_DEPENDENCY,
ERROR,
SUCCESS;
NOT_EXISTS(MessageKey.GENERIC_NOT_EXISTS),
NOT_ENABLED(MessageKey.GENERIC_NOT_ENABLED),
ALREADY_LOADED(MessageKey.GENERIC_ALREADY_LOADED),
ALREADY_ENABLED(MessageKey.GENERIC_ALREADY_ENABLED),
ALREADY_DISABLED(MessageKey.GENERIC_ALREADY_DISABLED),
FILE_DELETED(MessageKey.GENERIC_FILE_DELETED),
INVALID_DESCRIPTION(MessageKey.GENERIC_INVALID_DESCRIPTION),
INVALID_PLUGIN(MessageKey.GENERIC_INVALID_PLUGIN),
UNKNOWN_DEPENDENCY(MessageKey.GENERIC_UNKNOWN_DEPENDENCY),
ERROR(MessageKey.GENERIC_ERROR),
SUCCESS(null),
;
private String arg;
private final MessageKey key;
/**
* private constructor which initializes a result with an empty argument.
*/
Result() {
this.arg = "";
Result(MessageKey key) {
this.key = key;
}
/**
* Sets the argument of the result's message.
* @param arg The argument
* @return The current instance.
*/
public Result arg(String arg) {
this.arg = arg;
return this;
}
/**
* Retrieves the associated message of the result
* and sends it to a CommandSender.
* @param sender The receiver.
* @param action The action which let to the result.
* @param what An associated variable.
*/
@Override
public void sendTo(ServerCommandSender<?> sender, String action, String what) {
ServerUtilsApp.getPlugin().getMessagesResource().sendMessage(
sender,
"serverutils." + this.name().toLowerCase(),
"%action%", action,
"%what%", what,
"%arg%", arg
);
public MessageKey getKey() {
return key;
}
}

View file

@ -1,60 +1,35 @@
package net.frankheijden.serverutils.common.entities.results;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.frankheijden.serverutils.common.ServerUtilsApp;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.config.ConfigKey;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Template;
public enum WatchResult implements AbstractResult {
START(MessageKey.WATCHPLUGIN_START),
CHANGE(MessageKey.WATCHPLUGIN_CHANGE),
ALREADY_WATCHING(MessageKey.WATCHPLUGIN_ALREADY_WATCHING),
NOT_WATCHING(MessageKey.WATCHPLUGIN_NOT_WATCHING),
FILE_DELETED(MessageKey.WATCHPLUGIN_FILE_DELETED),
DELETED_FILE_IS_CREATED(MessageKey.WATCHPLUGIN_DELETED_FILE_IS_CREATED),
STOPPED(MessageKey.WATCHPLUGIN_STOPPED),
;
START,
CHANGE,
ALREADY_WATCHING,
NOT_WATCHING,
FILE_DELETED,
DELETED_FILE_IS_CREATED,
STOPPED;
private final ConfigKey key;
private List<String> args = null;
public WatchResult arg(String arg) {
return args(Collections.singletonList(arg));
WatchResult(ConfigKey key) {
this.key = key;
}
public WatchResult args(List<String> args) {
this.args = args;
return this;
public void sendTo(ServerUtilsAudience<?> sender, Template... templates) {
Component component = ServerUtilsApp.getPlugin().getMessagesResource().get(key).toComponent(templates);
sender.sendMessage(component);
}
@Override
public void sendTo(ServerCommandSender<?> sender, String action, String what) {
arg(what);
sendTo(sender);
}
/**
* Sends the result(s) to the console and specified sender.
*/
public void sendTo(ServerCommandSender<?> sender) {
String path = "serverutils.watchplugin." + this.name().toLowerCase();
List<String[]> sendArguments = new ArrayList<>();
if (args == null || args.isEmpty()) {
sendArguments.add(new String[0]);
} else {
for (String what : args) {
sendArguments.add(new String[] { "%what%", what });
}
}
MessagesResource messages = ServerUtilsApp.getPlugin().getMessagesResource();
ServerCommandSender<?> console = ServerUtilsApp.getPlugin().getChatProvider().getConsoleSender();
for (String[] replacements : sendArguments) {
messages.sendMessage(sender, path, replacements);
if (sender.isPlayer()) {
messages.sendMessage(console, path, replacements);
}
}
public ConfigKey getKey() {
return key;
}
}

View file

@ -1,10 +1,10 @@
package net.frankheijden.serverutils.common.listeners;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.tasks.UpdateCheckerTask;
public abstract class PlayerListener<U extends ServerUtilsPlugin<P, ?, C, ?, ?>, P, C extends ServerCommandSender<?>>
public abstract class PlayerListener<U extends ServerUtilsPlugin<P, ?, C, ?, ?>, P, C extends ServerUtilsAudience<?>>
extends ServerUtilsListener<U, C> {
protected PlayerListener(U plugin) {

View file

@ -1,9 +1,9 @@
package net.frankheijden.serverutils.common.listeners;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
public abstract class ServerUtilsListener<U extends ServerUtilsPlugin<?, ?, C, ?, ?>, C extends ServerCommandSender<?>> {
public abstract class ServerUtilsListener<U extends ServerUtilsPlugin<?, ?, C, ?, ?>, C extends ServerUtilsAudience<?>> {
protected final U plugin;

View file

@ -5,10 +5,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.entities.results.PluginWatchResults;
import net.frankheijden.serverutils.common.entities.results.WatchResult;
import net.frankheijden.serverutils.common.tasks.PluginWatcherTask;
import net.kyori.adventure.text.minimessage.Template;
public class WatchManager<P, T> {
@ -23,12 +25,12 @@ public class WatchManager<P, T> {
/**
* Starts watching the specified plugin and reloads it when a change is detected.
*/
public WatchResult watchPlugins(ServerCommandSender<?> sender, List<P> plugins) {
public PluginWatchResults watchPlugins(ServerUtilsAudience<?> sender, List<P> plugins) {
List<String> pluginIds = new ArrayList<>(plugins.size());
for (P watchPlugin : plugins) {
String pluginId = plugin.getPluginManager().getPluginId(watchPlugin);
if (watchTasks.containsKey(pluginId)) {
return WatchResult.ALREADY_WATCHING.arg(pluginId);
return new PluginWatchResults().add(WatchResult.ALREADY_WATCHING, Template.of("plugin", pluginId));
}
pluginIds.add(plugin.getPluginManager().getPluginId(watchPlugin));
@ -45,19 +47,28 @@ public class WatchManager<P, T> {
watchTasks.put(pluginId, watchTask);
}
return WatchResult.START.args(pluginIds);
PluginWatchResults watchResults = new PluginWatchResults();
for (String pluginId : pluginIds) {
watchResults.add(WatchResult.START, Template.of("plugin", pluginId));
}
return watchResults;
}
/**
* Stops watching plugins for changes.
*/
public WatchResult unwatchPluginsAssociatedWith(String pluginId) {
WatchTask task = watchTasks.get(pluginId);
public PluginWatchResults unwatchPluginsAssociatedWith(String associatedPluginId) {
WatchTask task = watchTasks.get(associatedPluginId);
if (task != null && plugin.getTaskManager().cancelTask(task.key.toString())) {
task.pluginIds.forEach(watchTasks::remove);
return WatchResult.STOPPED.args(task.pluginIds);
PluginWatchResults watchResults = new PluginWatchResults();
for (String pluginId : task.pluginIds) {
watchResults.add(WatchResult.START, Template.of("plugin", pluginId));
}
return watchResults;
}
return WatchResult.NOT_WATCHING.arg(pluginId);
return new PluginWatchResults().add(WatchResult.NOT_WATCHING, Template.of("plugin", associatedPluginId));
}
private static final class WatchTask {

View file

@ -1,34 +0,0 @@
package net.frankheijden.serverutils.common.providers;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
/**
* A basic chat provider class.
*/
public interface ChatProvider<C extends ServerCommandSender<T>, T> {
/**
* Retrieves the console sender of a server instance.
* @return The console sender.
*/
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.
*/
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.
*/
void broadcast(String permission, String message);
}

View file

@ -0,0 +1,22 @@
package net.frankheijden.serverutils.common.providers;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.text.Component;
public interface ServerUtilsAudienceProvider<S> {
/**
* Retrieves the console ServerAudience.
*/
ServerUtilsAudience<S> getConsoleServerAudience();
/**
* Converts the given source (specific to impl) to an ServerAudience.
*/
ServerUtilsAudience<S> get(S source);
/**
* Broadcasts a message to all with given permission.
*/
void broadcast(Component component, String permission);
}

View file

@ -17,8 +17,9 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.entities.AbstractTask;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.entities.ServerUtilsPluginDescription;
import net.frankheijden.serverutils.common.entities.exceptions.InvalidPluginDescriptionException;
@ -27,6 +28,7 @@ import net.frankheijden.serverutils.common.entities.results.PluginResults;
import net.frankheijden.serverutils.common.entities.results.WatchResult;
import net.frankheijden.serverutils.common.managers.AbstractPluginManager;
import net.frankheijden.serverutils.common.utils.FileUtils;
import net.kyori.adventure.text.minimessage.Template;
public class PluginWatcherTask<P, T> extends AbstractTask {
@ -37,7 +39,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
};
private final ServerUtilsPlugin<P, T, ?, ?, ?> plugin;
private final ServerCommandSender<?> sender;
private final ServerUtilsAudience<?> sender;
private final Map<String, WatchEntry> fileNameToWatchEntryMap;
private final Map<String, WatchEntry> pluginIdToWatchEntryMap;
@ -48,7 +50,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
/**
* Constructs a new PluginWatcherTask for the specified plugin.
*/
public PluginWatcherTask(ServerUtilsPlugin<P, T, ?, ?, ?> plugin, ServerCommandSender<?> sender, List<P> plugins) {
public PluginWatcherTask(ServerUtilsPlugin<P, T, ?, ?, ?> plugin, ServerUtilsAudience<?> sender, List<P> plugins) {
this.plugin = plugin;
this.sender = sender;
this.fileNameToWatchEntryMap = new HashMap<>();
@ -114,7 +116,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
ServerUtilsPluginDescription description = descriptionOptional.get();
WatchEntry foundEntry = pluginIdToWatchEntryMap.remove(description.getId());
if (foundEntry != null) {
send(WatchResult.DELETED_FILE_IS_CREATED.arg(foundEntry.pluginId));
send(WatchResult.DELETED_FILE_IS_CREATED, Template.of("plugin", foundEntry.pluginId));
fileNameToWatchEntryMap.put(fileName, foundEntry);
if (pluginIdToWatchEntryMap.isEmpty()) {
@ -137,7 +139,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
AbstractPluginManager<P, ?> pluginManager = plugin.getPluginManager();
Optional<File> fileOptional = pluginManager.getPluginFile(entry.pluginId);
if (!fileOptional.isPresent()) {
send(WatchResult.FILE_DELETED.arg(entry.pluginId));
send(WatchResult.FILE_DELETED, Template.of("plugin", entry.pluginId));
fileNameToWatchEntryMap.remove(fileName);
pluginIdToWatchEntryMap.put(entry.pluginId, entry);
@ -165,7 +167,7 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
fileNameToWatchEntryMap.clear();
PluginResults<P> reloadResults = pluginManager.reloadPlugins(plugins);
reloadResults.sendTo(sender, "reload");
sender.sendMessage(reloadResults.toComponent(MessageKey.RELOADPLUGIN));
for (PluginResult<P> reloadResult : reloadResults) {
if (!reloadResult.isSuccess()) continue;
@ -181,10 +183,10 @@ public class PluginWatcherTask<P, T> extends AbstractTask {
}, 10L);
}
private void send(WatchResult result) {
result.sendTo(sender);
private void send(WatchResult result, Template... templates) {
result.sendTo(sender, templates);
if (sender.isPlayer()) {
result.sendTo(plugin.getChatProvider().getConsoleSender());
result.sendTo(plugin.getChatProvider().getConsoleServerAudience(), templates);
}
}

View file

@ -10,10 +10,12 @@ 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.ConfigKey;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.config.ServerUtilsConfig;
import net.frankheijden.serverutils.common.entities.results.PluginResult;
import net.frankheijden.serverutils.common.entities.results.Result;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.frankheijden.serverutils.common.entities.ServerUtilsPlugin;
import net.frankheijden.serverutils.common.entities.http.GitHubAsset;
import net.frankheijden.serverutils.common.entities.http.GitHubResponse;
@ -21,11 +23,13 @@ import net.frankheijden.serverutils.common.managers.UpdateManager;
import net.frankheijden.serverutils.common.utils.GitHubUtils;
import net.frankheijden.serverutils.common.utils.VersionUtils;
import net.frankheijden.serverutilsupdater.common.Updater;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Template;
public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> implements Runnable {
private final U plugin;
private final ServerCommandSender<?> sender;
private final ServerUtilsAudience<?> sender;
private final boolean download;
private final boolean install;
@ -49,7 +53,7 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
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(U plugin, ServerCommandSender<?> sender, boolean download, boolean install) {
private UpdateCheckerTask(U plugin, ServerUtilsAudience<?> sender, boolean download, boolean install) {
this.plugin = plugin;
this.sender = sender;
this.download = download;
@ -62,7 +66,7 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
*/
public static <U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> void tryStart(
U plugin,
ServerCommandSender<?> sender,
ServerUtilsAudience<?> sender,
String action
) {
ServerUtilsConfig config = ServerUtilsApp.getPlugin().getConfigResource().getConfig();
@ -77,7 +81,7 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
*/
public static <U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> void start(
U plugin,
ServerCommandSender<?> sender,
ServerUtilsAudience<?> sender,
String action
) {
ServerUtilsConfig config = ServerUtilsApp.getPlugin().getConfigResource().getConfig();
@ -121,20 +125,24 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
GitHubAsset pluginAsset = GitHubAsset.from(pluginJson);
if (!download || pluginAsset == null) {
if (sender.isPlayer()) {
plugin.getMessagesResource().sendMessage(sender, "serverutils.update.available",
"%old%", ServerUtilsApp.VERSION,
"%new%", githubVersion,
"%info%", body);
Component component = plugin.getMessagesResource().get(MessageKey.UPDATE_AVAILABLE).toComponent(
Template.of("old", ServerUtilsApp.VERSION),
Template.of("new", githubVersion),
Template.of("info", body)
);
sender.sendMessage(component);
}
return;
}
plugin.getLogger().log(Level.INFO, DOWNLOAD_START, pluginAsset.getDownloadUrl());
if (sender.isPlayer()) {
plugin.getMessagesResource().sendMessage(sender, "serverutils.update.downloading",
"%old%", ServerUtilsApp.VERSION,
"%new%", githubVersion,
"%info%", body);
Component component = plugin.getMessagesResource().get(MessageKey.UPDATE_DOWNLOADING).toComponent(
Template.of("old", ServerUtilsApp.VERSION),
Template.of("new", githubVersion),
Template.of("info", body)
);
sender.sendMessage(component);
}
File pluginTarget = new File(plugin.getPluginManager().getPluginsFolder(), pluginAsset.getName());
@ -260,8 +268,8 @@ public class UpdateCheckerTask<U extends ServerUtilsPlugin<P, ?, ?, ?, ?>, P> im
}
private void broadcastDownloadStatus(String githubVersion, boolean isError) {
final String path = "serverutils.update." + (isError ? "failed" : "success");
String message = plugin.getMessagesResource().getMessage(path, "%new%", githubVersion);
plugin.getChatProvider().broadcast("serverutils.notification.update", message);
ConfigKey key = isError ? MessageKey.UPDATE_DOWNLOAD_FAILED : MessageKey.UPDATE_DOWNLOAD_SUCCESS;
Component component = plugin.getMessagesResource().get(key).toComponent(Template.of("new", githubVersion));
plugin.getChatProvider().broadcast(component, "serverutils.notification.update");
}
}

View file

@ -1,63 +0,0 @@
package net.frankheijden.serverutils.common.utils;
import java.util.ArrayList;
import java.util.List;
public class FormatBuilder {
private final String format;
private final List<String[]> valueList;
private String[] orderedKeys;
private boolean skipEmpty;
private FormatBuilder(String format) {
this.format = format;
this.valueList = new ArrayList<>();
this.orderedKeys = new String[0];
this.skipEmpty = true;
}
public static FormatBuilder create(String format) {
return new FormatBuilder(format);
}
public FormatBuilder orderedKeys(String... orderedKeys) {
this.orderedKeys = orderedKeys;
return this;
}
public FormatBuilder add(String... values) {
this.valueList.add(values);
return this;
}
public FormatBuilder skipEmpty(boolean skipEmpty) {
this.skipEmpty = skipEmpty;
return this;
}
/**
* Builds the current FormatBuilder instance into a list of strings.
*/
public List<String> build() {
List<String> strings = new ArrayList<>();
loop:
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()) && skipEmpty) continue loop;
str = str.replace(orderedKeys[i], String.valueOf(value));
}
strings.add(str);
}
return strings;
}
@Override
public String toString() {
return build().toString();
}
}

View file

@ -2,14 +2,15 @@ package net.frankheijden.serverutils.common.utils;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import net.frankheijden.serverutils.common.entities.ServerCommandSender;
import net.frankheijden.serverutils.common.providers.ChatProvider;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
public class ForwardFilter extends PredicateFilter {
private static final char INFO_COLOR = 'a';
private static final char WARNING_COLOR = '6';
private static final char SEVERE_COLOR = 'c';
private static final NamedTextColor INFO_COLOR = NamedTextColor.GREEN;
private static final NamedTextColor WARNING_COLOR = NamedTextColor.GOLD;
private static final NamedTextColor SEVERE_COLOR = NamedTextColor.RED;
private boolean warnings;
@ -17,13 +18,13 @@ public class ForwardFilter extends PredicateFilter {
* Creates a filter which forwards all output to the sender.
* @param sender The sender to forward logs to.
*/
public ForwardFilter(ChatProvider chatProvider, ServerCommandSender sender) {
public ForwardFilter(ServerUtilsAudience<?> sender) {
this.warnings = false;
setPredicate(rec -> {
char color = getColor(rec.getLevel());
NamedTextColor color = getColor(rec.getLevel());
if (color != INFO_COLOR) warnings = true;
sender.sendMessage(chatProvider.color("&" + color + format(rec)));
sender.sendMessage(Component.text(format(rec), color));
return true;
});
}
@ -32,7 +33,7 @@ public class ForwardFilter extends PredicateFilter {
return warnings;
}
private static char getColor(Level level) {
private static NamedTextColor getColor(Level level) {
if (Level.SEVERE.equals(level)) {
return SEVERE_COLOR;
} else if (Level.WARNING.equals(level)) {

View file

@ -1,43 +0,0 @@
package net.frankheijden.serverutils.common.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Provides basic conversion between the hex format <#FFFFFF> and bukkit hex format &x&F&F&F&F&F&F.
*/
public class HexUtils {
private static final Pattern hexPattern = Pattern.compile("<(#[0-9a-fA-F]{6})>");
private static final char COLOR_CHAR = '&';
/**
* Prefixes each character provided with the color character {@link #COLOR_CHAR}.
* @param color The color to prefix with the color character.
* @return The prefixed color.
*/
public static String convertHexColor(String color) {
StringBuilder sb = new StringBuilder(2 * (color.length() + 1)).append(COLOR_CHAR).append("x");
for (char c : color.toCharArray()) {
sb.append(COLOR_CHAR).append(c);
}
return sb.toString();
}
/**
* Converts the input string to a bukkit readable color string.
* The accepted hex format is `<#FFFFFF>`.
* @param str The input string.
* @return The output converted hex string.
*/
public static String convertHexString(String str) {
StringBuffer sb = new StringBuffer(str.length());
Matcher matcher = hexPattern.matcher(str);
while (matcher.find()) {
String hex = matcher.group();
matcher.appendReplacement(sb, convertHexColor(hex.substring(2, hex.length() - 1)));
}
matcher.appendTail(sb);
return sb.toString();
}
}

View file

@ -0,0 +1,95 @@
package net.frankheijden.serverutils.common.utils;
import java.util.ArrayList;
import java.util.List;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
public class KeyValueComponentBuilder {
private final MessagesResource.Message format;
private final List<Template[]> templatesList;
private final String keyPlaceholder;
private final String valuePlaceholder;
private KeyValueComponentBuilder(
MessagesResource.Message format,
String keyPlaceholder,
String valuePlaceholder
) {
this.format = format;
this.templatesList = new ArrayList<>();
this.keyPlaceholder = keyPlaceholder;
this.valuePlaceholder = valuePlaceholder;
}
/**
* Constructs a new KeyValueComponentBuilder.
*/
public static KeyValueComponentBuilder create(
MessagesResource.Message format,
String keyPlaceholder,
String valuePlaceholder
) {
return new KeyValueComponentBuilder(format, keyPlaceholder, valuePlaceholder);
}
/**
* Adds an entry.
*/
public KeyValueComponentBuilder add(String key, String value) {
if (value != null) this.templatesList.add(new Template[]{
Template.of(keyPlaceholder, key),
Template.of(valuePlaceholder, value)
});
return this;
}
/**
* Adds an entry.
*/
public KeyValueComponentBuilder add(String key, Component value) {
if (value != null) this.templatesList.add(new Template[]{
Template.of(keyPlaceholder, key),
Template.of(valuePlaceholder, value)
});
return this;
}
/**
* Adds an entry.
*/
public KeyValueComponentBuilder add(Component key, String value) {
if (value != null) this.templatesList.add(new Template[]{
Template.of(keyPlaceholder, key),
Template.of(valuePlaceholder, value)
});
return this;
}
/**
* Adds an entry.
*/
public KeyValueComponentBuilder add(Component key, Component value) {
if (value != null) this.templatesList.add(new Template[]{
Template.of(keyPlaceholder, key),
Template.of(valuePlaceholder, value)
});
return this;
}
/**
* Builds the current ListMessageBuilder instance into a Component.
*/
public Component build() {
TextComponent.Builder builder = Component.text();
for (Template[] templates : templatesList) {
builder.append(format.toComponent(templates));
}
return builder.build();
}
}

View file

@ -1,80 +0,0 @@
package net.frankheijden.serverutils.common.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ListBuilder<T> {
private final List<T> list;
private ListFormat<T> formatter;
private String seperator;
private String lastSeperator;
private ListBuilder() {
this.list = new ArrayList<>();
}
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<T>().addAll(Arrays.asList(elements));
}
/**
* Creates a pre-defined ListBuilder with type String.
* @param list The collection to be used.
* @return The ListBuilder.
*/
@SuppressWarnings("unchecked")
public static ListBuilder<String> createStrings(List<? extends String> list) {
ListBuilder<String> builder = create((List<String>) list);
builder.format(ListFormat.stringFormat);
return builder;
}
public ListBuilder<T> format(ListFormat<T> formatter) {
this.formatter = formatter;
return this;
}
public ListBuilder<T> seperator(String seperator) {
this.seperator = seperator;
return this;
}
public ListBuilder<T> lastSeperator(String lastSeperator) {
this.lastSeperator = lastSeperator;
return this;
}
public ListBuilder<T> addAll(Collection<? extends T> collection) {
this.list.addAll(collection);
return this;
}
@Override
public String toString() {
if (list.size() == 1) {
return formatter.format(list.iterator().next());
} else {
StringBuilder sb = new StringBuilder();
int i = 1;
for (T t : list) {
sb.append(formatter.format(t));
if (i == list.size() - 1 && lastSeperator != null) {
sb.append(lastSeperator);
} else if (i != list.size() && seperator != null) {
sb.append(seperator);
}
i++;
}
return sb.toString();
}
}
}

View file

@ -0,0 +1,78 @@
package net.frankheijden.serverutils.common.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
public class ListComponentBuilder<T> {
private final List<T> elements;
private Format<T> format;
private Component separator;
private Component lastSeparator;
private ListComponentBuilder() {
this.elements = new ArrayList<>();
}
public static <T> ListComponentBuilder<T> create(Collection<? extends T> list) {
return new ListComponentBuilder<T>().addAll(list);
}
@SafeVarargs
public static <T> ListComponentBuilder<T> create(T... elements) {
return new ListComponentBuilder<T>().addAll(Arrays.asList(elements));
}
public ListComponentBuilder<T> format(Format<T> format) {
this.format = format;
return this;
}
public ListComponentBuilder<T> separator(Component separator) {
this.separator = separator;
return this;
}
public ListComponentBuilder<T> lastSeparator(Component lastSeparator) {
this.lastSeparator = lastSeparator;
return this;
}
public ListComponentBuilder<T> addAll(Collection<? extends T> elements) {
this.elements.addAll(elements);
return this;
}
/**
* Builds the ListComponent.
*/
public Component build() {
if (elements.size() == 1) {
return format.format(elements.iterator().next());
} else {
TextComponent.Builder builder = Component.empty().toBuilder();
int sizeMinusTwo = elements.size() - 2;
for (int i = 0; i < elements.size(); i++) {
builder.append(format.format(elements.get(i)));
if (i == sizeMinusTwo && lastSeparator != null) {
builder.append(lastSeparator);
} else if (i < sizeMinusTwo && separator != null) {
builder.append(separator);
}
}
return builder.build();
}
}
public interface Format<T> {
Component format(T element);
}
}

View file

@ -1,9 +0,0 @@
package net.frankheijden.serverutils.common.utils;
public interface ListFormat<T> {
ListFormat<String> stringFormat = String::toString;
String format(T t);
}

View file

@ -1,71 +1,76 @@
{
"config-version": 2,
"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%",
"depending_plugins": {
"prefix": "&cPlugin &4%what%&c has depending plugins: ",
"format": "&4%plugin%",
"separator": "&c, ",
"last_separator": " &cand ",
"override": "&cUse \"&4/%command%&c\" to force command execution."
"messages": {
"generic": {
"prefix": "<aqua><bold>ServerUtils <dark_gray><bold>»<reset> <gray>",
"error": "<red>An error occurred, please check the console!",
"not-exists": "<red>Plugin <dark_red><plugin></dark_red> does not exist!",
"not-enabled": "<red>Plugin <dark_red><plugin></dark_red> is not enabled!",
"already-loaded": "<red>Plugin <dark_red><plugin></dark_red> is already loaded!",
"already-enabled": "<red>Plugin <dark_red><plugin></dark_red> is already enabled!",
"already-disabled": "<red>Plugin <dark_red><plugin></dark_red> is already disabled!",
"invalid-plugin": "<red>Plugin <dark_red><plugin></dark_red> is invalid!",
"invalid-description": "<red>Plugin <dark_red><plugin></dark_red> has an invalid plugin description!",
"unknown-dependency": "<red>Plugin <dark_red><plugin></dark_red> has an unknown dependency: <dark_red><dependency><red>!",
"file-deleted": "<red>File of plugin <dark_red><plugin></dark_red> has been deleted!"
},
"reload": "<dark_aqua>Successfully reloaded <aqua>ServerUtils configurations</aqua>!",
"loadplugin": "<dark_aqua>Successfully loaded <aqua><plugin></aqua>!",
"unloadplugin": "<dark_aqua>Successfully unloaded <aqua><plugin></aqua>!",
"reloadplugin": "<dark_aqua>Successfully reloaded <aqua><plugin></aqua>!",
"depending-plugins": {
"prefix": "<red>Plugin <dark_red><plugin></dark_red> has depending plugins: ",
"format": "<dark_red><plugin>",
"separator": "<red>, ",
"last-separator": " <red>and ",
"override": "<red>Use \"<dark_red>/<command></dark_red>\" to force command execution."
},
"watchplugin": {
"start": "&3Started watching &b%what%&3!",
"change": "&3Changes detected, reloading plugins now...",
"stopped": "&3Stopped watching &b%what%&3!",
"file_deleted": "&cPlugin file &4%what%&c has been deleted! Waiting for plugin to show up...",
"deleted_file_is_created": "&3Plugin file &b%what%&3 has shown up again!",
"already_watching": "&cYou are already watching &4%what%&c!",
"not_watching": "&cYou are not watching &4%what%&c!"
"start": "<dark_aqua>Started watching <aqua><plugin></aqua>!",
"change": "<dark_aqua>Changes detected, reloading plugins now...",
"stopped": "<dark_aqua>Stopped watching <aqua><plugin></aqua>!",
"file-deleted": "<red>File of plugin <dark_red><plugin></dark_red> has been deleted! Waiting for plugin to show up...",
"deleted-file-is-created": "<dark_aqua>File of plugin <aqua><plugin></aqua> has shown up again!",
"already-watching": "<red>You are already watching <dark_red><plugin></dark_red>!",
"not-watching": "<red>You are not watching <dark_red><plugin></dark_red>!"
},
"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."
"available": "<dark_gray><strikethrough>------------=<reset><dark_gray>[ <aqua><bold>ServerUtils Update<reset> <dark_gray>]<strikethrough>=--------------\n <dark_aqua>Current version: <aqua><old>\n <dark_aqua>New version: <aqua><new>\n <dark_aqua>Release info: <aqua><info>\n<dark_gray><strikethrough>-------------------------------------------------",
"downloading": "<dark_gray><strikethrough>------------=<reset><dark_gray>[ <aqua><bold>ServerUtils Update<reset> <dark_gray>]<strikethrough>=--------------\n <dark_aqua>A new version of ServerUtils will be downloaded and installed after a restart!\n <dark_aqua>Current version: <aqua><old>\n <dark_aqua>New version: <aqua><new>\n <dark_aqua>Release info: <aqua><info>\n<dark_gray><strikethrough>-------------------------------------------------",
"download-failed": "<red>Failed to download version <new> of ServerUtils. Please update manually.",
"download-success": "<dark_aqua>ServerUtils 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% &8(&b%help%&8)",
"footer": "&8&m-------------------------------------------------"
"header": "<dark_gray><strikethrough>-------------=<reset><dark_gray>[ <aqua><bold>ServerUtils Help<reset> <dark_gray>]<strikethrough>=---------------",
"format": "<dark_gray>/<dark_aqua><command> <dark_gray>(<aqua><help><dark_gray>)",
"footer": "<dark_gray><strikethrough>-------------------------------------------------"
},
"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-------------------------------------------------"
"header": "<dark_gray><strikethrough>------------=<reset><dark_gray>[ <aqua><bold>ServerUtils Plugins<reset> <dark_gray>]<strikethrough>=-------------",
"prefix": " <dark_aqua>Plugins <dark_gray>(<green><count><dark_gray>)<aqua>: ",
"format": "<dark_aqua><plugin>",
"format-disabled": "<red><plugin>",
"separator": "<aqua>, ",
"last-separator": " <aqua>and ",
"version": " <dark_gray>(<green><version><dark_gray>)",
"footer": "<dark_gray><strikethrough>-------------------------------------------------"
},
"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-------------------------------------------------"
"header": "<dark_gray><strikethrough>-----------=<reset><dark_gray>[ <aqua><bold>ServerUtils PluginInfo<reset> <dark_gray>]<strikethrough>=-----------",
"format": " <dark_aqua><key><dark_gray>: <aqua><value>",
"list-format": "<aqua><value>",
"list-separator": "<dark_gray>, ",
"list-last-separator": " <dark_gray>and ",
"footer": "<dark_gray><strikethrough>-------------------------------------------------"
},
"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."
"header": "<dark_gray><strikethrough>-----------=<reset><dark_gray>[ <aqua><bold>ServerUtils CommandInfo<reset> <dark_gray>]<strikethrough>=----------",
"format": " <dark_aqua><key><dark_gray>: <aqua><value>",
"list-format": "<aqua><value>",
"list-separator": "<dark_gray>, ",
"list-last-separator": " <dark_gray>and ",
"footer": "<dark_gray><strikethrough>-------------------------------------------------",
"not-exists": "<red>That command is not a valid registered command."
}
}
}

View file

@ -0,0 +1,25 @@
package net.frankheijden.serverutils.common.config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class MessageKeyTest {
@ParameterizedTest(name = "key = {0}")
@MethodSource("messageKeyGenerator")
void testMessageKeyConsistency(MessageKey key) {
assertThatCode(() -> MessageKey.fromPath(key.getPath())).doesNotThrowAnyException();
assertThat(MessageKey.fromPath(key.getPath())).isEqualTo(key);
}
private static Stream<Arguments> messageKeyGenerator() {
return Arrays.stream(MessageKey.values())
.map(Arguments::of);
}
}

View file

@ -1,42 +0,0 @@
package net.frankheijden.serverutils.common.utils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.params.provider.Arguments.of;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
class HexUtilsTest {
@ParameterizedTest(name = "color = {0}, expected = {1}")
@CsvSource({
"0, &x&0",
"10, &x&1&0",
"789344, &x&7&8&9&3&4&4",
})
void convertHexColor(String color, String expected) {
assertThat(HexUtils.convertHexColor(color)).isEqualTo(expected);
}
@ParameterizedTest(name = "hexString = {0}, expected = {1}")
@MethodSource("hexStringGenerator")
void convertHexString(String hexString, String expected) {
assertThat(HexUtils.convertHexString(hexString)).isEqualTo(expected);
}
private static Stream<Arguments> hexStringGenerator() {
return Stream.of(
of("<#FFFFFF>", "&x&F&F&F&F&F&F"),
of("Hey <#FFFFFF>", "Hey &x&F&F&F&F&F&F"),
of("Hey<#FFFFFF>Hey2<#AAAAAA>", "Hey&x&F&F&F&F&F&FHey2&x&A&A&A&A&A&A"),
of("<#FFFFFF><#AAAAAA><#FFFFFF>", "&x&F&F&F&F&F&F&x&A&A&A&A&A&A&x&F&F&F&F&F&F"),
of("<#FFFFFF>#FFFFFF", "&x&F&F&F&F&F&F#FFFFFF"),
of("<#FFFFFF>FFFFFF", "&x&F&F&F&F&F&FFFFFFF"),
of("<<#FFFFFF>>", "<&x&F&F&F&F&F&F>"),
of("<#<#ABCDEF>>", "<#&x&A&B&C&D&E&F>")
);
}
}

View file

@ -5,38 +5,47 @@ import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.ComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.junit.jupiter.api.Test;
class ListBuilderTest {
private final String seperator = ", ";
private final String lastSeperator = " and ";
private static final ComponentSerializer<Component, TextComponent, String> plainTextComponentSerializer
= PlainTextComponentSerializer.plainText();
private final Component separator = Component.text(", ");
private final Component lastSeparator = Component.text(" and ");
@Test
void testToStringOneElement() {
String list = ListBuilder.createStrings(singletonList("Nice"))
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString();
assertEquals("Nice", list);
Component component = ListComponentBuilder.create(singletonList("Nice"))
.format(Component::text)
.separator(separator)
.lastSeparator(lastSeparator)
.build();
assertEquals("Nice", plainTextComponentSerializer.serialize(component));
}
@Test
void testToStringTwoElements() {
String list = ListBuilder.createStrings(asList("Nice", "List"))
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString();
assertEquals("Nice and List", list);
Component component = ListComponentBuilder.create(asList("Nice", "List"))
.format(Component::text)
.separator(separator)
.lastSeparator(lastSeparator)
.build();
assertEquals("Nice and List", plainTextComponentSerializer.serialize(component));
}
@Test
void testToStringMultipleElements() {
String list = ListBuilder.createStrings(asList("Nice", "List", "You", "Having", "There"))
.seperator(seperator)
.lastSeperator(lastSeperator)
.toString();
assertEquals("Nice, List, You, Having and There", list);
Component component = ListComponentBuilder.create(asList("Nice", "List", "You", "Having", "There"))
.format(Component::text)
.separator(separator)
.lastSeparator(lastSeparator)
.build();
assertEquals("Nice, List, You, Having and There", plainTextComponentSerializer.serialize(component));
}
@Test
@ -47,12 +56,12 @@ class ListBuilderTest {
new TestObject("pre3", 4)
);
String list = ListBuilder.create(objects)
.format(obj -> obj.prefix + "-" + obj.value)
.seperator("; ")
.lastSeperator(" and at last ")
.toString();
assertEquals("pre1-2; pre2-3 and at last pre3-4", list);
Component component = ListComponentBuilder.create(objects)
.format(obj -> Component.text(obj.prefix + "-" + obj.value))
.separator(Component.text("; "))
.lastSeparator(Component.text(" and at last "))
.build();
assertEquals("pre1-2; pre2-3 and at last pre3-4", plainTextComponentSerializer.serialize(component));
}
private static class TestObject {

View file

@ -6,10 +6,15 @@ import cloud.commandframework.context.CommandContext;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginDescription;
import net.frankheijden.serverutils.common.commands.CommandPlugins;
import net.frankheijden.serverutils.velocity.entities.VelocityCommandSender;
import net.frankheijden.serverutils.common.config.MessageKey;
import net.frankheijden.serverutils.common.config.MessagesResource;
import net.frankheijden.serverutils.velocity.entities.VelocityAudience;
import net.frankheijden.serverutils.velocity.entities.VelocityPlugin;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.Template;
public class VelocityCommandPlugins extends CommandPlugins<VelocityPlugin, PluginContainer, VelocityCommandSender> {
public class VelocityCommandPlugins extends CommandPlugins<VelocityPlugin, PluginContainer, VelocityAudience> {
public VelocityCommandPlugins(VelocityPlugin plugin) {
super(plugin);
@ -17,8 +22,8 @@ public class VelocityCommandPlugins extends CommandPlugins<VelocityPlugin, Plugi
@Override
protected void register(
CommandManager<VelocityCommandSender> manager,
Command.Builder<VelocityCommandSender> builder
CommandManager<VelocityAudience> manager,
Command.Builder<VelocityAudience> builder
) {
manager.command(builder
.flag(parseFlag("version"))
@ -26,26 +31,25 @@ public class VelocityCommandPlugins extends CommandPlugins<VelocityPlugin, Plugi
}
@Override
protected void handlePlugins(CommandContext<VelocityCommandSender> context) {
VelocityCommandSender sender = context.getSender();
protected void handlePlugins(CommandContext<VelocityAudience> context) {
VelocityAudience sender = context.getSender();
boolean hasVersionFlag = context.flags().contains("version");
MessagesResource messages = plugin.getMessagesResource();
handlePlugins(sender, plugin.getPluginManager().getPluginsSorted(), container -> {
PluginDescription description = container.getDescription();
String message = plugin.getMessagesResource().getMessage(
"serverutils.plugins.format",
"%plugin%", description.getId()
);
TextComponent.Builder builder = Component.text();
builder.append(messages.get(MessageKey.PLUGINS_FORMAT).toComponent(
Template.of("plugin", description.getId())
));
if (hasVersionFlag) {
message += plugin.getMessagesResource().getMessage(
"serverutils.plugins.version",
"%version%", description.getVersion().orElse("<UNKNOWN>")
);
builder.append(messages.get(MessageKey.PLUGINS_FORMAT).toComponent(
Template.of("version", description.getVersion().orElse("<UNKNOWN>"))
));
}
return message;
return builder.build();
});
}
}

View file

@ -10,24 +10,24 @@ 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.common.utils.KeyValueComponentBuilder;
import net.frankheijden.serverutils.common.utils.ListComponentBuilder;
import net.frankheijden.serverutils.velocity.ServerUtils;
import net.frankheijden.serverutils.velocity.entities.VelocityCommandSender;
import net.frankheijden.serverutils.velocity.entities.VelocityAudience;
import net.frankheijden.serverutils.velocity.entities.VelocityPlugin;
import net.frankheijden.serverutils.velocity.reflection.RVelocityCommandManager;
import net.kyori.adventure.text.Component;
public class VelocityCommandServerUtils
extends CommandServerUtils<VelocityPlugin, PluginContainer, VelocityCommandSender> {
public class VelocityCommandServerUtils extends CommandServerUtils<VelocityPlugin, PluginContainer, VelocityAudience> {
public VelocityCommandServerUtils(VelocityPlugin plugin) {
super(plugin, PluginContainer[]::new);
}
@Override
protected FormatBuilder createPluginInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected KeyValueComponentBuilder createPluginInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
PluginContainer container
) {
PluginDescription desc = container.getDescription();
@ -52,9 +52,9 @@ public class VelocityCommandServerUtils
}
@Override
protected FormatBuilder createCommandInfo(
FormatBuilder builder,
Function<Consumer<ListBuilder<String>>, String> listBuilderFunction,
protected KeyValueComponentBuilder createCommandInfo(
KeyValueComponentBuilder builder,
Function<Consumer<ListComponentBuilder<String>>, Component> listBuilderFunction,
String commandName
) {
ServerUtils plugin = ServerUtils.getInstance();

View file

@ -0,0 +1,23 @@
package net.frankheijden.serverutils.velocity.entities;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.frankheijden.serverutils.common.entities.ServerUtilsAudience;
import net.kyori.adventure.audience.Audience;
public class VelocityAudience extends ServerUtilsAudience<CommandSource> {
protected VelocityAudience(Audience audience, CommandSource source) {
super(audience, source);
}
@Override
public boolean isPlayer() {
return source instanceof Player;
}
@Override
public boolean hasPermission(String permission) {
return source.hasPermission(permission);
}
}

View file

@ -0,0 +1,43 @@
package net.frankheijden.serverutils.velocity.entities;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import net.frankheijden.serverutils.common.providers.ServerUtilsAudienceProvider;
import net.frankheijden.serverutils.velocity.ServerUtils;
import net.kyori.adventure.text.Component;
public class VelocityAudienceProvider implements ServerUtilsAudienceProvider<CommandSource> {
private final ServerUtils plugin;
private final VelocityAudience consoleServerAudience;
/**
* Constructs a new VelocityAudienceProvider.
*/
public VelocityAudienceProvider(ServerUtils plugin) {
this.plugin = plugin;
this.consoleServerAudience = new VelocityAudience(
plugin.getProxy().getConsoleCommandSource(),
plugin.getProxy().getConsoleCommandSource()
);
}
@Override
public VelocityAudience getConsoleServerAudience() {
return consoleServerAudience;
}
@Override
public VelocityAudience get(CommandSource source) {
return new VelocityAudience(source, source);
}
@Override
public void broadcast(Component component, String permission) {
for (Player player : plugin.getProxy().getAllPlayers()) {
if (player.hasPermission(permission)) {
player.sendMessage(component);
}
}
}
}

View file

@ -1,40 +0,0 @@
package net.frankheijden.serverutils.velocity.entities;
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.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class VelocityChatProvider implements ChatProvider<VelocityCommandSender, CommandSource> {
private final ServerUtils plugin;
public VelocityChatProvider(ServerUtils plugin) {
this.plugin = plugin;
}
@Override
public VelocityCommandSender getConsoleSender() {
return new VelocityCommandSender(plugin.getProxy().getConsoleCommandSource());
}
@Override
public VelocityCommandSender get(CommandSource source) {
return new VelocityCommandSender(source);
}
@Override
public String color(String str) {
return HexUtils.convertHexString(str);
}
@Override
public void broadcast(String permission, String message) {
Component msg = LegacyComponentSerializer.legacyAmpersand().deserialize(message);
plugin.getProxy().getAllPlayers().stream()
.filter(p -> p.hasPermission(permission))
.forEach(p -> p.sendMessage(msg));
}
}

View file

@ -1,39 +0,0 @@
package net.frankheijden.serverutils.velocity.entities;
import com.velocitypowered.api.command.CommandSource;
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<CommandSource> {
private final CommandSource source;
public VelocityCommandSender(CommandSource source) {
this.source = source;
}
@Override
public void sendMessage(String message) {
source.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
}
@Override
public boolean hasPermission(String permission) {
return source.hasPermission(permission);
}
/**
* Whether or not the given instance is a player.
* @return Boolean true or false.
*/
@Override
public boolean isPlayer() {
return source instanceof Player;
}
@Override
public CommandSource getSource() {
return source;
}
}

View file

@ -15,13 +15,13 @@ import net.frankheijden.serverutils.velocity.listeners.VelocityPlayerListener;
import net.frankheijden.serverutils.velocity.managers.VelocityPluginManager;
import net.frankheijden.serverutils.velocity.managers.VelocityTaskManager;
public class VelocityPlugin extends ServerUtilsPlugin<PluginContainer, ScheduledTask, VelocityCommandSender, CommandSource, VelocityPluginDescription> {
public class VelocityPlugin extends ServerUtilsPlugin<PluginContainer, ScheduledTask, VelocityAudience, CommandSource, VelocityPluginDescription> {
private final ServerUtils plugin;
private final VelocityPluginManager pluginManager;
private final VelocityTaskManager taskManager;
private final VelocityResourceProvider resourceProvider;
private final VelocityChatProvider chatProvider;
private final VelocityAudienceProvider chatProvider;
/**
* Creates a new BungeePlugin instance of ServerUtils.
@ -36,17 +36,17 @@ public class VelocityPlugin extends ServerUtilsPlugin<PluginContainer, Scheduled
);
this.taskManager = new VelocityTaskManager(plugin);
this.resourceProvider = new VelocityResourceProvider(plugin);
this.chatProvider = new VelocityChatProvider(plugin);
this.chatProvider = new VelocityAudienceProvider(plugin);
}
@Override
protected VelocityCommandManager<VelocityCommandSender> newCommandManager() {
VelocityCommandManager<VelocityCommandSender> commandManager = new VelocityCommandManager<>(
protected VelocityCommandManager<VelocityAudience> newCommandManager() {
VelocityCommandManager<VelocityAudience> commandManager = new VelocityCommandManager<>(
plugin.getPluginContainer(),
plugin.getProxy(),
AsynchronousCommandExecutionCoordinator.<VelocityCommandSender>newBuilder().build(),
AsynchronousCommandExecutionCoordinator.<VelocityAudience>newBuilder().build(),
chatProvider::get,
VelocityCommandSender::getSource
VelocityAudience::getSource
);
handleBrigadier(commandManager.brigadierManager());
return commandManager;
@ -78,7 +78,7 @@ public class VelocityPlugin extends ServerUtilsPlugin<PluginContainer, Scheduled
}
@Override
public VelocityChatProvider getChatProvider() {
public VelocityAudienceProvider getChatProvider() {
return this.chatProvider;
}

View file

@ -4,11 +4,10 @@ import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
import com.velocitypowered.api.plugin.PluginContainer;
import net.frankheijden.serverutils.common.listeners.PlayerListener;
import net.frankheijden.serverutils.velocity.entities.VelocityCommandSender;
import net.frankheijden.serverutils.velocity.entities.VelocityAudience;
import net.frankheijden.serverutils.velocity.entities.VelocityPlugin;
public class VelocityPlayerListener
extends PlayerListener<VelocityPlugin, PluginContainer, VelocityCommandSender> {
public class VelocityPlayerListener extends PlayerListener<VelocityPlugin, PluginContainer, VelocityAudience> {
public VelocityPlayerListener(VelocityPlugin plugin) {
super(plugin);

View file

@ -44,6 +44,7 @@ import net.frankheijden.serverutils.velocity.reflection.RVelocityEventManager;
import net.frankheijden.serverutils.velocity.reflection.RVelocityPluginContainer;
import net.frankheijden.serverutils.velocity.reflection.RVelocityPluginManager;
import net.frankheijden.serverutils.velocity.reflection.RVelocityScheduler;
import net.kyori.adventure.text.minimessage.Template;
import org.slf4j.Logger;
public class VelocityPluginManager extends AbstractPluginManager<PluginContainer, VelocityPluginDescription> {
@ -91,9 +92,8 @@ public class VelocityPluginManager extends AbstractPluginManager<PluginContainer
candidate.getId(),
dependency.getId()
);
return loadResults.addResult(
description.getId(),
Result.UNKNOWN_DEPENDENCY.arg(dependency.getId())
return loadResults.addResult(description.getId(), Result.UNKNOWN_DEPENDENCY,
Template.of("dependency", dependency.getId())
);
}
}

View file

@ -34,6 +34,9 @@ subprojects {
implementation "com.github.FrankHeijden.cloud:cloud-core:${rootProject.cloudVersion}"
implementation "com.github.FrankHeijden.cloud:cloud-brigadier:${rootProject.cloudVersion}"
implementation 'com.github.FrankHeijden:MinecraftReflection:1.0.0'
implementation ('net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT') {
exclude group: 'net.kyori', module: 'adventure-api'
}
implementation 'com.google.guava:guava:30.1.1-jre'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'me.lucko:commodore:1.10'
@ -90,6 +93,8 @@ subprojects {
relocate 'com.google.common.graph', dependencyDir + '.common.graph'
relocate 'dev.frankheijden.minecraftreflection', dependencyDir + '.minecraftreflection'
relocate 'cloud.commandframework', dependencyDir + '.cloud'
relocate 'net.kyori.adventure.text.minimessage', dependencyDir + '.adventure.text.minimessage'
relocate 'me.lucko.commodore', dependencyDir + '.commodore'
relocate 'io.leangen.geantyref', dependencyDir + '.typetoken'
}