From 187d2dbe32060fede2c9770aff155c98b978cb4f Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Mon, 8 Jul 2019 18:22:50 -0500 Subject: [PATCH] Code cleanups, more work on API --- api/pom.xml | 8 ++ .../main/java/org/geysermc/api/Connector.java | 48 ++++++++++ .../main/java/org/geysermc/api/Geyser.java | 55 ++++++++++-- .../org/geysermc/api/command/CommandMap.java | 42 +++++++++ .../java/org/geysermc/api/logger/Logger.java | 46 ++++++++++ .../java/org/geysermc/api/plugin/Plugin.java | 17 ++++ .../geysermc/api/plugin/PluginManager.java | 55 ++++++++++++ .../geysermc/connector/GeyserConnector.java | 29 ++++-- .../connector/command/GeyserCommandMap.java | 3 +- .../connector/console/GeyserLogger.java | 2 +- .../connector/plugin/GeyserPluginLoader.java | 89 +++++++++++++++++++ .../connector/plugin/GeyserPluginManager.java | 56 ++++++++++++ .../org/geysermc/connector/plugin/Loader.java | 89 ------------------- 13 files changed, 433 insertions(+), 106 deletions(-) create mode 100644 api/src/main/java/org/geysermc/api/Connector.java create mode 100644 api/src/main/java/org/geysermc/api/command/CommandMap.java create mode 100644 api/src/main/java/org/geysermc/api/logger/Logger.java create mode 100644 api/src/main/java/org/geysermc/api/plugin/PluginManager.java create mode 100644 connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java create mode 100644 connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java delete mode 100644 connector/src/main/java/org/geysermc/connector/plugin/Loader.java diff --git a/api/pom.xml b/api/pom.xml index b6455baf4..eb6b8c201 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -9,4 +9,12 @@ ${revision} api + + + org.projectlombok + lombok + 1.18.4 + compile + + \ No newline at end of file diff --git a/api/src/main/java/org/geysermc/api/Connector.java b/api/src/main/java/org/geysermc/api/Connector.java new file mode 100644 index 000000000..68478b657 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/Connector.java @@ -0,0 +1,48 @@ +/* + * GNU LESSER GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + * + * You can view the LICENCE file for details. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api; + +import org.geysermc.api.command.CommandMap; +import org.geysermc.api.logger.Logger; +import org.geysermc.api.plugin.PluginManager; + +public interface Connector { + + /** + * Returns the logger + * + * @return the logger + */ + Logger getLogger(); + + /** + * Returns the command map + * + * @return the command map + */ + CommandMap getCommandMap(); + + /** + * Returns the plugin manager + * + * @return the plugin manager + */ + PluginManager getPluginManager(); + + /** + * Shuts down the connector + */ + void shutdown(); +} diff --git a/api/src/main/java/org/geysermc/api/Geyser.java b/api/src/main/java/org/geysermc/api/Geyser.java index e8f68d163..cbbc01bd2 100644 --- a/api/src/main/java/org/geysermc/api/Geyser.java +++ b/api/src/main/java/org/geysermc/api/Geyser.java @@ -1,18 +1,55 @@ package org.geysermc.api; -import org.geysermc.api.plugin.Plugin; - -import java.util.ArrayList; -import java.util.List; +import org.geysermc.api.command.CommandMap; +import org.geysermc.api.logger.Logger; +import org.geysermc.api.plugin.PluginManager; public class Geyser { - private static final List plugins = new ArrayList<>(); - public static List getPlugins() { - return new ArrayList<>(plugins); + private static Connector connector; + + /** + * Returns the connector instance for Geyser + * + * @return the connector instance for Geyser + */ + public static Connector getConnector() { + return connector; } - public static void add(Plugin p) { - plugins.add(p); + /** + * Sets the connector instance for Geyser + * + * @param connector the connector instance + */ + public static void setConnector(Connector connector) { + Geyser.connector = connector; + } + + /** + * Returns the logger + * + * @return the logger + */ + public static Logger getLogger() { + return connector.getLogger(); + } + + /** + * Returns the plugin manager + * + * @return the plugin manager + */ + public static PluginManager getPluginManager() { + return connector.getPluginManager(); + } + + /** + * Returns the command map + * + * @return the command map + */ + public static CommandMap getCommandMap() { + return connector.getCommandMap(); } } diff --git a/api/src/main/java/org/geysermc/api/command/CommandMap.java b/api/src/main/java/org/geysermc/api/command/CommandMap.java new file mode 100644 index 000000000..41db01d61 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/command/CommandMap.java @@ -0,0 +1,42 @@ +/* + * GNU LESSER GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + * + * You can view the LICENCE file for details. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.command; + +import java.util.Map; + +public interface CommandMap { + + /** + * Registers a new command + * + * @param command the command to register + */ + void registerCommand(Command command); + + /** + * Runs a command for the given command sender + * + * @param sender the sender to run the command for + * @param command the command to run + */ + void runCommand(CommandSender sender, String command); + + /** + * Returns a map of the commands + * + * @return a map of the commands + */ + Map getCommands(); +} diff --git a/api/src/main/java/org/geysermc/api/logger/Logger.java b/api/src/main/java/org/geysermc/api/logger/Logger.java new file mode 100644 index 000000000..3a58714d8 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/logger/Logger.java @@ -0,0 +1,46 @@ +/* + * GNU LESSER GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + * + * You can view the LICENCE file for details. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.logger; + +public interface Logger { + + /** + * Logs an info message to console + * + * @param message the message to log + */ + void info(String message); + + /** + * Logs a severe message to console + * + * @param message the message to log + */ + void severe(String message); + + /** + * Logs a warning message to console + * + * @param message the message to log + */ + void warning(String message); + + /** + * Logs a debug message to console + * + * @param message the message to log + */ + void debug(String message); +} diff --git a/api/src/main/java/org/geysermc/api/plugin/Plugin.java b/api/src/main/java/org/geysermc/api/plugin/Plugin.java index 90299b6de..fb7b09f1a 100644 --- a/api/src/main/java/org/geysermc/api/plugin/Plugin.java +++ b/api/src/main/java/org/geysermc/api/plugin/Plugin.java @@ -1,14 +1,31 @@ package org.geysermc.api.plugin; +import lombok.Getter; +import lombok.Setter; + public class Plugin { + + @Getter + @Setter + private boolean enabled = true; + + /** + * Called when a plugin is enabled + */ public void onEnable() { } + /** + * Called when a plugin is disabled + */ public void onDisable() { } + /** + * Called when a plugin is loaded + */ public void onLoad() { } diff --git a/api/src/main/java/org/geysermc/api/plugin/PluginManager.java b/api/src/main/java/org/geysermc/api/plugin/PluginManager.java new file mode 100644 index 000000000..6a8567ef0 --- /dev/null +++ b/api/src/main/java/org/geysermc/api/plugin/PluginManager.java @@ -0,0 +1,55 @@ +/* + * GNU LESSER GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + * + * You can view the LICENCE file for details. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.api.plugin; + +import java.util.Set; + +public interface PluginManager { + + /** + * Loads a plugin and all its class files + * + * @param plugin the plugin to load + */ + void loadPlugin(Plugin plugin); + + /** + * Enables a plugin + * + * @param plugin the plugin to enable + */ + void enablePlugin(Plugin plugin); + + /** + * Disables a plugin + * + * @param plugin the plugin to disable + */ + void disablePlugin(Plugin plugin); + + /** + * Unloads a plugin + * + * @param plugin the plugin to unload + */ + void unloadPlugin(Plugin plugin); + + /** + * Returns a set of the loaded plugins + * + * @return a set of the loaded plugins + */ + Set getPlugins(); +} diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index ec3ac0b18..b6dc1d1e2 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -20,11 +20,17 @@ import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.v354.Bedrock_v354; import lombok.Getter; import org.geysermc.api.ChatColor; +import org.geysermc.api.Connector; +import org.geysermc.api.Geyser; +import org.geysermc.api.command.CommandMap; +import org.geysermc.api.logger.Logger; +import org.geysermc.api.plugin.Plugin; import org.geysermc.connector.command.GeyserCommandMap; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.console.ConsoleCommandReader; import org.geysermc.connector.console.GeyserLogger; -import org.geysermc.connector.plugin.Loader; +import org.geysermc.connector.plugin.GeyserPluginLoader; +import org.geysermc.connector.plugin.GeyserPluginManager; import java.io.File; import java.io.FileOutputStream; @@ -33,7 +39,7 @@ import java.io.InputStream; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -public class GeyserConnector { +public class GeyserConnector implements Connector { public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v354.V354_CODEC; @@ -43,14 +49,17 @@ public class GeyserConnector { private static GeyserConnector instance; @Getter - private GeyserLogger logger; + private Logger logger; @Getter - private GeyserCommandMap commandMap; + private CommandMap commandMap; @Getter private GeyserConfiguration config; + @Getter + private GeyserPluginManager pluginManager; + @Getter private boolean shuttingDown = false; @@ -95,13 +104,21 @@ public class GeyserConnector { shutdown(); } - Loader.start(); - commandMap = new GeyserCommandMap(this); + + Geyser.setConnector(this); + + pluginManager = new GeyserPluginManager(new GeyserPluginLoader(this)); + pluginManager.getLoader().loadPlugins(); } public void shutdown() { logger.info("Shutting down connector."); + for (Plugin plugin : pluginManager.getPlugins()) { + pluginManager.disablePlugin(plugin); + pluginManager.unloadPlugin(plugin); + } + shuttingDown = true; generalThreadPool.shutdown(); diff --git a/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java b/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java index c1d58d324..54f94b5a7 100644 --- a/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java +++ b/connector/src/main/java/org/geysermc/connector/command/GeyserCommandMap.java @@ -15,6 +15,7 @@ package org.geysermc.connector.command; import org.geysermc.api.command.Command; +import org.geysermc.api.command.CommandMap; import org.geysermc.api.command.CommandSender; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.defaults.HelpCommand; @@ -24,7 +25,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -public class GeyserCommandMap { +public class GeyserCommandMap implements CommandMap { private final Map commandMap = Collections.synchronizedMap(new HashMap()); private GeyserConnector connector; diff --git a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java index c8be0642b..699de4836 100644 --- a/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java +++ b/connector/src/main/java/org/geysermc/connector/console/GeyserLogger.java @@ -30,7 +30,7 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; -public class GeyserLogger { +public class GeyserLogger implements org.geysermc.api.logger.Logger { private Logger logger; diff --git a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java new file mode 100644 index 000000000..df3bdeb4a --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginLoader.java @@ -0,0 +1,89 @@ +package org.geysermc.connector.plugin; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import org.geysermc.api.Connector; +import org.geysermc.api.Geyser; +import org.geysermc.api.plugin.Plugin; +import org.geysermc.connector.GeyserConnector; + +import java.io.File; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class GeyserPluginLoader extends ClassLoader { + + private Connector connector; + + public GeyserPluginLoader(Connector connector) { + this.connector = connector; + } + + public void loadPlugins() { + File dir = new File("plugins"); + + if (!dir.exists()) { + dir.mkdir(); + } + + for (File f : dir.listFiles()) { + if (!f.getName().endsWith(".jar")) + continue; + + try { + ZipFile file = new ZipFile(f); + ZipEntry e = file.getEntry("plugin.yml"); + + if (e == null || e.isDirectory()) { + connector.getLogger().severe("Plugin " + f.getName() + " has no valid plugin.yml!"); + continue; + } + + file.stream().forEach((x) -> { + if (x.getName().endsWith(".class")) { + try { + InputStream is = file.getInputStream(x); + byte[] b = new byte[is.available()]; + is.read(b); + this.defineClass(x.getName().replace(".class", "").replaceAll("/", "."), b, 0, b.length); + is.close(); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + }); + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + InputStream is = file.getInputStream(e); + + PluginYML yml = mapper.readValue(is, PluginYML.class); + is.close(); + Plugin plugin = (Plugin) Class.forName(yml.main, true, this).newInstance(); + connector.getLogger().info("Loading plugin " + yml.name + " version " + yml.version); + connector.getPluginManager().loadPlugin(plugin); + } catch (Exception e) { + connector.getLogger().severe("Error loading plugin " + f.getName()); + e.printStackTrace(); + } + } + + for (Plugin plugin : connector.getPluginManager().getPlugins()) { + connector.getPluginManager().enablePlugin(plugin); + } + } + + public void loadPlugin(Plugin plugin) { + plugin.onLoad(); + } + + public void enablePlugin(Plugin plugin) { + plugin.setEnabled(true); + plugin.onEnable(); + } + + public void disablePlugin(Plugin plugin) { + plugin.setEnabled(false); + plugin.onDisable(); + } +} diff --git a/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java new file mode 100644 index 000000000..895d5cd06 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/plugin/GeyserPluginManager.java @@ -0,0 +1,56 @@ +/* + * GNU LESSER GENERAL PUBLIC LICENSE + * Version 3, 29 June 2007 + * + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + * + * You can view the LICENCE file for details. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.connector.plugin; + +import lombok.Getter; +import org.geysermc.api.plugin.Plugin; +import org.geysermc.api.plugin.PluginManager; + +import java.util.HashSet; +import java.util.Set; + +public class GeyserPluginManager implements PluginManager { + + @Getter + private GeyserPluginLoader loader; + + @Getter + private Set plugins = new HashSet(); + + public GeyserPluginManager(GeyserPluginLoader loader) { + this.loader = loader; + } + + public void loadPlugin(Plugin plugin) { + loader.loadPlugin(plugin); + plugins.add(plugin); + } + + public void unloadPlugin(Plugin plugin) { + plugins.remove(plugin); + } + + public void enablePlugin(Plugin plugin) { + loader.enablePlugin(plugin); + } + + public void disablePlugin(Plugin plugin) { + loader.disablePlugin(plugin); + } + + public Set getPlugins() { + return plugins; + } +} \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/plugin/Loader.java b/connector/src/main/java/org/geysermc/connector/plugin/Loader.java deleted file mode 100644 index e51bbd487..000000000 --- a/connector/src/main/java/org/geysermc/connector/plugin/Loader.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.geysermc.connector.plugin; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import org.geysermc.api.Geyser; -import org.geysermc.api.plugin.Plugin; - -import java.io.File; -import java.io.InputStream; -import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -public class Loader extends ClassLoader { - static { - System.out.println("a"); - Loader l = new Loader(); - System.out.println("b"); - File dir = new File("plugins"); - System.out.println(dir.getAbsoluteFile()); - - if(!dir.exists()) { - dir.mkdir(); - } - - for(File f : dir.listFiles()) { - if(f.getName().endsWith(".jar")) { - try { - ZipFile file = new ZipFile(f); - - ZipEntry e = file.getEntry("plugin.yml"); - - if(e == null || e.isDirectory()) { - System.err.println("Plugin " + f.getName() + " has no valid plugin.yml!"); - continue; - } - - file.stream().forEach((x) -> { - if(x.getName().endsWith(".class")) { - try { - InputStream is = file.getInputStream(x); - byte[] b = new byte[is.available()]; - is.read(b); - l.defineClass(x.getName().replace(".class", "").replaceAll("/", "."), b, 0, b.length); - is.close(); - } catch (Exception e1) { - e1.printStackTrace(); - } - } - }); - - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - - InputStream is = file.getInputStream(e); - - PluginYML yml; - - yml = mapper.readValue(is, PluginYML.class); - - is.close(); - - Plugin plugin = (Plugin) Class.forName(yml.main, true, l).newInstance(); - - plugin.onLoad(); - - Geyser.add(plugin); - - } catch (Exception e) { - System.out.println("Error loading plugin " + f.getName()); - e.printStackTrace(); - } - } - } - for(Plugin p : Geyser.getPlugins()) { - p.onEnable(); - } - LOADER = l; - } - - public static final Loader LOADER; - - public static void start() { - - } - - private Loader() { - - } -}