Modularise project
This commit is contained in:
parent
2be3825438
commit
4416d55173
55 changed files with 388 additions and 331 deletions
|
|
@ -0,0 +1,169 @@
|
|||
package net.frankheijden.serverutils.bukkit;
|
||||
|
||||
import co.aikar.commands.BukkitCommandCompletionContext;
|
||||
import co.aikar.commands.CommandCompletions;
|
||||
import co.aikar.commands.PaperCommandManager;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import net.frankheijden.serverutils.bukkit.commands.CommandPlugins;
|
||||
import net.frankheijden.serverutils.bukkit.commands.CommandServerUtils;
|
||||
import net.frankheijden.serverutils.bukkit.config.Config;
|
||||
import net.frankheijden.serverutils.bukkit.config.Messenger;
|
||||
import net.frankheijden.serverutils.bukkit.listeners.MainListener;
|
||||
import net.frankheijden.serverutils.bukkit.managers.VersionManager;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.BukkitReflection;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCommandMap;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
|
||||
import net.frankheijden.serverutils.bukkit.tasks.UpdateCheckerTask;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.defaults.PluginsCommand;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class ServerUtils extends JavaPlugin implements CommandExecutor {
|
||||
|
||||
private static final int BSTATS_METRICS_ID = 7790;
|
||||
|
||||
private static ServerUtils instance;
|
||||
private PaperCommandManager commandManager;
|
||||
private CommandPlugins commandPlugins;
|
||||
|
||||
public static ServerUtils getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
super.onEnable();
|
||||
instance = this;
|
||||
|
||||
new Metrics(this, BSTATS_METRICS_ID);
|
||||
new BukkitReflection();
|
||||
|
||||
this.commandManager = new PaperCommandManager(this);
|
||||
commandManager.registerCommand(new CommandServerUtils());
|
||||
this.commandPlugins = null;
|
||||
|
||||
CommandCompletions<BukkitCommandCompletionContext> completions = commandManager.getCommandCompletions();
|
||||
completions.registerAsyncCompletion("plugins", context -> getPluginNames());
|
||||
completions.registerAsyncCompletion("pluginJars", context -> getPluginFileNames());
|
||||
completions.registerAsyncCompletion("supportedConfigs ", context -> CommandServerUtils.getSupportedConfigs());
|
||||
completions.registerAsyncCompletion("commands", context -> {
|
||||
try {
|
||||
return RCommandMap.getKnownCommands(RCraftServer.getCommandMap()).keySet();
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
});
|
||||
reload();
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new MainListener(), this);
|
||||
|
||||
new VersionManager();
|
||||
checkForUpdates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
super.onDisable();
|
||||
restoreBukkitPluginCommand();
|
||||
}
|
||||
|
||||
private List<String> getPluginNames() {
|
||||
return Arrays.stream(Bukkit.getPluginManager().getPlugins())
|
||||
.map(Plugin::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> getPluginFileNames() {
|
||||
return Arrays.stream(getJars())
|
||||
.map(File::getName)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void removeCommands(String... commands) {
|
||||
Map<String, Command> map;
|
||||
try {
|
||||
map = RCommandMap.getKnownCommands(RCraftServer.getCommandMap());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
for (String command : commands) {
|
||||
map.remove(command);
|
||||
}
|
||||
}
|
||||
|
||||
public void restoreBukkitPluginCommand() {
|
||||
RCraftServer.getCommandMap().register("bukkit", new PluginsCommand("plugins"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the configurations of the plugin.
|
||||
* Also makes sure the bukkit /pl command gets restored.
|
||||
*/
|
||||
public void reload() {
|
||||
if (commandPlugins != null) {
|
||||
commandManager.unregisterCommand(commandPlugins);
|
||||
restoreBukkitPluginCommand();
|
||||
}
|
||||
|
||||
new Config(copyResourceIfNotExists("config.yml", "bukkit-config.yml"));
|
||||
new Messenger(copyResourceIfNotExists("messages.yml", "bukkit-messages.yml"));
|
||||
|
||||
if (!Config.getInstance().getBoolean("settings.disable-plugins-command")) {
|
||||
this.removeCommands("pl", "plugins");
|
||||
this.commandPlugins = new CommandPlugins();
|
||||
commandManager.registerCommand(commandPlugins);
|
||||
}
|
||||
}
|
||||
|
||||
public PaperCommandManager getCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all files with a jar extension in the plugins/ folder.
|
||||
* @return An array of jar files.
|
||||
*/
|
||||
public File[] getJars() {
|
||||
File parent = getDataFolder().getParentFile();
|
||||
if (parent == null) return new File[0];
|
||||
return parent.listFiles(f -> f.getName().endsWith(".jar"));
|
||||
}
|
||||
|
||||
private void createDataFolderIfNotExists() {
|
||||
if (!getDataFolder().exists()) {
|
||||
getDataFolder().mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
private File copyResourceIfNotExists(String targetName, String resource) {
|
||||
createDataFolderIfNotExists();
|
||||
|
||||
File file = new File(getDataFolder(), targetName);
|
||||
if (!file.exists()) {
|
||||
getLogger().info(String.format("'%s' not found, creating!", targetName));
|
||||
saveResource(resource, false);
|
||||
File copiedFile = new File(getDataFolder(), resource);
|
||||
copiedFile.renameTo(file);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private void checkForUpdates() {
|
||||
if (Config.getInstance().getBoolean("settings.check-updates")) {
|
||||
UpdateCheckerTask.start(Bukkit.getConsoleSender(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
package net.frankheijden.serverutils.bukkit.commands;
|
||||
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Default;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
import co.aikar.commands.annotation.Subcommand;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import net.frankheijden.serverutils.bukkit.config.Messenger;
|
||||
import net.frankheijden.serverutils.common.utils.ListBuilder;
|
||||
import net.frankheijden.serverutils.common.utils.ListFormat;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
@CommandAlias("plugins|pl")
|
||||
public class CommandPlugins extends BaseCommand {
|
||||
|
||||
/**
|
||||
* Sends the plugin list to the sender, without plugin version.
|
||||
* @param sender The sender of the command.
|
||||
*/
|
||||
@Default
|
||||
@CommandPermission("serverutils.plugins")
|
||||
@Description("Shows the plugins of this server.")
|
||||
public void onPlugins(CommandSender sender) {
|
||||
sendPlugins(sender, pl -> {
|
||||
String format = "serverutils.plugins.format" + (pl.isEnabled() ? "" : "_disabled");
|
||||
return Messenger.getMessage(format, "%plugin%", pl.getName());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the plugin list to the sender, with plugin version.
|
||||
* @param sender The sender of the command.
|
||||
*/
|
||||
@Subcommand("-v")
|
||||
@CommandPermission("serverutils.plugins.version")
|
||||
@Description("Shows the plugins of this server with version.")
|
||||
public void onPluginsWithVersion(CommandSender sender) {
|
||||
sendPlugins(sender, pl -> {
|
||||
String format = "serverutils.plugins.format" + (pl.isEnabled() ? "" : "_disabled");
|
||||
String version = Messenger.getMessage("serverutils.plugins.version",
|
||||
"%version%", pl.getDescription().getVersion());
|
||||
return Messenger.getMessage(format, "%plugin%", pl.getName()) + version;
|
||||
});
|
||||
}
|
||||
|
||||
private static void sendPlugins(CommandSender sender, ListFormat<Plugin> pluginFormat) {
|
||||
Messenger.sendMessage(sender, "serverutils.plugins.header");
|
||||
List<Plugin> plugins = getPluginsSorted();
|
||||
String prefix = Messenger.getMessage("serverutils.plugins.prefix",
|
||||
"%count%", String.valueOf(plugins.size()));
|
||||
sender.sendMessage(Messenger.color(prefix + ListBuilder.create(plugins)
|
||||
.seperator(Messenger.getMessage("serverutils.plugins.seperator"))
|
||||
.lastSeperator(Messenger.getMessage("serverutils.plugins.last_seperator"))
|
||||
.format(pluginFormat)
|
||||
.toString()));
|
||||
Messenger.sendMessage(sender, "serverutils.plugins.footer");
|
||||
}
|
||||
|
||||
private static List<Plugin> getPluginsSorted() {
|
||||
List<Plugin> plugins = Arrays.asList(Bukkit.getPluginManager().getPlugins());
|
||||
plugins.sort(Comparator.comparing(Plugin::getName));
|
||||
return plugins;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
package net.frankheijden.serverutils.bukkit.commands;
|
||||
|
||||
import static net.frankheijden.serverutils.bukkit.config.Messenger.sendMessage;
|
||||
import static net.frankheijden.serverutils.bukkit.reflection.BukkitReflection.MINOR;
|
||||
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Default;
|
||||
import co.aikar.commands.annotation.Dependency;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
import co.aikar.commands.annotation.Subcommand;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.ServerUtils;
|
||||
import net.frankheijden.serverutils.bukkit.config.Messenger;
|
||||
import net.frankheijden.serverutils.bukkit.managers.CloseableResult;
|
||||
import net.frankheijden.serverutils.bukkit.managers.LoadResult;
|
||||
import net.frankheijden.serverutils.bukkit.managers.PluginManager;
|
||||
import net.frankheijden.serverutils.bukkit.managers.Result;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
|
||||
import net.frankheijden.serverutils.bukkit.utils.FormatBuilder;
|
||||
import net.frankheijden.serverutils.bukkit.utils.ForwardFilter;
|
||||
import net.frankheijden.serverutils.bukkit.utils.ReloadHandler;
|
||||
import net.frankheijden.serverutils.common.utils.ListBuilder;
|
||||
import net.frankheijden.serverutils.common.utils.ListFormat;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginIdentifiableCommand;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
|
||||
@CommandAlias("serverutils|su")
|
||||
public class CommandServerUtils extends BaseCommand {
|
||||
|
||||
private static final Set<String> ALIASES;
|
||||
private static final Map<String, ReloadHandler> supportedConfigs;
|
||||
|
||||
static {
|
||||
ALIASES = new HashSet<>();
|
||||
ALIASES.add("serverutils");
|
||||
ALIASES.add("plugins");
|
||||
|
||||
supportedConfigs = new HashMap<>();
|
||||
supportedConfigs.put("bukkit", RCraftServer::reloadBukkitConfiguration);
|
||||
supportedConfigs.put("commands.yml", RCraftServer::reloadCommandsConfiguration);
|
||||
supportedConfigs.put("server-icon.png", RCraftServer::loadIcon);
|
||||
supportedConfigs.put("banned-ips.json", RCraftServer::reloadIpBans);
|
||||
supportedConfigs.put("banned-players.json", RCraftServer::reloadProfileBans);
|
||||
}
|
||||
|
||||
@Dependency
|
||||
private ServerUtils plugin;
|
||||
|
||||
public static Set<String> getSupportedConfigs() {
|
||||
return supportedConfigs.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the help page to the sender.
|
||||
* @param sender The sender of the command.
|
||||
*/
|
||||
@Default
|
||||
@Subcommand("help")
|
||||
@CommandPermission("serverutils.help")
|
||||
@Description("Shows a help page with a few commands.")
|
||||
public void onHelp(CommandSender sender) {
|
||||
Messenger.sendMessage(sender, "serverutils.help.header");
|
||||
|
||||
FormatBuilder builder = FormatBuilder.create(Messenger.getMessage("serverutils.help.format"))
|
||||
.orderedKeys("%command%", "%subcommand%", "%help%");
|
||||
plugin.getCommandManager().getRegisteredRootCommands().stream()
|
||||
.filter(c -> !ALIASES.contains(c.getCommandName().toLowerCase()))
|
||||
.forEach(rootCommand -> {
|
||||
builder.add(rootCommand.getCommandName(), "", rootCommand.getDescription());
|
||||
rootCommand.getSubCommands().forEach((str, cmd) -> {
|
||||
if (cmd.getPrefSubCommand().isEmpty()) return;
|
||||
builder.add(rootCommand.getCommandName(), " " + cmd.getPrefSubCommand(), cmd.getHelpText());
|
||||
});
|
||||
});
|
||||
builder.sendTo(sender);
|
||||
Messenger.sendMessage(sender, "serverutils.help.footer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the configurations of ServerUtils.
|
||||
* @param sender The sender of the command.
|
||||
*/
|
||||
@Subcommand("reload")
|
||||
@CommandPermission("serverutils.reload")
|
||||
@Description("Reloads the ServerUtils plugin.")
|
||||
public void onReload(CommandSender sender) {
|
||||
plugin.reload();
|
||||
sendMessage(sender, "serverutils.success",
|
||||
"%action%", "reload",
|
||||
"%what%", "ServerUtils configurations");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads a config from a set of configurations of the server.
|
||||
* @param sender The sender of the command.
|
||||
* @param config The configuration to reload.
|
||||
*/
|
||||
@Subcommand("reloadconfig")
|
||||
@CommandCompletion("@supportedConfigs")
|
||||
@CommandPermission("serverutils.reloadconfig")
|
||||
@Description("Reloads individual Server configurations.")
|
||||
public void onReloadCommands(CommandSender sender, String config) {
|
||||
ReloadHandler handler = supportedConfigs.get(config);
|
||||
if (handler == null) {
|
||||
this.doHelp(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] replacements = new String[]{ "%action%", "reload", "%what%", config };
|
||||
|
||||
ForwardFilter filter = new ForwardFilter(sender);
|
||||
filter.start(Bukkit.getLogger());
|
||||
try {
|
||||
handler.handle();
|
||||
filter.stop(Bukkit.getLogger());
|
||||
|
||||
String path = "serverutils." + (filter.hasWarnings() ? "warning" : "success");
|
||||
sendMessage(sender, path, replacements);
|
||||
} catch (Exception ex) {
|
||||
filter.stop(Bukkit.getLogger());
|
||||
|
||||
ex.printStackTrace();
|
||||
sendMessage(sender, "serverutils.error", replacements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified plugin on the server.
|
||||
* @param sender The sender of the command.
|
||||
* @param jarFile The filename of the plugin in the plugins/ directory.
|
||||
*/
|
||||
@Subcommand("loadplugin")
|
||||
@CommandCompletion("@pluginJars")
|
||||
@CommandPermission("serverutils.loadplugin")
|
||||
@Description("Loads the specified jar file as a plugin.")
|
||||
public void onLoadPlugin(CommandSender sender, String jarFile) {
|
||||
LoadResult loadResult = PluginManager.loadPlugin(jarFile);
|
||||
if (!loadResult.isSuccess()) {
|
||||
loadResult.getResult().sendTo(sender, "load", jarFile);
|
||||
return;
|
||||
}
|
||||
|
||||
Result result = PluginManager.enablePlugin(loadResult.getPlugin());
|
||||
result.sendTo(sender, "load", jarFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the specified plugin from the server.
|
||||
* @param sender The sender of the command.
|
||||
* @param pluginName The plugin name.
|
||||
*/
|
||||
@Subcommand("unloadplugin")
|
||||
@CommandCompletion("@plugins")
|
||||
@CommandPermission("serverutils.unloadplugin")
|
||||
@Description("Disables and unloads the specified plugin.")
|
||||
public void onUnloadPlugin(CommandSender sender, String pluginName) {
|
||||
Result disableResult = PluginManager.disablePlugin(pluginName);
|
||||
if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) {
|
||||
disableResult.sendTo(sender, "disabl", pluginName);
|
||||
return;
|
||||
}
|
||||
|
||||
CloseableResult result = PluginManager.unloadPlugin(pluginName);
|
||||
result.getResult().sendTo(sender, "unload", pluginName);
|
||||
result.tryClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the specified plugin on the server.
|
||||
* @param sender The sender of the command.
|
||||
* @param pluginName The plugin name.
|
||||
*/
|
||||
@Subcommand("reloadplugin")
|
||||
@CommandCompletion("@plugins")
|
||||
@CommandPermission("serverutils.reloadplugin")
|
||||
@Description("Reloads a specified plugin.")
|
||||
public void onReloadPlugin(CommandSender sender, String pluginName) {
|
||||
CloseableResult result = PluginManager.reloadPlugin(pluginName);
|
||||
result.getResult().sendTo(sender, "reload", pluginName);
|
||||
result.tryClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the specified plugin on the server.
|
||||
* @param sender The sender of the command.
|
||||
* @param pluginName The plugin name.
|
||||
*/
|
||||
@Subcommand("enableplugin")
|
||||
@CommandCompletion("@plugins")
|
||||
@CommandPermission("serverutils.enableplugin")
|
||||
@Description("Enables the loaded plugin.")
|
||||
public void onEnablePlugin(CommandSender sender, String pluginName) {
|
||||
Result result = PluginManager.enablePlugin(pluginName);
|
||||
result.sendTo(sender, "enabl", pluginName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the specified plugin on the server.
|
||||
* @param sender The sender of the command.
|
||||
* @param pluginName The plugin name.
|
||||
*/
|
||||
@Subcommand("disableplugin")
|
||||
@CommandCompletion("@plugins")
|
||||
@CommandPermission("serverutils.disableplugin")
|
||||
@Description("Disables the specified plugin.")
|
||||
public void onDisablePlugin(CommandSender sender, String pluginName) {
|
||||
Result result = PluginManager.disablePlugin(pluginName);
|
||||
result.sendTo(sender, "disabl", pluginName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows information about the specified plugin.
|
||||
* @param sender The sender of the command.
|
||||
* @param pluginName The plugin name.
|
||||
*/
|
||||
@Subcommand("plugininfo")
|
||||
@CommandCompletion("@plugins")
|
||||
@CommandPermission("serverutils.plugininfo")
|
||||
@Description("Shows information about the specified plugin.")
|
||||
public void onPluginInfo(CommandSender sender, String pluginName) {
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
Result.NOT_EXISTS.sendTo(sender, "fetch", pluginName);
|
||||
return;
|
||||
}
|
||||
|
||||
PluginDescriptionFile description = plugin.getDescription();
|
||||
String format = Messenger.getMessage("serverutils.plugininfo.format");
|
||||
String listFormatString = Messenger.getMessage("serverutils.plugininfo.list_format");
|
||||
String seperator = Messenger.getMessage("serverutils.plugininfo.seperator");
|
||||
String lastSeperator = Messenger.getMessage("serverutils.plugininfo.last_seperator");
|
||||
|
||||
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
|
||||
|
||||
Messenger.sendMessage(sender, "serverutils.plugininfo.header");
|
||||
|
||||
FormatBuilder builder = FormatBuilder.create(format)
|
||||
.orderedKeys("%key%", "%value%")
|
||||
.add("Name", plugin.getName())
|
||||
.add("Full Name", description.getFullName())
|
||||
.add("Version", description.getVersion());
|
||||
if (MINOR >= 13) builder.add("API Version", description.getAPIVersion());
|
||||
builder.add("Website", description.getWebsite())
|
||||
.add("Authors", ListBuilder.create(description.getAuthors())
|
||||
.format(listFormat)
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString())
|
||||
.add("Description", description.getDescription())
|
||||
.add("Main", description.getMain())
|
||||
.add("Prefix", description.getPrefix())
|
||||
.add("Load Order", description.getLoad().name())
|
||||
.add("Load Before", ListBuilder.create(description.getLoadBefore())
|
||||
.format(listFormat)
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString())
|
||||
.add("Depend", ListBuilder.create(description.getDepend())
|
||||
.format(listFormat)
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString())
|
||||
.add("Soft Depend", ListBuilder.create(description.getSoftDepend())
|
||||
.format(listFormat)
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString());
|
||||
if (MINOR >= 15) builder.add("Provides", ListBuilder.create(description.getProvides())
|
||||
.format(listFormat)
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString());
|
||||
|
||||
builder.sendTo(sender);
|
||||
Messenger.sendMessage(sender, "serverutils.plugininfo.footer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows information about a provided command.
|
||||
* @param sender The sender of the command.
|
||||
* @param command The command to lookup.
|
||||
*/
|
||||
@Subcommand("commandinfo")
|
||||
@CommandCompletion("@commands")
|
||||
@CommandPermission("serverutils.commandinfo")
|
||||
@Description("Shows information about the specified command.")
|
||||
public void onCommandInfo(CommandSender sender, String command) {
|
||||
Command cmd = PluginManager.getCommand(command);
|
||||
if (cmd == null) {
|
||||
Messenger.sendMessage(sender, "serverutils.commandinfo.not_exists");
|
||||
return;
|
||||
}
|
||||
|
||||
String format = Messenger.getMessage("serverutils.commandinfo.format");
|
||||
String listFormatString = Messenger.getMessage("serverutils.commandinfo.list_format");
|
||||
String seperator = Messenger.getMessage("serverutils.commandinfo.seperator");
|
||||
String lastSeperator = Messenger.getMessage("serverutils.commandinfo.last_seperator");
|
||||
|
||||
ListFormat<String> listFormat = str -> listFormatString.replace("%value%", str);
|
||||
|
||||
Messenger.sendMessage(sender, "serverutils.commandinfo.header");
|
||||
FormatBuilder builder = FormatBuilder.create(format)
|
||||
.orderedKeys("%key%", "%value%")
|
||||
.add("Name", cmd.getName());
|
||||
if (cmd instanceof PluginIdentifiableCommand) {
|
||||
PluginIdentifiableCommand pc = (PluginIdentifiableCommand) cmd;
|
||||
builder.add("Plugin", pc.getPlugin().getName());
|
||||
}
|
||||
builder.add("Usage", cmd.getUsage())
|
||||
.add("Description", cmd.getDescription())
|
||||
.add("Aliases", ListBuilder.create(cmd.getAliases())
|
||||
.format(listFormat)
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString())
|
||||
.add("Label", cmd.getLabel())
|
||||
.add("Timings Name", cmd.getTimingName())
|
||||
.add("Permission", cmd.getPermission())
|
||||
.add("Permission Message", cmd.getPermissionMessage());
|
||||
|
||||
builder.sendTo(sender);
|
||||
Messenger.sendMessage(sender, "serverutils.commandinfo.footer");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package net.frankheijden.serverutils.bukkit.config;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Config extends YamlResource {
|
||||
|
||||
private static Config instance;
|
||||
|
||||
public Config(File file) {
|
||||
super(file, "bukkit-config.yml");
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static Config getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path) {
|
||||
return getConfiguration().getBoolean(path);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package net.frankheijden.serverutils.bukkit.config;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.ServerUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class Messenger extends YamlResource {
|
||||
|
||||
private static final ServerUtils plugin = ServerUtils.getInstance();
|
||||
private static Messenger instance;
|
||||
|
||||
public Messenger(File file) {
|
||||
super(file, "bukkit-messages.yml");
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a message from the config.
|
||||
* @param path The yml path to the message.
|
||||
* @param replacements The replacements to be taken into account.
|
||||
* @return The config message with translated placeholders.
|
||||
*/
|
||||
public static String getMessage(String path, String... replacements) {
|
||||
String message = instance.getConfiguration().getString(path);
|
||||
if (message != null) {
|
||||
return apply(message, replacements);
|
||||
} else {
|
||||
plugin.getLogger().severe("Missing locale in bukkit-messages.yml at path '" + path + "'!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies placeholders to a message.
|
||||
* @param message The message.
|
||||
* @param replacements The replacements of the message. Expects input to be even and in a key-value like format.
|
||||
* Example: ["%player%", "Player"]
|
||||
* @return The message with translated placeholders.
|
||||
*/
|
||||
public static String apply(String message, String... replacements) {
|
||||
if (message == null || message.isEmpty()) return null;
|
||||
message = message.replace("\\n", "\n");
|
||||
for (int i = 0; i < replacements.length; i++, i++) {
|
||||
message = message.replace(replacements[i], replacements[i + 1]);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to a player with translated placeholders.
|
||||
* @param sender The receiver.
|
||||
* @param msg The message to be sent.
|
||||
* @param replacements The replacements to be taken into account.
|
||||
*/
|
||||
public static void sendRawMessage(CommandSender sender, String msg, String... replacements) {
|
||||
String message = apply(msg, replacements);
|
||||
if (message != null) {
|
||||
sender.sendMessage(color(message));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message from the specified config path to a player with translated placeholders.
|
||||
* @param sender The receiver.
|
||||
* @param path The yml path to the message.
|
||||
* @param replacements The replacements to be taken into account.
|
||||
*/
|
||||
public static void sendMessage(CommandSender sender, String path, String... replacements) {
|
||||
String message = getMessage(path, replacements);
|
||||
if (message != null) {
|
||||
sender.sendMessage(color(message));
|
||||
}
|
||||
}
|
||||
|
||||
public static String color(String str) {
|
||||
return ChatColor.translateAlternateColorCodes('&', str);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.frankheijden.serverutils.bukkit.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.ServerUtils;
|
||||
import net.frankheijden.serverutils.bukkit.utils.YamlUtils;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public abstract class YamlResource {
|
||||
|
||||
private static final ServerUtils plugin = ServerUtils.getInstance();
|
||||
|
||||
private final YamlConfiguration configuration;
|
||||
|
||||
/**
|
||||
* Creates a new YamlResource instance.
|
||||
* Loads the resource from the jar file.
|
||||
* @param file The destination file.
|
||||
* @param resource The resource from the jar file.
|
||||
*/
|
||||
public YamlResource(File file, String resource) {
|
||||
InputStream is = plugin.getResource(resource);
|
||||
YamlConfiguration def = YamlConfiguration.loadConfiguration(new InputStreamReader(is));
|
||||
configuration = YamlUtils.init(file, def);
|
||||
}
|
||||
|
||||
public YamlConfiguration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.frankheijden.serverutils.bukkit.listeners;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.config.Config;
|
||||
import net.frankheijden.serverutils.bukkit.tasks.UpdateCheckerTask;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class MainListener implements Listener {
|
||||
|
||||
private static final Config config = Config.getInstance();
|
||||
|
||||
/**
|
||||
* Called when a player joins the server.
|
||||
* Used for sending an update message to the player, if enabled and has permission.
|
||||
* @param event The PlayerJoinEvent.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
if (!config.getBoolean("settings.check-updates-login")) return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("serverutils.notification.update")) {
|
||||
UpdateCheckerTask.start(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package net.frankheijden.serverutils.bukkit.managers;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
public class CloseableResult implements Closeable {
|
||||
|
||||
private Result result;
|
||||
private final Closeable closeable;
|
||||
|
||||
/**
|
||||
* Constructs a new closable result.
|
||||
* Used for unloading / reloading a plugin.
|
||||
* NB: The closable needs to be closed to fully ensure that the old plugin doesn't work anymore!
|
||||
* @param result The result of the procedure
|
||||
* @param closeable The closable of the procedure.
|
||||
*/
|
||||
public CloseableResult(Result result, Closeable closeable) {
|
||||
this.result = result;
|
||||
this.closeable = closeable;
|
||||
}
|
||||
|
||||
public CloseableResult(Result result) {
|
||||
this(result, null);
|
||||
}
|
||||
|
||||
public CloseableResult(Closeable closeable) {
|
||||
this(Result.SUCCESS, closeable);
|
||||
}
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public CloseableResult set(Result result) {
|
||||
this.result = result;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to close the closable, essentially wrapping it with try-catch.
|
||||
*/
|
||||
public void tryClose() {
|
||||
if (closeable == null) return;
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
closeable.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package net.frankheijden.serverutils.bukkit.managers;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class LoadResult {
|
||||
private final Plugin plugin;
|
||||
private final Result result;
|
||||
|
||||
private LoadResult(Plugin plugin, Result result) {
|
||||
this.plugin = plugin;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public LoadResult(Plugin plugin) {
|
||||
this(plugin, Result.SUCCESS);
|
||||
}
|
||||
|
||||
public LoadResult(Result result) {
|
||||
this(null, result);
|
||||
}
|
||||
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return plugin != null && result == Result.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
package net.frankheijden.serverutils.bukkit.managers;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.ServerUtils;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCommandMap;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftServer;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RCraftingManager;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RJavaPlugin;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RPluginClassLoader;
|
||||
import net.frankheijden.serverutils.bukkit.reflection.RSimplePluginManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.InvalidPluginException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginLoader;
|
||||
import org.bukkit.plugin.UnknownDependencyException;
|
||||
|
||||
public class PluginManager {
|
||||
|
||||
/**
|
||||
* Loads the specified file as a plugin.
|
||||
* @param jarFile The name of the file in the plugins/ folder.
|
||||
* @return The result of the loading procedure.
|
||||
*/
|
||||
public static LoadResult loadPlugin(String jarFile) {
|
||||
return loadPlugin(new File(ServerUtils.getInstance().getDataFolder().getParent(), jarFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified file as a plugin.
|
||||
* @param file The file to be loaded.
|
||||
* @return The result of the loading procedure.
|
||||
*/
|
||||
public static LoadResult loadPlugin(File file) {
|
||||
if (!file.exists()) return new LoadResult(Result.NOT_EXISTS);
|
||||
|
||||
Plugin loadedPlugin = getLoadedPlugin(file);
|
||||
if (loadedPlugin != null) return new LoadResult(Result.ALREADY_LOADED);
|
||||
|
||||
Plugin plugin;
|
||||
try {
|
||||
plugin = Bukkit.getPluginManager().loadPlugin(file);
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
return new LoadResult(Result.INVALID_DESCRIPTION);
|
||||
} catch (UnknownDependencyException ex) {
|
||||
return new LoadResult(Result.UNKNOWN_DEPENDENCY.arg(ex.getMessage()));
|
||||
} catch (InvalidPluginException ex) {
|
||||
if (ex.getCause() instanceof IllegalArgumentException) {
|
||||
IllegalArgumentException e = (IllegalArgumentException) ex.getCause();
|
||||
if (e.getMessage().equalsIgnoreCase("Plugin already initialized!")) {
|
||||
return new LoadResult(Result.ALREADY_ENABLED);
|
||||
}
|
||||
}
|
||||
ex.printStackTrace();
|
||||
return new LoadResult(Result.ERROR);
|
||||
}
|
||||
|
||||
if (plugin == null) return new LoadResult(Result.INVALID_PLUGIN);
|
||||
plugin.onLoad();
|
||||
return new LoadResult(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the specified plugin by name and cleans all commands and recipes of the plugin.
|
||||
* @param pluginName The plugin to disable.
|
||||
* @return The result of the disable call.
|
||||
*/
|
||||
public static Result disablePlugin(String pluginName) {
|
||||
return disablePlugin(Bukkit.getPluginManager().getPlugin(pluginName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the specified plugin and cleans all commands and recipes of the plugin.
|
||||
* @param plugin The plugin to disable.
|
||||
* @return The result of the disable call.
|
||||
*/
|
||||
public static Result disablePlugin(Plugin plugin) {
|
||||
if (plugin == null) return Result.NOT_ENABLED;
|
||||
if (!plugin.isEnabled()) return Result.ALREADY_DISABLED;
|
||||
try {
|
||||
Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
RCraftingManager.removeRecipesFor(plugin);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return Result.ERROR;
|
||||
}
|
||||
unregisterCommands(plugin);
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the specified plugin by name and cleans all traces within bukkit.
|
||||
* @param pluginName The plugin to unload.
|
||||
* @return The result of the unload.
|
||||
*/
|
||||
public static CloseableResult unloadPlugin(String pluginName) {
|
||||
return unloadPlugin(Bukkit.getPluginManager().getPlugin(pluginName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the specified plugin and cleans all traces within bukkit.
|
||||
* @param plugin The plugin to unload.
|
||||
* @return The result of the unload.
|
||||
*/
|
||||
public static CloseableResult unloadPlugin(Plugin plugin) {
|
||||
if (plugin == null) return new CloseableResult(Result.NOT_EXISTS);
|
||||
Closeable closeable;
|
||||
try {
|
||||
RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin);
|
||||
RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName());
|
||||
closeable = RPluginClassLoader.clearClassLoader(RJavaPlugin.getClassLoader(plugin));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return new CloseableResult(Result.ERROR);
|
||||
}
|
||||
return new CloseableResult(closeable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the specified plugin by name.
|
||||
* @param pluginName The plugin to enable.
|
||||
* @return The result of the enabling.
|
||||
*/
|
||||
public static Result enablePlugin(String pluginName) {
|
||||
return enablePlugin(Bukkit.getPluginManager().getPlugin(pluginName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the specified plugin.
|
||||
* @param plugin The plugin to enable.
|
||||
* @return The result of the enabling.
|
||||
*/
|
||||
public static Result enablePlugin(Plugin plugin) {
|
||||
if (plugin == null) return Result.NOT_EXISTS;
|
||||
if (Bukkit.getPluginManager().isPluginEnabled(plugin.getName())) return Result.ALREADY_ENABLED;
|
||||
Bukkit.getPluginManager().enablePlugin(plugin);
|
||||
if (Bukkit.getPluginManager().isPluginEnabled(plugin.getName())) {
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
return Result.ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the specified plugin by name.
|
||||
* @param pluginName The plugin to reload.
|
||||
* @return The result of the reload.
|
||||
*/
|
||||
public static CloseableResult reloadPlugin(String pluginName) {
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
if (plugin == null) return new CloseableResult(Result.NOT_EXISTS);
|
||||
return reloadPlugin(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the specified plugin.
|
||||
* @param plugin The plugin to reload.
|
||||
* @return The result of the reload.
|
||||
*/
|
||||
public static CloseableResult reloadPlugin(Plugin plugin) {
|
||||
Result disableResult = disablePlugin(plugin);
|
||||
if (disableResult != Result.SUCCESS && disableResult != Result.ALREADY_DISABLED) {
|
||||
return new CloseableResult(disableResult);
|
||||
}
|
||||
|
||||
CloseableResult result = unloadPlugin(plugin);
|
||||
if (result.getResult() != Result.SUCCESS) return result;
|
||||
|
||||
File pluginFile = getPluginFile(plugin.getName());
|
||||
if (pluginFile == null) return result.set(Result.FILE_DELETED);
|
||||
|
||||
LoadResult loadResult = loadPlugin(pluginFile);
|
||||
if (!loadResult.isSuccess()) return result.set(loadResult.getResult());
|
||||
return result.set(enablePlugin(loadResult.getPlugin()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all known commands registered to bukkit.
|
||||
* @return A map with all known commands.
|
||||
*/
|
||||
public static Map<String, Command> getKnownCommands() {
|
||||
try {
|
||||
return RCommandMap.getKnownCommands(RCraftServer.getCommandMap());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters all commands from the specified plugin.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
public static void unregisterCommands(Plugin plugin) {
|
||||
Map<String, Command> knownCommands = getKnownCommands();
|
||||
if (knownCommands == null) return;
|
||||
|
||||
knownCommands.values().removeIf(c -> {
|
||||
if (c instanceof PluginCommand) {
|
||||
PluginCommand pc = (PluginCommand) c;
|
||||
if (pc.getPlugin() == plugin) {
|
||||
pc.unregister(RCraftServer.getCommandMap());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a command from the command map.
|
||||
* @param command The command string.
|
||||
* @return The command.
|
||||
*/
|
||||
public static Command getCommand(String command) {
|
||||
Map<String, Command> knownCommands = getKnownCommands();
|
||||
if (knownCommands == null) return null;
|
||||
return knownCommands.get(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all file associations, i.e. all plugin loaders.
|
||||
* @return A map with all pluginloaders.
|
||||
*/
|
||||
public static Map<Pattern, PluginLoader> getFileAssociations() {
|
||||
try {
|
||||
return RSimplePluginManager.getFileAssociations(Bukkit.getPluginManager());
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the PluginLoader for the input file.
|
||||
* @param file The file.
|
||||
* @return The appropiate PluginLoader.
|
||||
*/
|
||||
public static PluginLoader getPluginLoader(File file) {
|
||||
Map<Pattern, PluginLoader> fileAssociations = getFileAssociations();
|
||||
if (fileAssociations == null) return null;
|
||||
|
||||
for (Pattern filter : fileAssociations.keySet()) {
|
||||
Matcher match = filter.matcher(file.getName());
|
||||
if (match.find()) {
|
||||
return fileAssociations.get(filter);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a loaded plugin associated to a jar file.
|
||||
* @param file The jar file.
|
||||
* @return The already loaded plugin, or null if none.
|
||||
*/
|
||||
public static Plugin getLoadedPlugin(File file) {
|
||||
PluginDescriptionFile descriptionFile;
|
||||
try {
|
||||
descriptionFile = getPluginDescription(file);
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
return null;
|
||||
}
|
||||
if (descriptionFile == null) return null;
|
||||
return Bukkit.getPluginManager().getPlugin(descriptionFile.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the PluginDescriptionFile of a jar file.
|
||||
* @param file The jar file.
|
||||
* @return The PluginDescriptionFile.
|
||||
* @throws InvalidDescriptionException Iff the PluginDescriptionFile is invalid.
|
||||
*/
|
||||
public static PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException {
|
||||
PluginLoader loader = getPluginLoader(file);
|
||||
if (loader == null) return null;
|
||||
return loader.getPluginDescription(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to retrieve the plugin file by plugin name.
|
||||
* @param pluginName The plugin name.
|
||||
* @return The file, or null if invalid or not found.
|
||||
*/
|
||||
public static File getPluginFile(String pluginName) {
|
||||
for (File file : ServerUtils.getInstance().getJars()) {
|
||||
PluginDescriptionFile descriptionFile;
|
||||
try {
|
||||
descriptionFile = getPluginDescription(file);
|
||||
} catch (InvalidDescriptionException ex) {
|
||||
return null;
|
||||
}
|
||||
if (descriptionFile == null) return null;
|
||||
if (descriptionFile.getName().equals(pluginName)) return file;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package net.frankheijden.serverutils.bukkit.managers;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.config.Messenger;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public enum Result {
|
||||
NOT_EXISTS,
|
||||
NOT_ENABLED,
|
||||
ALREADY_LOADED,
|
||||
ALREADY_ENABLED,
|
||||
ALREADY_DISABLED,
|
||||
FILE_DELETED,
|
||||
INVALID_DESCRIPTION,
|
||||
INVALID_PLUGIN,
|
||||
UNKNOWN_DEPENDENCY,
|
||||
ERROR,
|
||||
SUCCESS;
|
||||
|
||||
private String arg;
|
||||
|
||||
Result() {
|
||||
this.arg = "";
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
public void sendTo(CommandSender sender, String action, String what) {
|
||||
Messenger.sendMessage(sender, "serverutils." + this.name().toLowerCase(),
|
||||
"%action%", action,
|
||||
"%what%", what,
|
||||
"%arg%", arg);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package net.frankheijden.serverutils.bukkit.managers;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.ServerUtils;
|
||||
|
||||
public class VersionManager {
|
||||
|
||||
private static VersionManager instance;
|
||||
private final ServerUtils plugin = ServerUtils.getInstance();
|
||||
private final String currentVersion;
|
||||
private String downloadedVersion;
|
||||
|
||||
/**
|
||||
* Creates a new VersionManager instance.
|
||||
* Used for automatic updating.
|
||||
*/
|
||||
public VersionManager() {
|
||||
instance = this;
|
||||
this.currentVersion = plugin.getDescription().getVersion();
|
||||
this.downloadedVersion = currentVersion;
|
||||
}
|
||||
|
||||
public static VersionManager getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public String getCurrentVersion() {
|
||||
return currentVersion;
|
||||
}
|
||||
|
||||
public String getDownloadedVersion() {
|
||||
return downloadedVersion;
|
||||
}
|
||||
|
||||
public boolean hasDownloaded() {
|
||||
return !downloadedVersion.equals(currentVersion);
|
||||
}
|
||||
|
||||
public boolean isDownloadedVersion(String version) {
|
||||
return downloadedVersion.equals(version);
|
||||
}
|
||||
|
||||
public void setDownloadedVersion(String downloadedVersion) {
|
||||
this.downloadedVersion = downloadedVersion;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import net.frankheijden.serverutils.common.reflection.ReflectionUtils;
|
||||
import net.frankheijden.serverutils.common.reflection.VersionParam;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class BukkitReflection extends ReflectionUtils {
|
||||
|
||||
public static String NMS;
|
||||
public static int MAJOR;
|
||||
public static int MINOR;
|
||||
public static int PATCH;
|
||||
|
||||
static {
|
||||
String bukkitPackage = Bukkit.getServer().getClass().getPackage().getName();
|
||||
NMS = bukkitPackage.substring(bukkitPackage.lastIndexOf('.') + 1);
|
||||
|
||||
String[] split = NMS.split("_");
|
||||
MAJOR = Integer.parseInt(split[0].substring(1));
|
||||
MINOR = Integer.parseInt(split[1]);
|
||||
PATCH = Integer.parseInt(split[2].substring(1, 2));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatible(VersionParam versionParam) {
|
||||
return versionParam.min <= MINOR && MINOR <= versionParam.max;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getDeclaredField;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
|
||||
public class RCommandMap {
|
||||
|
||||
private static Field knownCommands = null;
|
||||
private static Method getKnownCommands = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
try {
|
||||
knownCommands = getDeclaredField(SimpleCommandMap.class, "knownCommands");
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
getKnownCommands = SimpleCommandMap.class.getDeclaredMethod("getKnownCommands");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Command> getKnownCommands(SimpleCommandMap map)
|
||||
throws IllegalAccessException, InvocationTargetException {
|
||||
return (Map<String, Command>) (knownCommands == null ? getKnownCommands.invoke(map) : knownCommands.get(map));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getDeclaredField;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getDeclaredMethod;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.invoke;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.set;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.max;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.min;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.versionOf;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Warning;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class RCraftServer {
|
||||
|
||||
private static Class<?> craftServerClass;
|
||||
private static Object craftServer;
|
||||
private static File configFile;
|
||||
private static File commandsConfigFile;
|
||||
private static SimpleCommandMap commandMap;
|
||||
|
||||
private static Map<String, Field> fields;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
craftServerClass = Class.forName(String.format("org.bukkit.craftbukkit.%s.CraftServer",
|
||||
BukkitReflection.NMS));
|
||||
craftServer = craftServerClass.cast(Bukkit.getServer());
|
||||
|
||||
commandsConfigFile = (File) getDeclaredMethod(craftServerClass,
|
||||
"getCommandsConfigFile").invoke(craftServer);
|
||||
configFile = (File) getDeclaredMethod(craftServerClass, "getConfigFile").invoke(craftServer);
|
||||
commandMap = (SimpleCommandMap) getDeclaredField(craftServerClass, "commandMap").get(Bukkit.getServer());
|
||||
|
||||
fields = getAllFields(craftServerClass,
|
||||
fieldOf("configuration", ALL_VERSIONS),
|
||||
fieldOf("console", ALL_VERSIONS),
|
||||
fieldOf("commandsConfiguration", ALL_VERSIONS),
|
||||
fieldOf("overrideAllCommandBlockCommands", ALL_VERSIONS),
|
||||
fieldOf("unrestrictedAdvancements", versionOf(12)),
|
||||
fieldOf("ignoreVanillaPermissions", min(13)),
|
||||
fieldOf("monsterSpawn", ALL_VERSIONS),
|
||||
fieldOf("animalSpawn", ALL_VERSIONS),
|
||||
fieldOf("waterAnimalSpawn", ALL_VERSIONS),
|
||||
fieldOf("ambientSpawn", ALL_VERSIONS),
|
||||
fieldOf("warningState", ALL_VERSIONS),
|
||||
fieldOf("minimumAPI", min(14)),
|
||||
fieldOf("printSaveWarning", ALL_VERSIONS),
|
||||
fieldOf("chunkGCPeriod", max(12)),
|
||||
fieldOf("chunkGCLoadThresh", max(12)),
|
||||
fieldOf("playerList", ALL_VERSIONS));
|
||||
methods = getAllMethods(craftServerClass,
|
||||
methodOf("loadIcon", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getCraftServer() {
|
||||
return craftServer;
|
||||
}
|
||||
|
||||
public static File getConfigFile() {
|
||||
return configFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the options file from a key.
|
||||
* @param option The option key.
|
||||
* @return The associated file.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
*/
|
||||
public static File getOptionsFile(String option) throws IllegalAccessException, InvocationTargetException {
|
||||
Object console = get(fields, craftServer, "console");
|
||||
Object options = get(RDedicatedServer.getFields(), console, "options");
|
||||
return (File) invoke(ROptionSet.getMethods(), options, "valueOf", option);
|
||||
}
|
||||
|
||||
public static File getCommandsConfigFile() {
|
||||
return commandsConfigFile;
|
||||
}
|
||||
|
||||
public static SimpleCommandMap getCommandMap() {
|
||||
return commandMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the bukkit configuration.
|
||||
* @throws ReflectiveOperationException Iff exception thrown regarding reflection.
|
||||
*/
|
||||
public static void reloadBukkitConfiguration() throws ReflectiveOperationException {
|
||||
YamlConfiguration bukkit = YamlConfiguration.loadConfiguration(getConfigFile());
|
||||
set(fields, craftServer, "configuration", bukkit);
|
||||
|
||||
Object console = get(fields, craftServer, "console");
|
||||
RDedicatedServer.reload(console);
|
||||
|
||||
set(fields, craftServer, "monsterSpawn", bukkit.getInt("spawn-limits.monsters"));
|
||||
set(fields, craftServer, "animalSpawn", bukkit.getInt("spawn-limits.animals"));
|
||||
set(fields, craftServer, "waterAnimalSpawn", bukkit.getInt("spawn-limits.water-animals"));
|
||||
set(fields, craftServer, "ambientSpawn", bukkit.getInt("spawn-limits.ambient"));
|
||||
set(fields, craftServer, "warningState",
|
||||
Warning.WarningState.value(bukkit.getString("settings.deprecated-verbose")));
|
||||
set(fields, craftServer, "minimumAPI", bukkit.getString("settings.minimum-api"));
|
||||
set(fields, craftServer, "printSaveWarning", false);
|
||||
|
||||
set(RDedicatedServer.getFields(), console, "autosavePeriod", bukkit.getInt("ticks-per.autosave"));
|
||||
|
||||
set(fields, craftServer, "chunkGCPeriod", bukkit.getInt("chunk-gc.period-in-ticks"));
|
||||
set(fields, craftServer, "chunkGCLoadThresh", bukkit.getInt("chunk-gc.load-threshold"));
|
||||
}
|
||||
|
||||
public static void loadIcon() throws InvocationTargetException, IllegalAccessException {
|
||||
invoke(methods, craftServer, "loadIcon");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the commands.yml file.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
*/
|
||||
public static void reloadCommandsConfiguration() throws IllegalAccessException, InvocationTargetException {
|
||||
Map<String, Command> map = RCommandMap.getKnownCommands(commandMap);
|
||||
Bukkit.getCommandAliases().keySet().forEach(map::remove);
|
||||
|
||||
YamlConfiguration commands = YamlConfiguration.loadConfiguration(getCommandsConfigFile());
|
||||
set(fields, craftServer, "commandsConfiguration", commands);
|
||||
set(fields, craftServer, "overrideAllCommandBlockCommands",
|
||||
commands.getStringList("command-block-overrides").contains("*"));
|
||||
set(fields, craftServer, "ignoreVanillaPermissions",
|
||||
commands.getBoolean("ignore-vanilla-permissions"));
|
||||
set(fields, craftServer, "unrestrictedAdvancements",
|
||||
commands.getBoolean("unrestricted-advancements"));
|
||||
|
||||
commandMap.registerServerAliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the ip-bans file.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
*/
|
||||
public static void reloadIpBans() throws IllegalAccessException, InvocationTargetException {
|
||||
Object playerList = get(fields, craftServer, "playerList");
|
||||
Object jsonList = invoke(RPlayerList.getMethods(), playerList, "getIPBans");
|
||||
RJsonList.load(jsonList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the profile bans file.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
*/
|
||||
public static void reloadProfileBans() throws IllegalAccessException, InvocationTargetException {
|
||||
Object playerList = get(fields, craftServer, "playerList");
|
||||
Object jsonList = invoke(RPlayerList.getMethods(), playerList, "getProfileBans");
|
||||
RJsonList.load(jsonList);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.bukkit.reflection.BukkitReflection.MINOR;
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.invoke;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.min;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import net.frankheijden.serverutils.common.utils.MapUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class RCraftingManager {
|
||||
|
||||
private static Class<?> craftingManagerClass;
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
craftingManagerClass = Class.forName(String.format("net.minecraft.server.%s.CraftingManager",
|
||||
BukkitReflection.NMS));
|
||||
fields = getAllFields(craftingManagerClass,
|
||||
fieldOf("recipes", min(12)));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all associated recipes of a plugin.
|
||||
* @param plugin The plugin to remove recipes for.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static void removeRecipesFor(Plugin plugin) throws IllegalAccessException, InvocationTargetException {
|
||||
// Cleaning up recipes before MC 1.12 is not possible,
|
||||
// as recipes are not associated to plugins.
|
||||
if (MINOR < 12) return;
|
||||
|
||||
Field recipesField = fields.get("recipes");
|
||||
|
||||
if (MINOR == 12) {
|
||||
Object recipes = get(fields, null, "recipes");
|
||||
RRegistryMaterials.removeKeysFor(recipes, plugin);
|
||||
} else {
|
||||
Object server = invoke(RMinecraftServer.getMethods(), null, "getServer");
|
||||
Object craftingManager = invoke(RMinecraftServer.getMethods(), server, "getCraftingManager");
|
||||
Map recipes = (Map) recipesField.get(craftingManager);
|
||||
|
||||
Predicate<Object> predicate = RMinecraftKey.matchingPluginPredicate(new AtomicBoolean(false), plugin);
|
||||
if (MINOR == 13) {
|
||||
MapUtils.removeKeys(recipes, predicate);
|
||||
} else {
|
||||
Collection<Map> list = (Collection<Map>) recipes.values();
|
||||
list.forEach(map -> MapUtils.removeKeys(map, predicate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.bukkit.reflection.BukkitReflection.MINOR;
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.invoke;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.set;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.min;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class RDedicatedServer {
|
||||
|
||||
private static Class<?> dedicatedServerClass;
|
||||
private static Map<String, Field> fields;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
dedicatedServerClass = Class.forName(String.format("net.minecraft.server.%s.DedicatedServer",
|
||||
BukkitReflection.NMS));
|
||||
|
||||
fields = getAllFields(dedicatedServerClass,
|
||||
fieldOf("propertyManager", ALL_VERSIONS),
|
||||
fieldOf("options", ALL_VERSIONS),
|
||||
fieldOf("autosavePeriod", ALL_VERSIONS),
|
||||
fieldOf("o", min(13)));
|
||||
methods = getAllMethods(dedicatedServerClass,
|
||||
methodOf("setSpawnAnimals", ALL_VERSIONS, boolean.class),
|
||||
methodOf("getSpawnAnimals", ALL_VERSIONS),
|
||||
methodOf("setPVP", ALL_VERSIONS, boolean.class),
|
||||
methodOf("getPVP", ALL_VERSIONS),
|
||||
methodOf("setAllowFlight", ALL_VERSIONS, boolean.class),
|
||||
methodOf("getAllowFlight", ALL_VERSIONS),
|
||||
methodOf("setMotd", ALL_VERSIONS, String.class),
|
||||
methodOf("getMotd", ALL_VERSIONS),
|
||||
methodOf("setSpawnNPCs", ALL_VERSIONS, boolean.class),
|
||||
methodOf("setAllowFlight", ALL_VERSIONS, boolean.class),
|
||||
methodOf("setResourcePack", ALL_VERSIONS, String.class, String.class),
|
||||
methodOf("setForceGamemode", ALL_VERSIONS, boolean.class),
|
||||
methodOf("n", min(13), boolean.class));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Field> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the specified console (= DedicatedServer) instance's bukkit config.
|
||||
* @param console The console to reload.
|
||||
* @throws ReflectiveOperationException Iff exception thrown regarding reflection.
|
||||
*/
|
||||
public static void reload(Object console) throws ReflectiveOperationException {
|
||||
Object options = get(fields, console, "options");
|
||||
|
||||
if (MINOR >= 13) {
|
||||
Object propertyManager = RDedicatedServerSettings.newInstance(options);
|
||||
set(fields, console, "propertyManager", propertyManager);
|
||||
Object config = invoke(RDedicatedServerSettings.getMethods(), propertyManager, "getProperties");
|
||||
invoke(methods, console, "setSpawnAnimals", getConfigValue(config, "spawnAnimals"));
|
||||
invoke(methods, console, "setSpawnNPCs", getConfigValue(config, "spawnNpcs"));
|
||||
invoke(methods, console, "setPVP", getConfigValue(config, "pvp"));
|
||||
invoke(methods, console, "setAllowFlight", getConfigValue(config, "allowFlight"));
|
||||
invoke(methods, console, "setResourcePack", getConfigValue(config, "resourcePack"),
|
||||
invoke(methods, console, "aZ"));
|
||||
invoke(methods, console, "setMotd", getConfigValue(config, "motd"));
|
||||
invoke(methods, console, "setForceGamemode", getConfigValue(config, "forceGamemode"));
|
||||
invoke(methods, console, "n", getConfigValue(config, "enforceWhitelist"));
|
||||
set(fields, console, "o", getConfigValue(config, "gamemode"));
|
||||
} else {
|
||||
Object config = RPropertyManager.newInstance(options);
|
||||
setConfigValue(config, console, "getSpawnAnimals", "setSpawnAnimals", "getBoolean", "spawn-animals");
|
||||
setConfigValue(config, console, "getPVP", "setPVP", "getBoolean", "pvp");
|
||||
setConfigValue(config, console, "getAllowFlight", "setAllowFlight", "getBoolean", "allow-flight");
|
||||
setConfigValue(config, console, "getMotd", "setMotd", "getString", "motd");
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getConfigValue(Object config, String key) throws IllegalAccessException {
|
||||
return get(RDedicatedServerProperties.getFields(), config, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified bukkit config value.
|
||||
* @param config The config instance (= PropertyManager)
|
||||
* @param console The console instance (= DedicatedServer)
|
||||
* @param getMethod The getter method for the config value.
|
||||
* @param setMethod The setter method for the config value.
|
||||
* @param configMethod The method which we call the config value upon.
|
||||
* @param key The config key.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
*/
|
||||
public static void setConfigValue(Object config, Object console, String getMethod, String setMethod,
|
||||
String configMethod, String key)
|
||||
throws InvocationTargetException, IllegalAccessException {
|
||||
Object defaultValue = invoke(methods, console, getMethod);
|
||||
Object configValue = invoke(RPropertyManager.getMethods(), config, configMethod, key, defaultValue);
|
||||
invoke(methods, console, setMethod, configValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
public class RDedicatedServerProperties {
|
||||
|
||||
private static Class<?> serverPropertiesClass;
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
serverPropertiesClass = Class.forName(String.format("net.minecraft.server.%s.DedicatedServerProperties",
|
||||
BukkitReflection.NMS));
|
||||
fields = getAllFields(serverPropertiesClass,
|
||||
fieldOf("spawnAnimals", ALL_VERSIONS),
|
||||
fieldOf("spawnNpcs", ALL_VERSIONS),
|
||||
fieldOf("pvp", ALL_VERSIONS),
|
||||
fieldOf("allowFlight", ALL_VERSIONS),
|
||||
fieldOf("resourcePack", ALL_VERSIONS),
|
||||
fieldOf("motd", ALL_VERSIONS),
|
||||
fieldOf("forceGamemode", ALL_VERSIONS),
|
||||
fieldOf("enforceWhitelist", ALL_VERSIONS),
|
||||
fieldOf("gamemode", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Field> getFields() {
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class RDedicatedServerSettings {
|
||||
|
||||
private static Class<?> serverSettingsClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
serverSettingsClass = Class.forName(String.format("net.minecraft.server.%s.DedicatedServerSettings",
|
||||
BukkitReflection.NMS));
|
||||
methods = getAllMethods(serverSettingsClass,
|
||||
methodOf("getProperties", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object newInstance(Object options)throws ReflectiveOperationException {
|
||||
return serverSettingsClass.getDeclaredConstructor(Class.forName("joptsimple.OptionSet")).newInstance(options);
|
||||
}
|
||||
|
||||
public static Map<String, Method> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.invoke;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class RJavaPlugin {
|
||||
|
||||
private static Class<?> javaPluginClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
javaPluginClass = JavaPlugin.class;
|
||||
methods = getAllMethods(javaPluginClass,
|
||||
methodOf("getClassLoader", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static ClassLoader getClassLoader(Object instance) throws InvocationTargetException, IllegalAccessException {
|
||||
return (ClassLoader) invoke(methods, instance, "getClassLoader");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.invoke;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class RJsonList {
|
||||
|
||||
private static Class<?> jsonListClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
jsonListClass = Class.forName(String.format("net.minecraft.server.%s.JsonList", BukkitReflection.NMS));
|
||||
methods = getAllMethods(jsonListClass,
|
||||
methodOf("load", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void load(Object jsonList) throws InvocationTargetException, IllegalAccessException {
|
||||
invoke(methods, jsonList, "load");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.bukkit.reflection.BukkitReflection.MINOR;
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.max;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.min;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class RMinecraftKey {
|
||||
|
||||
private static Class<?> minecraftKeyClass;
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
minecraftKeyClass = Class.forName(String.format("net.minecraft.server.%s.MinecraftKey",
|
||||
BukkitReflection.NMS));
|
||||
fields = getAllFields(minecraftKeyClass,
|
||||
fieldOf("a", max(13)),
|
||||
fieldOf("namespace", min(14)));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the namespace of the specified MinecraftKey instance.
|
||||
* @param instance The MinecraftKey instance.
|
||||
* @return The namespace.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
public static String getNameSpace(Object instance) throws IllegalAccessException {
|
||||
if (MINOR <= 13) {
|
||||
return (String) get(fields, instance, "a");
|
||||
}
|
||||
return (String) get(fields, instance, "namespace");
|
||||
}
|
||||
|
||||
public static boolean isFrom(Object instance, Plugin plugin) throws IllegalAccessException {
|
||||
String namespace = plugin.getName().toLowerCase(Locale.ROOT);
|
||||
return namespace.equalsIgnoreCase(getNameSpace(instance));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a predicate which returns true if a MinecraftKey instance comes from the specified plugin.
|
||||
* @param errorThrown Requires an atomicboolean to ensure an exception is only thrown once, if any.
|
||||
* @param plugin The plugin to match the MinecraftKey instance with.
|
||||
* @return The predicate.
|
||||
*/
|
||||
public static Predicate<Object> matchingPluginPredicate(AtomicBoolean errorThrown, Plugin plugin) {
|
||||
return o -> {
|
||||
try {
|
||||
return RMinecraftKey.isFrom(o, plugin);
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (!errorThrown.get()) {
|
||||
ex.printStackTrace();
|
||||
errorThrown.set(true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class RMinecraftServer {
|
||||
|
||||
private static Class<?> minecraftServerClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
minecraftServerClass = Class.forName(String.format("net.minecraft.server.%s.MinecraftServer",
|
||||
BukkitReflection.NMS));
|
||||
methods = getAllMethods(minecraftServerClass,
|
||||
methodOf("getServer", ALL_VERSIONS),
|
||||
methodOf("getCraftingManager", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Method> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class ROptionSet {
|
||||
|
||||
private static Class<?> optionSetClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
optionSetClass = Class.forName("joptsimple.OptionSet");
|
||||
methods = getAllMethods(optionSetClass,
|
||||
methodOf("valueOf", ALL_VERSIONS, String.class));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Method> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class RPlayerList {
|
||||
|
||||
private static Class<?> playerListClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
playerListClass = Class.forName(String.format("net.minecraft.server.%s.PlayerList", BukkitReflection.NMS));
|
||||
methods = getAllMethods(playerListClass,
|
||||
methodOf("getIPBans", ALL_VERSIONS),
|
||||
methodOf("getProfileBans", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Method> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getDeclaredMethod;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class RPlugin {
|
||||
|
||||
private static Method getFile;
|
||||
|
||||
static {
|
||||
try {
|
||||
getFile = getDeclaredMethod(JavaPlugin.class, "getFile");
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static File getPluginFile(Plugin plugin) throws InvocationTargetException, IllegalAccessException {
|
||||
return (File) getFile.invoke(plugin);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.set;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
public class RPluginClassLoader {
|
||||
|
||||
private static Class<?> pluginClassLoaderClass;
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
pluginClassLoaderClass = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
|
||||
fields = getAllFields(pluginClassLoaderClass,
|
||||
fieldOf("plugin", ALL_VERSIONS),
|
||||
fieldOf("pluginInit", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isInstance(Object obj) {
|
||||
return pluginClassLoaderClass.isInstance(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears and closes the provided classloader.
|
||||
* @param loader The classloader instance.
|
||||
* @return The Closeable object.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
public static Closeable clearClassLoader(ClassLoader loader) throws IllegalAccessException {
|
||||
if (loader == null) return null;
|
||||
if (isInstance(loader)) {
|
||||
clearUrlClassLoader(loader);
|
||||
}
|
||||
|
||||
if (loader instanceof Closeable) return (Closeable) loader;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the plugin fields from the specified PluginClassLoader.
|
||||
* @param pluginLoader The plugin loader instance.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
public static void clearUrlClassLoader(Object pluginLoader) throws IllegalAccessException {
|
||||
if (pluginLoader == null) return;
|
||||
set(fields, pluginLoader, "plugin", null);
|
||||
set(fields, pluginLoader, "pluginInit", null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.MethodParam.methodOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllMethods;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class RPropertyManager {
|
||||
|
||||
private static Class<?> propertyManagerClass;
|
||||
private static Map<String, Method> methods;
|
||||
|
||||
static {
|
||||
try {
|
||||
propertyManagerClass = Class.forName(String.format("net.minecraft.server.%s.PropertyManager",
|
||||
BukkitReflection.NMS));
|
||||
methods = getAllMethods(propertyManagerClass,
|
||||
methodOf("getBoolean", ALL_VERSIONS, String.class, boolean.class),
|
||||
methodOf("getString", ALL_VERSIONS, String.class, String.class));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object newInstance(Object options) throws ReflectiveOperationException {
|
||||
return propertyManagerClass.getDeclaredConstructor(Class.forName("joptsimple.OptionSet")).newInstance(options);
|
||||
}
|
||||
|
||||
public static Map<String, Method> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.frankheijden.serverutils.common.utils.MapUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class RRegistryMaterials {
|
||||
|
||||
private static Class<?> registryMaterialsClass;
|
||||
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
registryMaterialsClass = Class.forName(String.format("net.minecraft.server.%s.RegistryMaterials",
|
||||
BukkitReflection.NMS));
|
||||
fields = getAllFields(registryMaterialsClass,
|
||||
fieldOf("b", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all registered keys from an instance associated to the specified plugin.
|
||||
* @param instance The RegistryMaterials instance.
|
||||
* @param plugin The plugin to remove keys for.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void removeKeysFor(Object instance, Plugin plugin) throws IllegalAccessException {
|
||||
Map map = (Map) get(fields, instance, "b");
|
||||
if (map == null) throw new RuntimeException("Map object was null!");
|
||||
|
||||
AtomicBoolean errorThrown = new AtomicBoolean(false);
|
||||
MapUtils.removeValues(map, RMinecraftKey.matchingPluginPredicate(errorThrown, plugin));
|
||||
RRegistrySimple.removeKeyFor(instance, plugin);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.frankheijden.serverutils.common.utils.MapUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class RRegistrySimple {
|
||||
|
||||
private static Class<?> registrySimpleClass;
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
registrySimpleClass = Class.forName(String.format("net.minecraft.server.%s.RegistrySimple",
|
||||
BukkitReflection.NMS));
|
||||
fields = getAllFields(registrySimpleClass,
|
||||
fieldOf("c", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all registered MinecraftKey's from an instance associated to the specified plugin.
|
||||
* @param instance The RegistrySimple instance.
|
||||
* @param plugin The plugin to remove keys for.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void removeKeyFor(Object instance, Plugin plugin) throws IllegalAccessException {
|
||||
Map map = (Map) get(fields, instance, "c");
|
||||
if (map == null) throw new RuntimeException("Map object was null!");
|
||||
|
||||
AtomicBoolean errorThrown = new AtomicBoolean(false);
|
||||
MapUtils.removeKeys(map, RMinecraftKey.matchingPluginPredicate(errorThrown, plugin));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package net.frankheijden.serverutils.bukkit.reflection;
|
||||
|
||||
import static net.frankheijden.serverutils.common.reflection.FieldParam.fieldOf;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.get;
|
||||
import static net.frankheijden.serverutils.common.reflection.ReflectionUtils.getAllFields;
|
||||
import static net.frankheijden.serverutils.common.reflection.VersionParam.ALL_VERSIONS;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginLoader;
|
||||
import org.bukkit.plugin.SimplePluginManager;
|
||||
|
||||
public class RSimplePluginManager {
|
||||
|
||||
private static Class<?> simplePluginManagerClass;
|
||||
private static Map<String, Field> fields;
|
||||
|
||||
static {
|
||||
try {
|
||||
simplePluginManagerClass = SimplePluginManager.class;
|
||||
fields = getAllFields(simplePluginManagerClass,
|
||||
fieldOf("plugins", ALL_VERSIONS),
|
||||
fieldOf("lookupNames", ALL_VERSIONS),
|
||||
fieldOf("fileAssociations", ALL_VERSIONS));
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<Pattern, PluginLoader> getFileAssociations(Object manager) throws IllegalAccessException {
|
||||
return (Map<Pattern, PluginLoader>) get(fields, manager, "fileAssociations");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Plugin> getPlugins(Object manager) throws IllegalAccessException {
|
||||
return (List<Plugin>) get(fields, manager, "plugins");
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the lookup name of the plugin.
|
||||
* This ensures the plugin cannot be found anymore in Bukkit#getPlugin(String name).
|
||||
* @param manager The SimplePluginManager instance to remove the lookup name from.
|
||||
* @param name The name of the plugin to remove.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void removeLookupName(Object manager, String name) throws IllegalAccessException {
|
||||
Map<String, Plugin> lookupNames = (Map<String, Plugin>) get(fields, manager, "lookupNames");
|
||||
if (lookupNames == null) return;
|
||||
lookupNames.remove(name.replace(' ', '_'));
|
||||
lookupNames.remove(name.replace(' ', '_').toLowerCase(Locale.ENGLISH)); // Paper
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
package net.frankheijden.serverutils.bukkit.tasks;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.ServerUtils;
|
||||
import net.frankheijden.serverutils.bukkit.config.Config;
|
||||
import net.frankheijden.serverutils.bukkit.config.Messenger;
|
||||
import net.frankheijden.serverutils.bukkit.managers.CloseableResult;
|
||||
import net.frankheijden.serverutils.bukkit.managers.PluginManager;
|
||||
import net.frankheijden.serverutils.bukkit.managers.VersionManager;
|
||||
import net.frankheijden.serverutils.common.utils.FileUtils;
|
||||
import net.frankheijden.serverutils.common.utils.VersionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class UpdateCheckerTask implements Runnable {
|
||||
|
||||
private static final ServerUtils plugin = ServerUtils.getInstance();
|
||||
private static final VersionManager versionManager = VersionManager.getInstance();
|
||||
private final CommandSender sender;
|
||||
private final String currentVersion;
|
||||
private final boolean startup;
|
||||
|
||||
private static final String GITHUB_LINK = "https://api.github.com/repos/FrankHeijden/ServerUtils/releases/latest";
|
||||
|
||||
private static final String UPDATE_CHECK_START = "Checking for updates...";
|
||||
private static final String GENERAL_ERROR = "Error fetching new version of ServerUtils";
|
||||
private static final String TRY_LATER = GENERAL_ERROR + ", please try again later!";
|
||||
private static final String CONNECTION_ERROR = GENERAL_ERROR + ": (%s) %s (maybe check your connection?)";
|
||||
private static final String UNAVAILABLE = GENERAL_ERROR + ": (%s) %s (no update available)";
|
||||
private static final String UPDATE_AVAILABLE = "ServerUtils %s is available!";
|
||||
private static final String DOWNLOAD_START = "Started downloading from \"%s\"...";
|
||||
private static final String DOWNLOAD_ERROR = "Error downloading a new version of ServerUtils";
|
||||
private static final String UPGRADE_SUCCESS = "Successfully upgraded ServerUtils to v%s!";
|
||||
private static final String DOWNLOADED_RESTART = "Downloaded ServerUtils version v%s. Restarting plugin now...";
|
||||
private static final String UP_TO_DATE = "We are up-to-date!";
|
||||
|
||||
private UpdateCheckerTask(CommandSender sender, boolean startup) {
|
||||
this.sender = sender;
|
||||
this.currentVersion = plugin.getDescription().getVersion();
|
||||
this.startup = startup;
|
||||
}
|
||||
|
||||
public static void start(CommandSender sender) {
|
||||
start(sender, false);
|
||||
}
|
||||
|
||||
public static void start(CommandSender sender, boolean startup) {
|
||||
UpdateCheckerTask task = new UpdateCheckerTask(sender, startup);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, task);
|
||||
}
|
||||
|
||||
public boolean isStartupCheck() {
|
||||
return this.startup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isStartupCheck()) {
|
||||
plugin.getLogger().info(UPDATE_CHECK_START);
|
||||
}
|
||||
|
||||
JsonElement jsonElement;
|
||||
try {
|
||||
jsonElement = FileUtils.readJsonFromUrl(GITHUB_LINK);
|
||||
} catch (ConnectException | UnknownHostException | SocketTimeoutException ex) {
|
||||
plugin.getLogger().severe(String.format(CONNECTION_ERROR, ex.getClass().getSimpleName(), ex.getMessage()));
|
||||
return;
|
||||
} catch (FileNotFoundException ex) {
|
||||
plugin.getLogger().severe(String.format(UNAVAILABLE, ex.getClass().getSimpleName(), ex.getMessage()));
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, ex, () -> GENERAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsonElement == null) {
|
||||
plugin.getLogger().warning(TRY_LATER);
|
||||
return;
|
||||
}
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
if (jsonObject.has("message")) {
|
||||
plugin.getLogger().warning(jsonObject.get("message").getAsString());
|
||||
return;
|
||||
}
|
||||
|
||||
String githubVersion = getVersion(jsonObject);
|
||||
String body = jsonObject.getAsJsonPrimitive("body").getAsString();
|
||||
String downloadUrl = getDownloadUrl(jsonObject);
|
||||
|
||||
if (VersionUtils.isNewVersion(currentVersion, githubVersion)) {
|
||||
if (isStartupCheck()) {
|
||||
plugin.getLogger().info(String.format(UPDATE_AVAILABLE, githubVersion));
|
||||
plugin.getLogger().info("Release info: " + body);
|
||||
}
|
||||
if (canDownloadPlugin()) {
|
||||
if (isStartupCheck()) {
|
||||
plugin.getLogger().info(String.format(DOWNLOAD_START, downloadUrl));
|
||||
} else {
|
||||
Messenger.sendMessage(sender, "serverutils.update.downloading",
|
||||
"%old%", currentVersion,
|
||||
"%new%", githubVersion,
|
||||
"%info%", body);
|
||||
}
|
||||
downloadPlugin(githubVersion, downloadUrl);
|
||||
tryReloadPlugin();
|
||||
} else if (!isStartupCheck()) {
|
||||
Messenger.sendMessage(sender, "serverutils.update.available",
|
||||
"%old%", currentVersion,
|
||||
"%new%", githubVersion,
|
||||
"%info%", body);
|
||||
}
|
||||
} else if (versionManager.hasDownloaded()) {
|
||||
Messenger.sendMessage(sender, "serverutils.update.success",
|
||||
"%new%", versionManager.getDownloadedVersion());
|
||||
} else if (isStartupCheck()) {
|
||||
plugin.getLogger().info(UP_TO_DATE);
|
||||
}
|
||||
}
|
||||
|
||||
private String getVersion(JsonObject jsonObject) {
|
||||
return jsonObject.getAsJsonPrimitive("tag_name").getAsString().replace("v", "");
|
||||
}
|
||||
|
||||
private String getDownloadUrl(JsonObject jsonObject) {
|
||||
JsonArray assets = jsonObject.getAsJsonArray("assets");
|
||||
if (assets != null && assets.size() > 0) {
|
||||
return assets.get(0).getAsJsonObject().getAsJsonPrimitive("browser_download_url").getAsString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean canDownloadPlugin() {
|
||||
if (isStartupCheck()) return Config.getInstance().getBoolean("settings.download-at-startup-and-update");
|
||||
return Config.getInstance().getBoolean("settings.download-updates");
|
||||
}
|
||||
|
||||
private void downloadPlugin(String githubVersion, String downloadLink) {
|
||||
if (versionManager.isDownloadedVersion(githubVersion)) {
|
||||
broadcastDownloadStatus(githubVersion, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (downloadLink == null) {
|
||||
broadcastDownloadStatus(githubVersion, true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
FileUtils.download(downloadLink, getPluginFile());
|
||||
} catch (IOException ex) {
|
||||
broadcastDownloadStatus(githubVersion, true);
|
||||
throw new RuntimeException(DOWNLOAD_ERROR, ex);
|
||||
}
|
||||
|
||||
versionManager.setDownloadedVersion(githubVersion);
|
||||
}
|
||||
|
||||
private void tryReloadPlugin() {
|
||||
String downloadedVersion = versionManager.getDownloadedVersion();
|
||||
|
||||
if (isStartupCheck()) {
|
||||
plugin.getLogger().info(String.format(DOWNLOADED_RESTART, downloadedVersion));
|
||||
CloseableResult result = PluginManager.reloadPlugin(plugin);
|
||||
plugin.getLogger().info(String.format(UPGRADE_SUCCESS, downloadedVersion));
|
||||
result.tryClose();
|
||||
} else {
|
||||
broadcastDownloadStatus(downloadedVersion, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastDownloadStatus(String githubVersion, boolean isError) {
|
||||
final String path = "serverutils.update." + (isError ? "failed" : "success");
|
||||
Bukkit.getOnlinePlayers().forEach((p) -> {
|
||||
if (p.hasPermission("serverutils.notification.update")) {
|
||||
Messenger.sendMessage(sender, path, "%new%", githubVersion);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private File getPluginFile() {
|
||||
try {
|
||||
Method method = JavaPlugin.class.getDeclaredMethod("getFile");
|
||||
method.setAccessible(true);
|
||||
return (File) method.invoke(plugin);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Error retrieving current plugin file", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package net.frankheijden.serverutils.bukkit.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.frankheijden.serverutils.bukkit.config.Messenger;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class FormatBuilder {
|
||||
|
||||
private final String format;
|
||||
private final List<String[]> valueList;
|
||||
private String[] orderedKeys;
|
||||
private boolean alwaysSend;
|
||||
|
||||
private FormatBuilder(String format) {
|
||||
this.format = format;
|
||||
this.valueList = new ArrayList<>();
|
||||
this.orderedKeys = new String[0];
|
||||
this.alwaysSend = false;
|
||||
}
|
||||
|
||||
public static FormatBuilder create(String format) {
|
||||
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 alwaysSend(boolean alwaysSend) {
|
||||
this.alwaysSend = alwaysSend;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the format and sends it to the CommandSender.
|
||||
* @param sender The receiver of the list.
|
||||
*/
|
||||
public void sendTo(CommandSender sender) {
|
||||
valueList.forEach(values -> {
|
||||
int length = Math.min(values.length, orderedKeys.length);
|
||||
String message = format;
|
||||
for (int i = 0; i < length; i++) {
|
||||
String value = values[i];
|
||||
if ((value == null || value.isEmpty()) && !alwaysSend) return;
|
||||
message = message.replace(orderedKeys[i], String.valueOf(value));
|
||||
}
|
||||
Messenger.sendRawMessage(sender, message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.frankheijden.serverutils.bukkit.utils;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
import net.frankheijden.serverutils.common.utils.PredicateFilter;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class ForwardFilter extends PredicateFilter {
|
||||
|
||||
private boolean warnings;
|
||||
|
||||
/**
|
||||
* Creates a filter which forwards all output to the sender.
|
||||
* @param sender The sender to forward logs to.
|
||||
*/
|
||||
public ForwardFilter(CommandSender sender) {
|
||||
this.warnings = false;
|
||||
|
||||
setPredicate(rec -> {
|
||||
ChatColor color = getColor(rec.getLevel());
|
||||
if (color != ChatColor.GREEN) warnings = true;
|
||||
sender.sendMessage(color + format(rec));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public boolean hasWarnings() {
|
||||
return warnings;
|
||||
}
|
||||
|
||||
private static ChatColor getColor(Level level) {
|
||||
if (Level.SEVERE.equals(level)) {
|
||||
return ChatColor.RED;
|
||||
} else if (Level.WARNING.equals(level)) {
|
||||
return ChatColor.GOLD;
|
||||
}
|
||||
return ChatColor.GREEN;
|
||||
}
|
||||
|
||||
private static String format(LogRecord record) {
|
||||
String msg = record.getMessage();
|
||||
|
||||
Object[] params = record.getParameters();
|
||||
if (params == null) return msg;
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
msg = msg.replace("{" + i + "}", String.valueOf(params[i]));
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package net.frankheijden.serverutils.bukkit.utils;
|
||||
|
||||
public interface ReloadHandler {
|
||||
|
||||
void handle() throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package net.frankheijden.serverutils.bukkit.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.configuration.MemorySection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class YamlUtils {
|
||||
|
||||
public static void addDefaults(MemorySection defaults, YamlConfiguration yml) {
|
||||
addDefaults(defaults, yml, "");
|
||||
}
|
||||
|
||||
private static void addDefaults(MemorySection defaults, YamlConfiguration yml, String root) {
|
||||
if (defaults == null) return;
|
||||
for (String key : defaults.getKeys(false)) {
|
||||
String newKey = (root.isEmpty() ? "" : root + ".") + key;
|
||||
Object value = defaults.get(key);
|
||||
if (value instanceof MemorySection) {
|
||||
addDefaults((MemorySection) value, yml, newKey);
|
||||
} else if (yml.get(newKey) == null) {
|
||||
yml.set(newKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates a YamlConfiguration from a file with associated defaults.
|
||||
* @param file The yml file.
|
||||
* @param def The default YamlConfiguration to be applied.
|
||||
* @return The loaded YamlConfiguration of the file with defaults.
|
||||
*/
|
||||
public static YamlConfiguration init(File file, YamlConfiguration def) {
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
||||
YamlUtils.addDefaults(def, yml);
|
||||
|
||||
try {
|
||||
// Idk somehow the order messes up
|
||||
// of the messages if we don't do this
|
||||
file.delete();
|
||||
file.createNewFile();
|
||||
|
||||
yml.save(file);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return yml;
|
||||
}
|
||||
}
|
||||
6
Bukkit/src/main/resources/bukkit-config.yml
Normal file
6
Bukkit/src/main/resources/bukkit-config.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
settings:
|
||||
disable-plugins-command: false
|
||||
check-updates: true
|
||||
check-updates-login: false
|
||||
download-updates: false
|
||||
download-at-startup-and-update: false
|
||||
57
Bukkit/src/main/resources/bukkit-messages.yml
Normal file
57
Bukkit/src/main/resources/bukkit-messages.yml
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
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%"
|
||||
update:
|
||||
available: |-
|
||||
&8&m------------=&r&8[ &b&lServerUtils Update&r &8]&m=--------------
|
||||
&3Current version: &b%old%
|
||||
&3New version: &b%new%
|
||||
&3Release info: &b%info%
|
||||
&8&m-------------------------------------------------
|
||||
downloading: |-
|
||||
&8&m------------=&r&8[ &b&lServerUtils Update&r &8]&m=--------------
|
||||
&3A new version of ServerUtils will be downloaded and installed after a restart!
|
||||
&3Current version: &b%old%
|
||||
&3New version: &b%new%
|
||||
&3Release info: &b%info%
|
||||
&8&m-------------------------------------------------
|
||||
download_failed: "&cFailed to download version %new% of ServerUtils. Please update manually."
|
||||
download_success: "&3ServerUtils has been downloaded and will be installed on the next restart."
|
||||
help:
|
||||
header: "&8&m-------------=&r&8[ &b&lServerUtils Help&r &8]&m=---------------"
|
||||
format: "&8/&3%command%&b%subcommand% &f(&7%help%&f)"
|
||||
footer: "&8&m-------------------------------------------------"
|
||||
plugins:
|
||||
header: "&8&m------------=&r&8[ &b&lServerUtils Plugins&r &8]&m=-------------"
|
||||
prefix: " &3Plugins &8(&a%count%&8)&b: "
|
||||
format: "&3%plugin%"
|
||||
format_disabled: "&c%plugin%"
|
||||
seperator: "&b, "
|
||||
last_seperator: " &band "
|
||||
version: " &8(&a%version%&8)"
|
||||
footer: "&8&m-------------------------------------------------"
|
||||
plugininfo:
|
||||
header: "&8&m-----------=&r&8[ &b&lServerUtils PluginInfo&r &8]&m=-----------"
|
||||
format: " &3%key%&8: &b%value%"
|
||||
list_format: "&b%value%"
|
||||
seperator: "&8, "
|
||||
last_seperator: " &8and "
|
||||
footer: "&8&m-------------------------------------------------"
|
||||
commandinfo:
|
||||
header: "&8&m-----------=&r&8[ &b&lServerUtils CommandInfo&r &8]&m=----------"
|
||||
format: " &3%key%&8: &b%value%"
|
||||
list_format: "&b%value%"
|
||||
seperator: "&8, "
|
||||
last_seperator: " &8and "
|
||||
footer: "&8&m-------------------------------------------------"
|
||||
not_exists: "&cThat command is not a valid registered command."
|
||||
12
Bukkit/src/main/resources/plugin.yml
Normal file
12
Bukkit/src/main/resources/plugin.yml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
name: ServerUtils
|
||||
main: net.frankheijden.serverutils.bukkit.ServerUtils
|
||||
version: ${version}
|
||||
author: FrankHeijden
|
||||
api-version: '1.13'
|
||||
|
||||
commands:
|
||||
serverutils:
|
||||
usage: "/<command>"
|
||||
aliases:
|
||||
- "su"
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue