From 4810dcf339a59f49305e184fc22abf839d41c310 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 6 Nov 2018 16:16:01 +0100 Subject: Moved files to use the gradle structure --- plugin.yml | 5 - .../annotations/AutoRegisterListener.java | 15 - src/com/redstoner/annotations/Commands.java | 15 - src/com/redstoner/annotations/Version.java | 32 - .../coremods/moduleLoader/ModuleLoader.cmd | 34 - .../coremods/moduleLoader/ModuleLoader.java | 736 --------------------- .../exceptions/MissingVersionException.java | 22 - .../exceptions/NonSaveableConfigException.java | 9 - src/com/redstoner/misc/BroadcastFilter.java | 14 - src/com/redstoner/misc/CommandHolderType.java | 13 - src/com/redstoner/misc/JsonManager.java | 149 ----- src/com/redstoner/misc/Main.java | 36 - src/com/redstoner/misc/Utils.java | 149 ----- src/com/redstoner/misc/VersionHelper.java | 151 ----- src/com/redstoner/misc/mysql/Config.java | 278 -------- src/com/redstoner/misc/mysql/JSONManager.java | 107 --- src/com/redstoner/misc/mysql/MysqlHandler.java | 115 ---- .../redstoner/misc/mysql/MysqlQueryHandler.java | 33 - .../misc/mysql/elements/ConstraintOperator.java | 24 - .../misc/mysql/elements/MysqlConstraint.java | 24 - .../misc/mysql/elements/MysqlDatabase.java | 90 --- .../redstoner/misc/mysql/elements/MysqlField.java | 33 - .../redstoner/misc/mysql/elements/MysqlResult.java | 16 - .../redstoner/misc/mysql/elements/MysqlTable.java | 133 ---- src/com/redstoner/misc/mysql/types/MysqlType.java | 96 --- src/com/redstoner/misc/mysql/types/date/Date.java | 10 - .../redstoner/misc/mysql/types/date/DateTime.java | 10 - src/com/redstoner/misc/mysql/types/date/Time.java | 10 - .../redstoner/misc/mysql/types/date/TimeStamp.java | 10 - src/com/redstoner/misc/mysql/types/date/Year.java | 10 - .../redstoner/misc/mysql/types/number/BigInt.java | 12 - .../redstoner/misc/mysql/types/number/Decimal.java | 10 - .../redstoner/misc/mysql/types/number/Double.java | 10 - .../redstoner/misc/mysql/types/number/Float.java | 10 - src/com/redstoner/misc/mysql/types/number/Int.java | 16 - .../misc/mysql/types/number/MediumInt.java | 12 - .../misc/mysql/types/number/SmallInt.java | 12 - .../redstoner/misc/mysql/types/number/TinyInt.java | 12 - src/com/redstoner/misc/mysql/types/text/Blob.java | 10 - src/com/redstoner/misc/mysql/types/text/Char.java | 16 - src/com/redstoner/misc/mysql/types/text/Enum.java | 27 - .../redstoner/misc/mysql/types/text/LongBlob.java | 8 - .../redstoner/misc/mysql/types/text/LongText.java | 8 - .../misc/mysql/types/text/MediumBlob.java | 8 - .../misc/mysql/types/text/MediumText.java | 8 - src/com/redstoner/misc/mysql/types/text/Set.java | 27 - src/com/redstoner/misc/mysql/types/text/Text.java | 10 - .../redstoner/misc/mysql/types/text/TinyText.java | 8 - .../redstoner/misc/mysql/types/text/VarChar.java | 16 - src/com/redstoner/modules/CoreModule.java | 24 - src/com/redstoner/modules/Module.java | 54 -- src/com/redstoner/modules/ModuleLogger.java | 76 --- .../annotations/AutoRegisterListener.java | 15 + .../java/com/redstoner/annotations/Commands.java | 15 + .../java/com/redstoner/annotations/Version.java | 32 + .../coremods/moduleLoader/ModuleLoader.cmd | 34 + .../coremods/moduleLoader/ModuleLoader.java | 736 +++++++++++++++++++++ .../exceptions/MissingVersionException.java | 22 + .../exceptions/NonSaveableConfigException.java | 9 + .../java/com/redstoner/misc/BroadcastFilter.java | 14 + .../java/com/redstoner/misc/CommandHolderType.java | 13 + src/main/java/com/redstoner/misc/JsonManager.java | 149 +++++ src/main/java/com/redstoner/misc/Main.java | 36 + src/main/java/com/redstoner/misc/Utils.java | 149 +++++ .../java/com/redstoner/misc/VersionHelper.java | 151 +++++ src/main/java/com/redstoner/misc/mysql/Config.java | 278 ++++++++ .../java/com/redstoner/misc/mysql/JSONManager.java | 107 +++ .../com/redstoner/misc/mysql/MysqlHandler.java | 115 ++++ .../redstoner/misc/mysql/MysqlQueryHandler.java | 33 + .../misc/mysql/elements/ConstraintOperator.java | 24 + .../misc/mysql/elements/MysqlConstraint.java | 24 + .../misc/mysql/elements/MysqlDatabase.java | 90 +++ .../redstoner/misc/mysql/elements/MysqlField.java | 33 + .../redstoner/misc/mysql/elements/MysqlResult.java | 16 + .../redstoner/misc/mysql/elements/MysqlTable.java | 133 ++++ .../com/redstoner/misc/mysql/types/MysqlType.java | 96 +++ .../com/redstoner/misc/mysql/types/date/Date.java | 10 + .../redstoner/misc/mysql/types/date/DateTime.java | 10 + .../com/redstoner/misc/mysql/types/date/Time.java | 10 + .../redstoner/misc/mysql/types/date/TimeStamp.java | 10 + .../com/redstoner/misc/mysql/types/date/Year.java | 10 + .../redstoner/misc/mysql/types/number/BigInt.java | 12 + .../redstoner/misc/mysql/types/number/Decimal.java | 10 + .../redstoner/misc/mysql/types/number/Double.java | 10 + .../redstoner/misc/mysql/types/number/Float.java | 10 + .../com/redstoner/misc/mysql/types/number/Int.java | 16 + .../misc/mysql/types/number/MediumInt.java | 12 + .../misc/mysql/types/number/SmallInt.java | 12 + .../redstoner/misc/mysql/types/number/TinyInt.java | 12 + .../com/redstoner/misc/mysql/types/text/Blob.java | 10 + .../com/redstoner/misc/mysql/types/text/Char.java | 16 + .../com/redstoner/misc/mysql/types/text/Enum.java | 27 + .../redstoner/misc/mysql/types/text/LongBlob.java | 8 + .../redstoner/misc/mysql/types/text/LongText.java | 8 + .../misc/mysql/types/text/MediumBlob.java | 8 + .../misc/mysql/types/text/MediumText.java | 8 + .../com/redstoner/misc/mysql/types/text/Set.java | 27 + .../com/redstoner/misc/mysql/types/text/Text.java | 10 + .../redstoner/misc/mysql/types/text/TinyText.java | 8 + .../redstoner/misc/mysql/types/text/VarChar.java | 16 + .../java/com/redstoner/modules/CoreModule.java | 24 + src/main/java/com/redstoner/modules/Module.java | 54 ++ .../java/com/redstoner/modules/ModuleLogger.java | 76 +++ src/main/resources/plugin.yml | 5 + 104 files changed, 2773 insertions(+), 2773 deletions(-) delete mode 100644 plugin.yml delete mode 100644 src/com/redstoner/annotations/AutoRegisterListener.java delete mode 100644 src/com/redstoner/annotations/Commands.java delete mode 100644 src/com/redstoner/annotations/Version.java delete mode 100644 src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd delete mode 100644 src/com/redstoner/coremods/moduleLoader/ModuleLoader.java delete mode 100644 src/com/redstoner/exceptions/MissingVersionException.java delete mode 100644 src/com/redstoner/exceptions/NonSaveableConfigException.java delete mode 100644 src/com/redstoner/misc/BroadcastFilter.java delete mode 100644 src/com/redstoner/misc/CommandHolderType.java delete mode 100644 src/com/redstoner/misc/JsonManager.java delete mode 100644 src/com/redstoner/misc/Main.java delete mode 100644 src/com/redstoner/misc/Utils.java delete mode 100644 src/com/redstoner/misc/VersionHelper.java delete mode 100644 src/com/redstoner/misc/mysql/Config.java delete mode 100644 src/com/redstoner/misc/mysql/JSONManager.java delete mode 100644 src/com/redstoner/misc/mysql/MysqlHandler.java delete mode 100644 src/com/redstoner/misc/mysql/MysqlQueryHandler.java delete mode 100644 src/com/redstoner/misc/mysql/elements/ConstraintOperator.java delete mode 100644 src/com/redstoner/misc/mysql/elements/MysqlConstraint.java delete mode 100644 src/com/redstoner/misc/mysql/elements/MysqlDatabase.java delete mode 100644 src/com/redstoner/misc/mysql/elements/MysqlField.java delete mode 100644 src/com/redstoner/misc/mysql/elements/MysqlResult.java delete mode 100644 src/com/redstoner/misc/mysql/elements/MysqlTable.java delete mode 100644 src/com/redstoner/misc/mysql/types/MysqlType.java delete mode 100644 src/com/redstoner/misc/mysql/types/date/Date.java delete mode 100644 src/com/redstoner/misc/mysql/types/date/DateTime.java delete mode 100644 src/com/redstoner/misc/mysql/types/date/Time.java delete mode 100644 src/com/redstoner/misc/mysql/types/date/TimeStamp.java delete mode 100644 src/com/redstoner/misc/mysql/types/date/Year.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/BigInt.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/Decimal.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/Double.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/Float.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/Int.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/MediumInt.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/SmallInt.java delete mode 100644 src/com/redstoner/misc/mysql/types/number/TinyInt.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/Blob.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/Char.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/Enum.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/LongBlob.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/LongText.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/MediumBlob.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/MediumText.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/Set.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/Text.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/TinyText.java delete mode 100644 src/com/redstoner/misc/mysql/types/text/VarChar.java delete mode 100644 src/com/redstoner/modules/CoreModule.java delete mode 100644 src/com/redstoner/modules/Module.java delete mode 100644 src/com/redstoner/modules/ModuleLogger.java create mode 100644 src/main/java/com/redstoner/annotations/AutoRegisterListener.java create mode 100644 src/main/java/com/redstoner/annotations/Commands.java create mode 100644 src/main/java/com/redstoner/annotations/Version.java create mode 100644 src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd create mode 100644 src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java create mode 100644 src/main/java/com/redstoner/exceptions/MissingVersionException.java create mode 100644 src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java create mode 100644 src/main/java/com/redstoner/misc/BroadcastFilter.java create mode 100644 src/main/java/com/redstoner/misc/CommandHolderType.java create mode 100644 src/main/java/com/redstoner/misc/JsonManager.java create mode 100644 src/main/java/com/redstoner/misc/Main.java create mode 100644 src/main/java/com/redstoner/misc/Utils.java create mode 100644 src/main/java/com/redstoner/misc/VersionHelper.java create mode 100644 src/main/java/com/redstoner/misc/mysql/Config.java create mode 100644 src/main/java/com/redstoner/misc/mysql/JSONManager.java create mode 100644 src/main/java/com/redstoner/misc/mysql/MysqlHandler.java create mode 100644 src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java create mode 100644 src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java create mode 100644 src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java create mode 100644 src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java create mode 100644 src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java create mode 100644 src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java create mode 100644 src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/MysqlType.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/date/Date.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/date/DateTime.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/date/Time.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/date/TimeStamp.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/date/Year.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/BigInt.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/Decimal.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/Double.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/Float.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/Int.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/MediumInt.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/SmallInt.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/number/TinyInt.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/Blob.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/Char.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/Enum.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/LongBlob.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/LongText.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/MediumBlob.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/MediumText.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/Set.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/Text.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/TinyText.java create mode 100644 src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java create mode 100644 src/main/java/com/redstoner/modules/CoreModule.java create mode 100644 src/main/java/com/redstoner/modules/Module.java create mode 100644 src/main/java/com/redstoner/modules/ModuleLogger.java create mode 100644 src/main/resources/plugin.yml diff --git a/plugin.yml b/plugin.yml deleted file mode 100644 index 5a3ff61..0000000 --- a/plugin.yml +++ /dev/null @@ -1,5 +0,0 @@ -name: ModuleLoader -version: 4.0.0 -authors: [pepich1851] -main: com.redstoner.misc.Main -softdepend: [Vault] \ No newline at end of file diff --git a/src/com/redstoner/annotations/AutoRegisterListener.java b/src/com/redstoner/annotations/AutoRegisterListener.java deleted file mode 100644 index fabdb5f..0000000 --- a/src/com/redstoner/annotations/AutoRegisterListener.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.redstoner.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** The auto register annotation, to be put onto Classes that implement listener when you are too lazy to register the events yourself. - * - * @author Pepich */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Version(major = 1, minor = 0, revision = 1, compatible = 1) -public @interface AutoRegisterListener -{} diff --git a/src/com/redstoner/annotations/Commands.java b/src/com/redstoner/annotations/Commands.java deleted file mode 100644 index 537bff0..0000000 --- a/src/com/redstoner/annotations/Commands.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.redstoner.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.redstoner.misc.CommandHolderType; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Commands -{ - CommandHolderType value(); -} diff --git a/src/com/redstoner/annotations/Version.java b/src/com/redstoner/annotations/Version.java deleted file mode 100644 index 52d5145..0000000 --- a/src/com/redstoner/annotations/Version.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.redstoner.annotations; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** The Version annotation, to be applied to all Classes that are part of the project. - * - * @author Pepich */ -@Target(ElementType.TYPE) -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface Version -{ - /** The major indicator of the version. Will be used for compatibility detection. - * - * @return the major version as an int */ - int major(); - - int minor(); - - int revision(); - - /** The compatibility part of the version number. Will be used for compatibility detection.
- * Set to -1 if it is supposed to be always compatible.
- * Defaults to 1. - * - * @return the smallest compatible version as an int. */ - int compatible() default 1; -} diff --git a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd deleted file mode 100644 index eadeeb7..0000000 --- a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd +++ /dev/null @@ -1,34 +0,0 @@ -command modules { - [empty] { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - list { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - -v { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listv; - } - list -v { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listv; - } - load [string:name...] { - help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run load name; - type console; - } - unload [string:name...] { - help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run unload name; - type console; - } -} \ No newline at end of file diff --git a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java deleted file mode 100644 index b4fbbe4..0000000 --- a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ /dev/null @@ -1,736 +0,0 @@ -package com.redstoner.coremods.moduleLoader; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; - -import com.nemez.cmdmgr.Command; -import com.nemez.cmdmgr.Command.AsyncType; -import com.nemez.cmdmgr.CommandManager; -import com.redstoner.annotations.AutoRegisterListener; -import com.redstoner.annotations.Commands; -import com.redstoner.annotations.Version; -import com.redstoner.exceptions.MissingVersionException; -import com.redstoner.misc.Main; -import com.redstoner.misc.VersionHelper; -import com.redstoner.modules.CoreModule; -import com.redstoner.modules.Module; -import com.redstoner.modules.ModuleLogger; - -import net.nemez.chatapi.click.Message; - -/** The module loader, mother of all modules. Responsible for loading and taking care of all modules. - * - * @author Pepich */ -@Version(major = 4, minor = 0, revision = 1, compatible = 4) -public final class ModuleLoader implements CoreModule -{ - private static ModuleLoader instance; - private static final HashMap modules = new HashMap<>(); - private static URL[] urls; - private static URLClassLoader mainLoader; - private static HashMap loaders = new HashMap<>(); - private static File configFile; - private static FileConfiguration config; - private static boolean debugMode = false; - private static HashMap loggers = new HashMap<>(); - - private ModuleLoader() - { - try - { - config = Main.plugin.getConfig(); - configFile = new File(Main.plugin.getDataFolder(), "config.yml"); - urls = new URL[] {(new File(Main.plugin.getDataFolder(), "classes")).toURI().toURL()}; - mainLoader = new URLClassLoader(urls, this.getClass().getClassLoader()); - } - catch (MalformedURLException e) - { - System.out.println("Sumtin is wong with ya filesüstem m8. Fix eeeet or I won't werk!"); - Bukkit.getPluginManager().disablePlugin(Main.plugin); - } - } - - public static void init() - { - if (instance == null) - instance = new ModuleLoader(); - loggers.put(instance, new ModuleLogger("ModuleLoader")); - CommandManager.registerCommand(ModuleLoader.class.getResourceAsStream("ModuleLoader.cmd"), instance, - Main.plugin); - } - - public static final void loadFromConfig() - { - try - { - if (!configFile.exists()) - { - configFile.getParentFile().mkdirs(); - configFile.createNewFile(); - } - config.load(configFile); - } - catch (FileNotFoundException e) - {} - catch (IOException e) - { - e.printStackTrace(); - } - catch (InvalidConfigurationException e) - { - configFile.delete(); - try - { - configFile.createNewFile(); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - instance.getLogger().error("Invalid config file! Creating new, blank file!"); - } - List coremods = config.getStringList("coremods"); - if (coremods == null || coremods.isEmpty()) - { - config.set("coremods", new String[] {"# Add the coremodules here!"}); - Main.plugin.saveConfig(); - try - { - config.save(configFile); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - List autoload = config.getStringList("autoload"); - if (autoload == null || autoload.isEmpty()) - { - config.set("autoload", new String[] {"# Add the modules here!"}); - Main.plugin.saveConfig(); - try - { - config.save(configFile); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - if (!config.contains("debugMode")) - { - config.set("debugMode", false); - try - { - config.save(configFile); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - debugMode = config.getBoolean("debugMode"); - for (String s : coremods) - if (!s.startsWith("#")) - if (!ModuleLoader.addDynamicModule(s)) - { - instance.getLogger().error("Couldn't autocomplete path for module name: " + s - + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); - - } - for (String s : autoload) - if (!s.startsWith("#")) - if (!ModuleLoader.addDynamicModule(s)) - { - instance.getLogger().error("Couldn't autocomplete path for module name: " + s - + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); - - } - updateConfig(); - } - - /** This method enables a specific module. If no module with that name is known to the loader yet it will be added to the list.
- * This method is deprecated, use enableDynamicModule instead. When using this method, dynamic reloading of the module will not be supported. - * - * @param clazz The class of the module to be enabled. - * @return true, when the module was successfully enabled. */ - @Deprecated - public static final boolean enableModule(Class clazz) - { - for (Module module : modules.keySet()) - { - if (module.getClass().equals(clazz)) - { - if (modules.get(module)) - { - instance.getLogger().info("Module was already enabled! Ignoring module.!"); - return true; - } - if (module.onEnable()) - { - if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) - && (module instanceof Listener)) - { - Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); - } - instance.getLogger().info("Enabled module " + module.getClass().getName()); - instance.getLogger().info("Loaded module " + module.getClass().getName()); - modules.put(module, true); - return true; - } - else - { - instance.getLogger().error("Failed to enable module " + module.getClass().getName()); - return false; - } - } - } - try - { - Module m = clazz.newInstance(); - modules.put(m, false); - if (m.onEnable()) - { - if (m.getClass().isAnnotationPresent(AutoRegisterListener.class) && (m instanceof Listener)) - { - Bukkit.getPluginManager().registerEvents((Listener) m, Main.plugin); - } - instance.getLogger().info("Loaded and enabled module " + m.getClass().getName()); - instance.getLogger().info("Loaded module " + m.getClass().getName()); - return true; - } - else - { - instance.getLogger().error("Failed to enable module " + m.getClass().getName()); - return false; - } - } - catch (InstantiationException | IllegalAccessException e) - { - instance.getLogger() - .error("Could not add " + clazz.getName() + " to the list, constructor not accessible."); - return false; - } - } - - private static final void enableLoadedModule(Module module, Version oldVersion) - { - try - { - loggers.put(module, new ModuleLogger(module.getClass().getSimpleName())); - if (module.onEnable()) - { - modules.put(module, true); - if (VersionHelper.getString(oldVersion).equals("0.0.0.0")) - module.firstLoad(); - else if (!VersionHelper.getVersion(module.getClass()).equals(VersionHelper.getString(oldVersion))) - module.migrate(oldVersion); - if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 3), module.getClass())) - module.postEnable(); - if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 4), module.getClass())) - { - Commands ann = module.getClass().getAnnotation(Commands.class); - if (ann != null) - { - switch (ann.value()) - { - case File: - File f = new File("plugins/ModuleLoader/classes/" - + module.getClass().getName().replace(".", "/") + ".cmd"); - CommandManager.registerCommand(f, module, Main.plugin); - break; - case Stream: - InputStream stream = module.getClass() - .getResourceAsStream(module.getClass().getSimpleName() + ".cmd"); - CommandManager.registerCommand(stream, module, Main.plugin); - case String: - CommandManager.registerCommand(module.getCommandString(), module, Main.plugin); - break; - case None: - break; - } - } - } - instance.getLogger().info("Loaded module " + module.getClass().getName()); - if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) && (module instanceof Listener)) - Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); - } - else - instance.getLogger().error("Failed to load module " + module.getClass().getName()); - } - catch (Exception e) - { - instance.getLogger().error("Failed to load module " + module.getClass().getName()); - e.printStackTrace(); - } - } - - /** This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. - * - * @param sender The person to send the info to, usually the issuer of the command or the console sender. - * @return true. */ - @Command(hook = "list", async = AsyncType.ALWAYS) - public boolean listModulesCommand(CommandSender sender) - { - Message m = new Message(sender, null); - m.appendText(getLogger().getHeader()); - m.appendText("§2Modules:\n&e"); - Module[] modules = ModuleLoader.modules.keySet().toArray(new Module[] {}); - for (int i = 0; i < modules.length; i++) - { - Module module = modules[i]; - String[] classPath = module.getClass().getName().split("\\."); - String classname = classPath[classPath.length - 1]; - m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname); - if (i + 1 < modules.length) - m.appendText("§7, "); - } - m.send(); - return true; - } - - /** This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. - * - * @param sender The person to send the info to, usually the issuer of the command or the console sender. - * @return true. */ - @Command(hook = "listv", async = AsyncType.ALWAYS) - public boolean listModulesCommandVersion(CommandSender sender) - { - Message m = new Message(sender, null); - m.appendText(getLogger().getHeader()); - m.appendText("§2Modules:\n&e"); - Module[] modules = ModuleLoader.modules.keySet().toArray(new Module[] {}); - for (int i = 0; i < modules.length; i++) - { - Module module = modules[i]; - String[] classPath = module.getClass().getName().split("\\."); - String classname = classPath[classPath.length - 1]; - try - { - m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname + "§e(" - + VersionHelper.getVersion(module.getClass()) + ")"); - } - catch (MissingVersionException e) - { - m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname + "§c" + "(Unknown Version)"); - } - if (i + 1 < modules.length) - m.appendText("§7, "); - } - m.send(); - return true; - } - - public static void disableModules() - { - for (Module module : modules.keySet()) - { - disableModule(module); - } - } - - public static void disableModule(Module module) - { - if (modules.get(module)) - { - module.onDisable(); - if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) && (module instanceof Listener)) - { - HandlerList.unregisterAll((Listener) module); - } - String[] commands = getAllHooks(module).toArray(new String[] {}); - CommandManager.unregisterAll(commands); - try - { - URLClassLoader loader = loaders.get(module); - if (loader != null) - loader.close(); - } - catch (IOException e) - {} - finally - { - loaders.remove(module); - } - } - } - - private static ArrayList getAllHooks(Module module) - { - ArrayList commands = new ArrayList<>(); - for (Method m : module.getClass().getMethods()) - { - Command cmd = m.getDeclaredAnnotation(Command.class); - if (cmd == null) - continue; - commands.add(cmd.hook()); - } - return commands; - } - - @Command(hook = "load") - public boolean loadModule(CommandSender sender, String name) - { - if (!addDynamicModule(name)) - { - instance.getLogger().message(sender, true, "Couldn't autocomplete path for module name: " + name - + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); - - } - updateConfig(); - return true; - } - - @Command(hook = "unload") - public boolean unloadModule(CommandSender sender, String name) - { - if (!removeDynamicModule(name)) - instance.getLogger().error("Couldn't find module! Couldn't disable nonexisting module!"); - return true; - } - - public static final boolean addDynamicModule(String raw_name) - { - String[] raw = raw_name.split(" "); - String name = raw[0]; - Version oldVersion; - if (raw.length > 1) - oldVersion = VersionHelper.getVersion(raw[1]); - else - oldVersion = VersionHelper.create(0, 0, 0, 0); - for (Module m : modules.keySet()) - { - if (m.getClass().getName().equals(name)) - { - instance.getLogger().info( - "Found existing module, attempting override. WARNING! This operation will halt the main thread until it is completed."); - instance.getLogger() - .info("Attempting to load new class definition before disabling and removing the old module"); - boolean differs = false; - instance.getLogger().info("Old class definition: Class@" + m.getClass().hashCode()); - ClassLoader delegateParent = mainLoader.getParent(); - Class newClass = null; - URLClassLoader cl = new URLClassLoader(urls, delegateParent); - try - { - newClass = cl.loadClass(m.getClass().getName()); - instance.getLogger().info("Found new class definition: Class@" + newClass.hashCode()); - differs = m.getClass() != newClass; - } - catch (ClassNotFoundException e) - { - instance.getLogger().error("Could not find a class definition, aborting now!"); - e.printStackTrace(); - try - { - cl.close(); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - return false; - } - if (!differs) - { - if (!debugMode) - { - instance.getLogger().warn( - "New class definition equals old definition, are you sure you did everything right?"); - instance.getLogger().info("Aborting now..."); - try - { - cl.close(); - } - catch (IOException e) - { - e.printStackTrace(); - } - return false; - } - else - instance.getLogger().warn( - "New class definition equals old definition, but debugMode is enabled. Loading anyways."); - } - else - instance.getLogger().info("Found new class definition, attempting to instantiate:"); - Module module = null; - try - { - module = (Module) newClass.newInstance(); - } - catch (InstantiationException | IllegalAccessException e) - { - instance.getLogger().error("Could not instantiate the module, aborting!"); - e.printStackTrace(); - try - { - cl.close(); - } - catch (IOException e1) - { - e1.printStackTrace(); - } - return false; - } - instance.getLogger().info("Instantiated new class definition, checking versions"); - oldVersion = m.getClass().getAnnotation(Version.class); - instance.getLogger().info("Current version: " + VersionHelper.getString(oldVersion)); - Version newVersion = module.getClass().getAnnotation(Version.class); - instance.getLogger().info("Version of remote class: " + VersionHelper.getString(newVersion)); - if (oldVersion.equals(newVersion)) - { - if (!debugMode) - { - instance.getLogger().error("Detected equal module versions, " + (debugMode - ? " aborting now... Set debugMode to true in your config if you want to continue!" - : " continueing anyways.")); - if (!debugMode) - { - try - { - cl.close(); - } - catch (IOException e) - { - e.printStackTrace(); - } - return false; - } - } - else - instance.getLogger() - .warn("New version equals old version, but debugMode is enabled. Loading anyways."); - } - else - instance.getLogger().info("Versions differ, disabling old module"); - disableModule(m); - instance.getLogger().info("Disabled module, overriding the implementation"); - modules.remove(m); - try - { - if (loaders.containsKey(m)) - loaders.remove(m).close(); - } - catch (IOException e) - { - e.printStackTrace(); - } - modules.put(module, false); - loaders.put(module, cl); - instance.getLogger().info("Successfully updated class definition. Enabling new implementation:"); - enableLoadedModule(module, oldVersion); - return true; - } - } - ClassLoader delegateParent = mainLoader.getParent(); - URLClassLoader cl = new URLClassLoader(urls, delegateParent); - try - { - Class clazz = cl.loadClass(name); - Module module = (Module) clazz.newInstance(); - modules.put(module, false); - loaders.put(module, cl); - enableLoadedModule(module, oldVersion); - return true; - } - catch (NoClassDefFoundError | ClassNotFoundException | InstantiationException | IllegalAccessException e) - { - try - { - cl.close(); - } - catch (IOException e1) - {} - if (e instanceof NoClassDefFoundError) - { - NoClassDefFoundError exception = (NoClassDefFoundError) e; - String[] exMessage = exception.getMessage().split(" "); - String moduleName = exMessage[exMessage.length - 1] - .substring(0, exMessage[exMessage.length - 1].length() - - (exMessage[exMessage.length - 1].endsWith(")") ? 1 : 0)) - .replace("/", "."); - if (!moduleName.equalsIgnoreCase(name)) - { - instance.getLogger() - .error("Class &e" + moduleName + "&r couldn't be found! Suspecting a missing dependency!"); - return false; - } - else - instance.getLogger().warn( - "Couldn't find class definition, attempting to get proper classname from thrown Exception."); - if (addDynamicModule(moduleName)) - return true; - } - if (name.endsWith(".class")) - { - instance.getLogger().warn( - "Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix."); - if (addDynamicModule(name.replaceAll(".class$", ""))) - return true; - } - if (!name.contains(".")) - { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a package name and trying again."); - if (addDynamicModule(name.toLowerCase() + "." + name)) - return true; - } - if (!name.startsWith("com.redstoner.modules.") && name.contains(".")) - { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of package name and trying again."); - if (addDynamicModule("com.redstoner.modules." + name)) - return true; - } - } - return false; - } - - public static final boolean removeDynamicModule(String name) - { - for (Module m : modules.keySet()) - { - if (m.getClass().getName().equals(name)) - { - instance.getLogger().info( - "Found existing module, attempting unload. WARNING! This operation will halt the main thread until it is completed."); - instance.getLogger().info("Attempting to disable module properly:"); - disableModule(m); - modules.remove(m); - instance.getLogger().info("Disabled module."); - return true; - } - } - if (!name.startsWith("com.redstoner.modules.")) - { - if (name.endsWith(".class")) - { - instance.getLogger().warn( - "Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix."); - if (removeDynamicModule(name.replaceAll(".class$", ""))) - return true; - } - if (!name.contains(".")) - { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a package name and trying again."); - if (removeDynamicModule(name.toLowerCase() + "." + name)) - return true; - } - if (!name.startsWith("com.redstoner.modules.")) - { - instance.getLogger().warn( - "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of package name and trying again."); - if (removeDynamicModule("com.redstoner.modules." + name)) - return true; - } - } - return false; - } - - /** Finds a module by name for other modules to reference it. - * - * @param name the name of the module. Use the full path if you are not sure about the module's SimpleClassName being unique. - * @return the instance of the module or @null it none could be found */ - public static Module getModule(String name) - { - for (Module m : modules.keySet()) - if (m.getClass().getSimpleName().equalsIgnoreCase(name) || m.getClass().getName().equalsIgnoreCase(name)) - return m; - return null; - } - - /** Finds a module by name for other modules to reference it. - * - * @param name the name of the module. Use the full path if you are not sure about the module's SimpleClassName being unique. - * @return the instance of the module or @null it none could be found */ - public static boolean exists(String name) - { - for (Module m : modules.keySet()) - if (m.getClass().getSimpleName().equals(name) || m.getClass().getName().equals(name)) - return true; - return false; - } - - public static ModuleLogger getModuleLogger(Module module) - { - return loggers.get(module); - } - - public static void updateConfig() - { - List coremods = config.getStringList("coremods"); - ArrayList new_coremods = new ArrayList<>(); - List autoload = config.getStringList("autoload"); - ArrayList new_autoload = new ArrayList<>(); - - for (String s : coremods) - { - if (s.startsWith("#")) - { - new_coremods.add(s); - } - else - { - s = s.split(" ")[0]; - try - { - new_coremods.add(getModule(s).getClass().getName() + " " - + VersionHelper.getVersion(getModule(s).getClass())); - } - catch (Exception e) - { - new_coremods.add(s + " " + VersionHelper.getString(VersionHelper.create(0, 0, 0, 0))); - } - } - } - for (String s : autoload) - { - if (s.startsWith("#")) - { - new_autoload.add(s); - } - else - { - s = s.split(" ")[0]; - try - { - new_autoload.add(getModule(s).getClass().getName() + " " - + VersionHelper.getVersion(getModule(s).getClass())); - } - catch (Exception e) - { - new_autoload.add(s + " " + VersionHelper.getString(VersionHelper.create(0, 0, 0, 0))); - } - } - } - - config.set("coremods", new_coremods); - config.set("autoload", new_autoload); - try - { - config.save(configFile); - } - catch (IOException e) - { - e.printStackTrace(); - } - } -} diff --git a/src/com/redstoner/exceptions/MissingVersionException.java b/src/com/redstoner/exceptions/MissingVersionException.java deleted file mode 100644 index 62032b6..0000000 --- a/src/com/redstoner/exceptions/MissingVersionException.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.redstoner.exceptions; - -import com.redstoner.annotations.Version; - -/** To be thrown when a module is not annotated with its version. If this gets thrown, then oh boy, you're in trouble now. - * - * @author Pepich */ -@Version(major = 1, minor = 0, revision = 0, compatible = -1) -public class MissingVersionException extends Exception -{ - private static final long serialVersionUID = 4940161335512222539L; - - public MissingVersionException() - { - super(); - } - - public MissingVersionException(String message) - { - super(message); - } -} diff --git a/src/com/redstoner/exceptions/NonSaveableConfigException.java b/src/com/redstoner/exceptions/NonSaveableConfigException.java deleted file mode 100644 index df33bff..0000000 --- a/src/com/redstoner/exceptions/NonSaveableConfigException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.redstoner.exceptions; - -public class NonSaveableConfigException extends Exception { - private static final long serialVersionUID = -7271481973389455510L; - - public NonSaveableConfigException() { - super("This config does not support saving!"); - } -} diff --git a/src/com/redstoner/misc/BroadcastFilter.java b/src/com/redstoner/misc/BroadcastFilter.java deleted file mode 100644 index 1f0ce04..0000000 --- a/src/com/redstoner/misc/BroadcastFilter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.redstoner.misc; - -import org.bukkit.command.CommandSender; - -import com.redstoner.annotations.Version; - -/** Classes implementing this interface can be used to define a filter for the Utils.broadcast method for sending a message to more than one, but less than all users. - * - * @author Pepich */ -@Version(major = 1, minor = 0, revision = 0, compatible = 1) -public interface BroadcastFilter -{ - public boolean sendTo(CommandSender recipient); -} diff --git a/src/com/redstoner/misc/CommandHolderType.java b/src/com/redstoner/misc/CommandHolderType.java deleted file mode 100644 index 7c4383e..0000000 --- a/src/com/redstoner/misc/CommandHolderType.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.redstoner.misc; - -import com.redstoner.annotations.Version; - -/** @author Pepich */ -@Version(major = 4, minor = 0, revision = 0, compatible = -1) -public enum CommandHolderType -{ - Stream, - File, - String, - None -} diff --git a/src/com/redstoner/misc/JsonManager.java b/src/com/redstoner/misc/JsonManager.java deleted file mode 100644 index 13b51b6..0000000 --- a/src/com/redstoner/misc/JsonManager.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.redstoner.misc; - -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import com.redstoner.annotations.Version; - -/** This class provides simple JSON handling, like storing and loading from and to files. - * - * @author Pepich */ -@Version(major = 1, minor = 0, revision = 2, compatible = -1) -public class JsonManager -{ - private JsonManager() - {} - - /** Loads a JSONObject from a file. - * - * @param source the file to load from. - * @return the JSONObject or null if the source does not contain a valid JSONObject. */ - public static JSONObject getObject(File source) - { - if (!source.exists()) - return null; - JSONParser parser = new JSONParser(); - try - { - FileReader reader = new FileReader(source); - Object rawObject = parser.parse(reader); - reader.close(); - JSONObject jsonObject = (JSONObject) rawObject; - return jsonObject; - } - catch (IOException | ParseException e) - {} - return null; - } - - /** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on a different thread and you do not need to take care of that yourself. - * - * @param object the JSONObject to save. - * @param destination the file to write to. */ - public static void save(JSONObject object, File destination) - { - Thread t = new Thread(new Runnable() - { - @Override - public void run() - { - saveSync(object, destination); - } - }); - t.start(); - } - - /** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on the same thread that you are calling it from! - * - * @param object the JSONObject to save. - * @param destination the file to write to. */ - public static void saveSync(JSONObject object, File destination) - { - if (destination.exists()) - destination.delete(); - else if (!destination.getParentFile().exists()) - destination.getParentFile().mkdirs(); - try - { - destination.createNewFile(); - FileWriter writer = new FileWriter(destination); - String json_string = object.toJSONString(); - writer.write(json_string); - writer.flush(); - writer.close(); - } - catch (IOException e) - {} - } - - /** Loads a JSONArray from a file. - * - * @param source the file to load from. - * @return the JSONArray or null if the source does not contain a valid JSONArray. */ - public static JSONArray getArray(File source) - { - if (!source.exists()) - return null; - JSONParser parser = new JSONParser(); - try - { - Object rawObject = parser.parse(new FileReader(source)); - JSONArray jsonArray = (JSONArray) rawObject; - return jsonArray; - } - catch (IOException | ParseException e) - {} - return null; - } - - /** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on a different thread and you do not need to take care of that yourself. - * - * @param object the JSONArray to save. - * @param destination the file to write to. */ - public static void save(JSONArray array, File destination) - { - Thread t = new Thread(new Runnable() - { - @Override - public void run() - { - saveSync(array, destination); - } - }); - t.start(); - } - - /** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
- * Note that this operation will be run on the same thread that you are calling it from! - * - * @param object the JSONArray to save. - * @param destination the file to write to. */ - public static void saveSync(JSONArray array, File destination) - { - if (destination.exists()) - destination.delete(); - else if (!destination.getParentFile().exists()) - destination.getParentFile().mkdirs(); - try - { - destination.createNewFile(); - FileWriter writer = new FileWriter(destination); - String json_string = array.toJSONString(); - writer.write(json_string); - writer.flush(); - writer.close(); - } - catch (IOException e) - {} - } -} diff --git a/src/com/redstoner/misc/Main.java b/src/com/redstoner/misc/Main.java deleted file mode 100644 index b24e532..0000000 --- a/src/com/redstoner/misc/Main.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.redstoner.misc; - -import org.bukkit.plugin.java.JavaPlugin; - -import com.redstoner.annotations.Version; -import com.redstoner.coremods.moduleLoader.ModuleLoader; -import com.redstoner.misc.mysql.MysqlHandler; - -import net.nemez.chatapi.ChatAPI; - -/** Main class. Duh. - * - * @author Pepich */ -@Version(major = 4, minor = 0, revision = 0, compatible = -1) -public class Main extends JavaPlugin -{ - public static JavaPlugin plugin; - - @Override - public void onEnable() - { - plugin = this; - ChatAPI.initialize(this); - // Configger.init(); - MysqlHandler.init(); - ModuleLoader.init(); - // Load modules from config - ModuleLoader.loadFromConfig(); - } - - @Override - public void onDisable() - { - ModuleLoader.disableModules(); - } -} diff --git a/src/com/redstoner/misc/Utils.java b/src/com/redstoner/misc/Utils.java deleted file mode 100644 index 8186bcb..0000000 --- a/src/com/redstoner/misc/Utils.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.redstoner.misc; - -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.regex.Pattern; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import com.redstoner.annotations.Version; - -/** The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more. - * - * @author Pepich */ -@Version(major = 4, minor = 0, revision = 2, compatible = 1) -public final class Utils -{ - /** The @SimpleDateFormat used for getting the current date. */ - public static SimpleDateFormat dateFormat = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]"); - - /** The Pattern for a UUID*/ - private static final Pattern UUID_pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"); - private static final Pattern Class_pattern = Pattern.compile(".*\\."); - private static final Pattern NoDolarSign_pattern = Pattern.compile("\\$\\d*"); - - /** Hidden constructor. Do not instantiate UTILS classes! :) */ - private Utils() - {} - - /** This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
- * If you want to, you can set a message that will be logged to console. Set to null to not log anything.
- * You can still allow console in the filter to log the original message. - * - * @param prefix The prefix for the message. Set to NULL to let it auto generate. - * @param message the message to be sent around - * @param filter the BroadcastFilter to be applied.
- * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. - * @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter). - * @return the amount of people that received the message. */ - public static int broadcast(String prefix, String message, BroadcastFilter filter) - { - if (prefix == null) - prefix = "§8[§2" + getCaller() + "§8]: "; - if (filter == null) - { - for (Player p : Bukkit.getOnlinePlayers()) - p.sendMessage(prefix + message); - Bukkit.getConsoleSender().sendMessage(prefix + message); - return Bukkit.getOnlinePlayers().size() + 1; - } - else - { - int count = 0; - for (Player p : Bukkit.getOnlinePlayers()) - if (filter.sendTo(p)) - { - p.sendMessage(prefix + message); - count++; - } - if (filter.sendTo(Bukkit.getConsoleSender())) - { - Bukkit.getConsoleSender().sendMessage(prefix + message); - count++; - } - return count; - } - } - - /** This method will find the next parent caller and return their class name, omitting package names. - * - * @return the Name of the calling class. */ - private static final String getCaller() - { - StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); - String classname = "Utils"; - for (int i = 0; classname.equals("Utils"); i++) - { - classname = Class_pattern.matcher(stackTrace[i].getClassName()).replaceAll(""); - } - return classname; - } - - /** This method will find the next parent caller and return their class name, omitting package names. - * - * @param directCaller used to prevent this method from returning the caller itself. Null if supposed to be ignored. - * @return the name of the calling class. */ - public static final String getCaller(String... directCaller) - { - if (directCaller == null || directCaller.length == 0) - return getCaller(); - StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); - String classname = "Utils"; - List callers = Arrays.asList(directCaller); - for (int i = 0; callers.contains(classname) || classname.equals("Utils"); i++) - { - classname = Class_pattern.matcher(stackTrace[i].getClassName()).replaceAll(""); - } - classname = NoDolarSign_pattern.matcher(classname).replaceAll(""); - return classname; - } - - /** Provides a uniform way of getting the date for all modules. - * - * @return The current date in the format "[dd-mm-yyyy hh:mm:ss]" */ - public static String getDate() - { - Date date = new Date(System.currentTimeMillis()); - return dateFormat.format(date); - } - - /** Provides a uniform way of getting the (display)name of a @CommandSender. - * - * @param sender The @CommandSender to get the name of. - * @return The DisplayName of the @CommandSender or if not a @Player, the name in blue. */ - public static String getName(CommandSender sender) - { - if (sender instanceof Player) - return ((Player) sender).getDisplayName(); - else - return "§9" + sender.getName(); - } - - /** Provides a uniform way of getting the UUID of a @CommandSender. - * - * @param sender The @CommandSender to get the UUID of. - * @return The UUID of the @CommandSender or if not a player, "CONSOLE" in blue. */ - public static String getID(CommandSender sender) - { - String id; - if (sender instanceof Player) - id = ((Player) sender).getUniqueId().toString(); - else - id = "CONSOLE"; - return id; - } - - /** Checks if the string is a UUID. - * - * @param toCheck String to check. - * @return if the string is a UUID. - */ - public static boolean isUUID(String toCheck) - { - return UUID_pattern.matcher(toCheck).matches(); - } -} diff --git a/src/com/redstoner/misc/VersionHelper.java b/src/com/redstoner/misc/VersionHelper.java deleted file mode 100644 index e4a9403..0000000 --- a/src/com/redstoner/misc/VersionHelper.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.redstoner.misc; - -import java.lang.annotation.Annotation; - -import com.redstoner.annotations.Version; -import com.redstoner.exceptions.MissingVersionException; - -/** This class can be used to compare modules against the loader version or against each other to prevent dependency issues. - * - * @author Pepich */ -@Version(major = 2, minor = 1, revision = 3, compatible = 0) -public final class VersionHelper -{ - private VersionHelper() - {} - - /** Checks two classes versions for compatibility. - * - * @param base The API to compare to. - * @param module The module to compare. - * @return true, when the module is up to date with the API, or the API supports outdated modules. - * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ - public static boolean isCompatible(Class api, Class module) throws MissingVersionException - { - if (!api.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The API is not annotated with a version."); - if (!module.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The module is not annotated with a version."); - Version apiVersion = api.getAnnotation(Version.class); - Version moduleVersion = module.getAnnotation(Version.class); - return isCompatible(apiVersion, moduleVersion); - } - - /** Checks two classes versions for compatibility. - * - * @param base The API to compare to. - * @param module The module to compare. - * @return true, when the module is up to date with the API, or the API supports outdated modules. - * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ - public static boolean isCompatible(Version apiVersion, Class module) throws MissingVersionException - { - if (!module.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The module is not annotated with a version."); - Version moduleVersion = module.getAnnotation(Version.class); - return isCompatible(apiVersion, moduleVersion); - } - - /** Checks two classes versions for compatibility. - * - * @param base The API to compare to. - * @param module The module to compare. - * @return true, when the module is up to date with the API, or the API supports outdated modules. - * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ - public static boolean isCompatible(Class api, Version moduleVersion) throws MissingVersionException - { - if (!api.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The API is not annotated with a version."); - Version apiVersion = api.getAnnotation(Version.class); - return isCompatible(apiVersion, moduleVersion); - } - - /** Checks two versions for compatibility. - * - * @param base The API version to compare to. - * @param module The module version to compare. - * @return true, when the module is up to date with the API, or the API supports outdated modules. */ - public static boolean isCompatible(Version apiVersion, Version moduleVersion) - { - if (apiVersion.major() >= moduleVersion.compatible()) - return true; - if (apiVersion.compatible() == -1) - return false; - if (apiVersion.compatible() <= moduleVersion.major()) - return true; - return false; - } - - /** Returns the version of a given class as a String. - * - * @param clazz The class to grab the version number from. - * @return The version number of the class in format major.minor.revision.compatible. - * @throws MissingVersionException If the class is not annotated with @Version. */ - public static String getVersion(Class clazz) throws MissingVersionException - { - if (!clazz.isAnnotationPresent(Version.class)) - throw new MissingVersionException("The given class is not associated with a version."); - Version ver = clazz.getAnnotation(Version.class); - return getString(ver); - } - - /** Returns the String representation of a version. - * - * @param ver The version to be represented. - * @return The String representation. */ - public static String getString(Version ver) - { - return ver.major() + "." + ver.minor() + "." + ver.revision() + "." + ver.compatible(); - } - - public static Version getVersion(String ver) - { - String[] raw = ver.split("\\."); - if (raw.length != 4) - return null; - return VersionHelper.create(Integer.parseInt(raw[0]), Integer.parseInt(raw[1]), Integer.parseInt(raw[2]), - Integer.parseInt(raw[3])); - } - - /** This method creates a new Version to use for compatibility checks. - * - * @param major The major version - * @param minor The minor version - * @param revision The revision - * @param compatible The compatibility tag - * @return */ - public static Version create(int major, int minor, int revision, int compatible) - { - return new Version() - { - @Override - public Class annotationType() - { - return Version.class; - } - - @Override - public int revision() - { - return revision; - } - - @Override - public int minor() - { - return minor; - } - - @Override - public int major() - { - return major; - } - - @Override - public int compatible() - { - return compatible; - } - }; - } -} diff --git a/src/com/redstoner/misc/mysql/Config.java b/src/com/redstoner/misc/mysql/Config.java deleted file mode 100644 index d403c7b..0000000 --- a/src/com/redstoner/misc/mysql/Config.java +++ /dev/null @@ -1,278 +0,0 @@ -package com.redstoner.misc.mysql; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import com.redstoner.exceptions.NonSaveableConfigException; -import com.redstoner.misc.Main; - -public class Config -{ - private File file; - private JSONObject config; - private JSONParser parser; - - public Config() - { - file = null; - parser = new JSONParser(); - config = new JSONObject(); - } - - public Config(JSONObject config) - { - this.file = null; - this.parser = new JSONParser(); - this.config = config; - } - - private Config(File file) throws IOException, ParseException - { - this.file = file; - parser = new JSONParser(); - if (file.exists()) - { - config = loadConfig(file); - } - else - { - config = new JSONObject(); - } - } - - public static final Config getConfig(String fileName) throws IOException, ParseException - { - return new Config(new File(Main.plugin.getDataFolder(), fileName)); - } - - public static final Config getConfig(File file) throws IOException, ParseException - { - return new Config(file); - } - - private JSONObject loadConfig(File file) throws IOException, ParseException - { - FileReader reader = new FileReader(file); - return (JSONObject) parser.parse(reader); - } - - @Override - public String toString() - { - return config.toJSONString(); - } - - public JSONObject asObject() - { - return config; - } - - public void save() throws IOException, NonSaveableConfigException - { - if (file == null) - { - throw new NonSaveableConfigException(); - } - PrintWriter writer = new PrintWriter(file); - writer.write(config.toJSONString()); - writer.close(); - } - - public void refresh() throws IOException, ParseException, NonSaveableConfigException - { - if (file == null) - { - throw new NonSaveableConfigException(); - } - loadConfig(file); - } - - public void setFile(String fileName) - { - file = new File(Main.plugin.getDataFolder(), fileName); - } - - public void setFile(File file) - { - this.file = file; - } - - @SuppressWarnings("unchecked") - public void put(String key, String value) - { - config.put(key, value); - } - - @SuppressWarnings("unchecked") - public void put(String key, List value) - { - JSONArray array = new JSONArray(); - for (String entry : value) - { - array.add(entry); - } - config.put(key, array); - } - - @SuppressWarnings("unchecked") - public void putArray(String key, JSONArray value) - { - config.put(key, value); - } - - @SuppressWarnings("unchecked") - public void put(String key, Map value) - { - JSONObject object = new JSONObject(); - for (String valKey : value.keySet()) - { - String valVal = value.get(valKey); - object.put(valKey, valVal); - } - config.put(key, object); - } - - @SuppressWarnings("unchecked") - public void put(String key, JSONObject value) - { - config.put(key, value); - } - - @SuppressWarnings("unchecked") - public void putAll(Map entry) - { - for (String key : entry.keySet()) - { - String value = entry.get(key); - config.put(key, value); - } - } - - public boolean containsKey(String key) - { - return config.containsKey(key); - } - - public String get(String key) - { - if (containsKey(key)) - { - Object value = config.get(key); - if (value instanceof String) - { - return (String) value; - } - } - return null; - } - - public String getOrDefault(String key, String defaultValue) - { - if (containsKey(key)) - { - Object value = config.get(key); - if (value instanceof String) - { - return (String) value; - } - return null; - } - else - { - return defaultValue; - } - } - - @SuppressWarnings("unchecked") - public List getList(String key) - { - if (containsKey(key)) - { - Object value = config.get(key); - if (value instanceof JSONArray) - { - JSONArray array = (JSONArray) value; - List output = new ArrayList(); - for (String entry : (String[]) array.toArray(new String[0])) - { - output.add(entry); - } - return output; - } - } - return null; - } - - public JSONArray getArray(String key) - { - if (containsKey(key)) - { - Object value = config.get(key); - if (value instanceof JSONArray) - { - JSONArray array = (JSONArray) value; - return array; - } - } - return null; - } - - public Map getMap(String key) - { - if (containsKey(key)) - { - Object value = config.get(key); - if (value instanceof JSONObject) - { - JSONObject object = (JSONObject) value; - @SuppressWarnings("unchecked") - Set> entrySet = object.entrySet(); - Map output = new HashMap(); - for (Map.Entry entry : entrySet) - { - output.put(entry.getKey(), entry.getValue()); - } - return output; - } - } - return null; - } - - public JSONObject getObject(String key) - { - if (containsKey(key)) - { - Object value = config.get(key); - if (value instanceof JSONObject) - { - JSONObject object = (JSONObject) value; - return object; - } - } - return null; - } - - public void remove(String key) - { - config.remove(key); - } - - @SuppressWarnings("unchecked") - public Set> getAll() - { - return config.entrySet(); - } -} diff --git a/src/com/redstoner/misc/mysql/JSONManager.java b/src/com/redstoner/misc/mysql/JSONManager.java deleted file mode 100644 index ae248d5..0000000 --- a/src/com/redstoner/misc/mysql/JSONManager.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.redstoner.misc.mysql; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; - -import com.redstoner.misc.Main; - -public class JSONManager -{ - public static Map getConfiguration(String fileName) - { - File file = new File(Main.plugin.getDataFolder(), fileName); - if (!file.exists()) - { - try - { - PrintWriter writer = new PrintWriter(file.getAbsolutePath(), "UTF-8"); - writer.println("{}"); - writer.close(); - } - catch (FileNotFoundException | UnsupportedEncodingException e) - { - e.printStackTrace(); - } - } - try - { - return loadMap(file); - } - catch (IOException | ParseException e) - { - e.printStackTrace(); - return null; - } - } - - public static void saveConfiguration(Map config, String fileName) - { - try - { - saveMap(new File(Main.plugin.getDataFolder(), fileName), config); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - - @SuppressWarnings("unchecked") - public static void saveList(File file, List entries) throws IOException - { - JSONArray array = new JSONArray(); - array.addAll(entries); - FileWriter writer = new FileWriter(file); - writer.write(array.toJSONString()); - writer.close(); - } - - public static List loadList(File file) throws IOException, ParseException - { - FileReader read = new FileReader(file); - List entries = new ArrayList<>(); - JSONArray array = (JSONArray) new JSONParser().parse(read); - for (Object o : array) - { - entries.add((Serializable) o); - } - return entries; - } - - @SuppressWarnings("unchecked") - public static void saveMap(File file, Map entries) throws IOException - { - JSONObject map = new JSONObject(); - map.putAll(entries); - FileWriter writer = new FileWriter(file); - writer.write(map.toJSONString()); - writer.close(); - } - - public static Map loadMap(File file) throws IOException, ParseException - { - FileReader reader = new FileReader(file); - JSONObject map = (JSONObject) new JSONParser().parse(reader); - Map entries = new HashMap<>(); - for (Object o : map.keySet()) - { - entries.put((Serializable) o, (Serializable) map.get(o)); - } - return entries; - } -} diff --git a/src/com/redstoner/misc/mysql/MysqlHandler.java b/src/com/redstoner/misc/mysql/MysqlHandler.java deleted file mode 100644 index 909d276..0000000 --- a/src/com/redstoner/misc/mysql/MysqlHandler.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.redstoner.misc.mysql; - -import java.io.File; -import java.io.IOException; -import java.io.Serializable; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.json.simple.parser.ParseException; - -import com.redstoner.misc.Main; -import com.redstoner.misc.mysql.elements.MysqlDatabase; - -public class MysqlHandler -{ - public static MysqlHandler INSTANCE; - private String url, username, password; - - public MysqlHandler(String hostname, int port, String username, String password) - { - this.url = "jdbc:mysql://" + hostname + ":" + port + "/"; - this.username = username; - this.password = password; - } - - public static void init() - { - Map mysqlCredentials = new HashMap<>(); - File mysqlCredentialsFile = new File(Main.plugin.getDataFolder(), "mysqlCredentials.json"); - if (mysqlCredentialsFile.exists()) - { - try - { - mysqlCredentials = JSONManager.loadMap(mysqlCredentialsFile); - } - catch (IOException | ParseException e) - { - e.printStackTrace(); - } - } - else - { - Bukkit.getConsoleSender().sendMessage( - ChatColor.RED + "MySQL config does not exist, creating an example one, things might (will) break!"); - mysqlCredentials.put("hostname", "localhost"); - mysqlCredentials.put("port", "3306"); - mysqlCredentials.put("username", "your username here"); - mysqlCredentials.put("password", "your password here"); - try - { - JSONManager.saveMap(mysqlCredentialsFile, mysqlCredentials); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - String hostname = (String) mysqlCredentials.get("hostname"); - int port = Integer.valueOf((String) mysqlCredentials.get("port")); - String username = (String) mysqlCredentials.get("username"); - String password = (String) mysqlCredentials.get("password"); - INSTANCE = new MysqlHandler(hostname, port, username, password); - } - - private Connection getConnection(String databaseName) throws IllegalStateException - { - Connection connection = null; - try - { - connection = DriverManager.getConnection(url + databaseName, username, password); - } - catch (SQLException e) - { - throw new IllegalStateException("Cannot connect to the database!", e); - } - return connection; - } - - public MysqlDatabase getDatabase(String databaseName) - { - return new MysqlDatabase(getConnection(databaseName)); - } - - public List getDatabases() - { - try - { - List databases = new ArrayList<>(); - Connection connection = DriverManager.getConnection(url.substring(0, url.length()), username, password); - DatabaseMetaData metadata = connection.getMetaData(); - ResultSet queryResults = metadata.getCatalogs(); - while (queryResults.next()) - { - String databaseName = queryResults.getString("TABLE_CAT"); - databases.add(new MysqlDatabase(getConnection(databaseName))); - } - connection.close(); - return databases; - } - catch (SQLException e) - { - e.printStackTrace(); - return null; - } - } -} diff --git a/src/com/redstoner/misc/mysql/MysqlQueryHandler.java b/src/com/redstoner/misc/mysql/MysqlQueryHandler.java deleted file mode 100644 index f89a08a..0000000 --- a/src/com/redstoner/misc/mysql/MysqlQueryHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.redstoner.misc.mysql; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -public class MysqlQueryHandler { - public static ResultSet queryResult(Connection connection, String query) { - try { - Statement statement = connection.createStatement(); - ResultSet results = statement.executeQuery(query); - - return results; - } catch (SQLException e) { - e.printStackTrace(); - return null; - } - } - - public static boolean queryNoResult(Connection connection, String query) { - try { - CallableStatement statement = connection.prepareCall(query); - statement.execute(); - - return true; - } catch (SQLException e) { - e.printStackTrace(); - return false; - } - } -} diff --git a/src/com/redstoner/misc/mysql/elements/ConstraintOperator.java b/src/com/redstoner/misc/mysql/elements/ConstraintOperator.java deleted file mode 100644 index 45cb33c..0000000 --- a/src/com/redstoner/misc/mysql/elements/ConstraintOperator.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.redstoner.misc.mysql.elements; - -public enum ConstraintOperator { - LESS_THAN, GREATER_THAN, EQUAL, NOT_EQUAL, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL; - - public String toString() { - switch (this) { - case LESS_THAN: - return "<"; - case GREATER_THAN: - return ">"; - case EQUAL: - return "="; - case NOT_EQUAL: - return "!="; - case LESS_THAN_OR_EQUAL: - return "<="; - case GREATER_THAN_OR_EQUAL: - return ">="; - default: - return "="; - } - } -} diff --git a/src/com/redstoner/misc/mysql/elements/MysqlConstraint.java b/src/com/redstoner/misc/mysql/elements/MysqlConstraint.java deleted file mode 100644 index d651344..0000000 --- a/src/com/redstoner/misc/mysql/elements/MysqlConstraint.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.redstoner.misc.mysql.elements; - -public class MysqlConstraint { - private String fieldName, value; - private ConstraintOperator operator; - - public MysqlConstraint(String fieldName, ConstraintOperator operator, String value) { - this.fieldName = fieldName; - this.operator = operator; - this.value = value; - } - - public String getFieldName() { - return fieldName; - } - - public String getValue() { - return value; - } - - public ConstraintOperator getOperator() { - return operator; - } -} diff --git a/src/com/redstoner/misc/mysql/elements/MysqlDatabase.java b/src/com/redstoner/misc/mysql/elements/MysqlDatabase.java deleted file mode 100644 index 91c0fe4..0000000 --- a/src/com/redstoner/misc/mysql/elements/MysqlDatabase.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.redstoner.misc.mysql.elements; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import com.redstoner.misc.mysql.MysqlQueryHandler; - -public class MysqlDatabase { - private Connection connection; - - public MysqlDatabase(Connection connection) { - this.connection = connection; - } - - public String getName() { - try { - return connection.getCatalog(); - } catch (SQLException e) { - e.printStackTrace(); - return null; - } - } - - public MysqlTable getTable(String name) { - return new MysqlTable(this, name); - } - - public boolean createTable(String name, MysqlField... description) { - return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE `" + name + "` " + getDescription(description) + ";"); - } - - public boolean createTableIfNotExists(String name, MysqlField... description) { - return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE IF NOT EXISTS `" + name + "` " + getDescription(description) + ";"); - } - - public boolean dropTable(String name) { - return MysqlQueryHandler.queryNoResult(connection, "DROP TABLE `" + name + "`;"); - } - - public boolean drop() { - return MysqlQueryHandler.queryNoResult(connection, "DROP DATABASE `" + getName() + "`;"); - } - - public List getTables() { - try { - List tables = new ArrayList<>(); - DatabaseMetaData metadata = connection.getMetaData(); - ResultSet queryResults = metadata.getTables(null, null, "%", null); - - while (queryResults.next()) { - tables.add(new MysqlTable(this, queryResults.getString(3))); - } - - return tables; - } catch (SQLException e) { - e.printStackTrace(); - return null; - } - } - - protected Connection getConnection() { - return connection; - } - - private String getDescription(MysqlField... description) { - String desc = "("; - - for (int i = 0; i < description.length; i++) { - String nil = ""; - - if (description[i].canBeNull()) { - nil = " NOT NULL"; - } - - desc += "`" + description[i].getName() + "` " + description[i].getType().getName() + nil; - - if (i < description.length - 1) { - desc += ","; - } - } - - desc += ")"; - - return desc; - } -} diff --git a/src/com/redstoner/misc/mysql/elements/MysqlField.java b/src/com/redstoner/misc/mysql/elements/MysqlField.java deleted file mode 100644 index 61cba2e..0000000 --- a/src/com/redstoner/misc/mysql/elements/MysqlField.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.redstoner.misc.mysql.elements; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class MysqlField { - private String name; - private MysqlType type; - private boolean canBeNull; - - public MysqlField(String name, MysqlType type, boolean canBeNull) { - this.name = name; - this.type = type; - this.canBeNull = canBeNull; - } - - public MysqlField(String name, String type, boolean canBeNull) { - this.name = name; - this.type = MysqlType.getTypeFromString(type); - this.canBeNull = canBeNull; - } - - public String getName() { - return name; - } - - public MysqlType getType() { - return type; - } - - public boolean canBeNull() { - return canBeNull; - } -} diff --git a/src/com/redstoner/misc/mysql/elements/MysqlResult.java b/src/com/redstoner/misc/mysql/elements/MysqlResult.java deleted file mode 100644 index 6db0769..0000000 --- a/src/com/redstoner/misc/mysql/elements/MysqlResult.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.redstoner.misc.mysql.elements; - -import java.sql.ResultSet; -import java.sql.SQLException; - -public class MysqlResult { - private ResultSet results; - - public MysqlResult(ResultSet results) { - this.results = results; - } - - public Object getObject(int columnIndex, Class type) throws SQLException { - return results.getObject(columnIndex, type); - } -} diff --git a/src/com/redstoner/misc/mysql/elements/MysqlTable.java b/src/com/redstoner/misc/mysql/elements/MysqlTable.java deleted file mode 100644 index 6656fcd..0000000 --- a/src/com/redstoner/misc/mysql/elements/MysqlTable.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.redstoner.misc.mysql.elements; - -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import com.redstoner.misc.mysql.MysqlQueryHandler; - -public class MysqlTable -{ - private MysqlDatabase database; - private String name; - - public MysqlTable(MysqlDatabase database, String name) - { - this.database = database; - this.name = name; - } - - public String getName() - { - return this.name; - } - - public MysqlField[] describe() - { - try - { - List description = new ArrayList<>(); - DatabaseMetaData metadata = database.getConnection().getMetaData(); - ResultSet queryResults = metadata.getColumns(null, null, name, null); - while (queryResults.next()) - { - description.add(new MysqlField(queryResults.getString(4), - queryResults.getString(6).split(" ")[0] + "(" + queryResults.getString(7) + ")", - queryResults.getBoolean(11))); - } - return description.toArray(new MysqlField[0]); - } - catch (SQLException e) - { - e.printStackTrace(); - return null; - } - } - - public boolean insert(String... values) - { - MysqlField[] description = describe(); - if (values.length > 0 && values.length == description.length) - { - String val = "(\"" + String.join("\",\"", values) + "\")"; - return MysqlQueryHandler.queryNoResult(database.getConnection(), - "INSERT INTO `" + name + "` VALUES " + val + ";"); - } - else - { - return false; - } - } - - public Object[] get(String fieldName, MysqlConstraint... constraints) - { - ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), - "SELECT " + fieldName + " FROM `" + name + "`" + getConstraints(constraints) + ";"); - List resObj = new ArrayList<>(); - try - { - while (results.next()) - { - resObj.add(results.getObject(1)); - } - } - catch (SQLException e) - { - e.printStackTrace(); - return new Object[0]; - } - return resObj.toArray(new Object[0]); - } - - public Object[] get(String statement) - { - ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), statement); - List resObj = new ArrayList<>(); - try - { - while (results.next()) - { - resObj.add(results.getObject(1)); - } - } - catch (SQLException e) - { - e.printStackTrace(); - return new Object[0]; - } - return resObj.toArray(new Object[0]); - } - - public boolean delete(MysqlConstraint... constraints) - { - return MysqlQueryHandler.queryNoResult(database.getConnection(), - "DELETE FROM `" + name + "`" + getConstraints(constraints) + ";"); - } - - public boolean drop() - { - return MysqlQueryHandler.queryNoResult(database.getConnection(), "DROP TABLE `" + name + "`;"); - } - - private String getConstraints(MysqlConstraint... constraints) - { - String cons = ""; - if (constraints.length > 0) - { - cons += " WHERE "; - for (int i = 0; i < constraints.length; i++) - { - MysqlConstraint constraint = constraints[i]; - cons += constraint.getFieldName() + constraint.getOperator().toString() + "\"" + constraint.getValue() - + "\""; - if (i < constraints.length - 1) - { - cons += " AND "; - } - } - } - return cons; - } -} diff --git a/src/com/redstoner/misc/mysql/types/MysqlType.java b/src/com/redstoner/misc/mysql/types/MysqlType.java deleted file mode 100644 index 86413f9..0000000 --- a/src/com/redstoner/misc/mysql/types/MysqlType.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.redstoner.misc.mysql.types; - -import com.redstoner.misc.mysql.types.date.Date; -import com.redstoner.misc.mysql.types.date.DateTime; -import com.redstoner.misc.mysql.types.date.Time; -import com.redstoner.misc.mysql.types.date.TimeStamp; -import com.redstoner.misc.mysql.types.date.Year; -import com.redstoner.misc.mysql.types.number.BigInt; -import com.redstoner.misc.mysql.types.number.Decimal; -import com.redstoner.misc.mysql.types.number.Double; -import com.redstoner.misc.mysql.types.number.Float; -import com.redstoner.misc.mysql.types.number.Int; -import com.redstoner.misc.mysql.types.number.MediumInt; -import com.redstoner.misc.mysql.types.number.SmallInt; -import com.redstoner.misc.mysql.types.number.TinyInt; -import com.redstoner.misc.mysql.types.text.Blob; -import com.redstoner.misc.mysql.types.text.Char; -import com.redstoner.misc.mysql.types.text.Enum; -import com.redstoner.misc.mysql.types.text.LongBlob; -import com.redstoner.misc.mysql.types.text.LongText; -import com.redstoner.misc.mysql.types.text.MediumBlob; -import com.redstoner.misc.mysql.types.text.MediumText; -import com.redstoner.misc.mysql.types.text.Set; -import com.redstoner.misc.mysql.types.text.Text; -import com.redstoner.misc.mysql.types.text.TinyText; -import com.redstoner.misc.mysql.types.text.VarChar; - -public abstract class MysqlType -{ - public abstract String getName(); - - public static MysqlType getTypeFromString(String type) - { - String[] splitType = type.split("\\("); - String toSwitch = splitType[0].toUpperCase(); - String value = ""; - if (type.contains("(") && type.endsWith(")")) - { - value = splitType[1].substring(0, splitType[1].length() - 1); - } - switch (toSwitch) - { - case "CHAR": - return new Char(Integer.valueOf(value)); - case "ENUM": - return new Enum(value.replaceAll("'", "").split(",")); - case "VARCHAR": - return new VarChar(Integer.valueOf(value)); - case "SET": - return new Set(value.replaceAll("'", "").split(",")); - case "BLOB": - return new Blob(); - case "TEXT": - return new Text(); - case "MEDIUMBLOB": - return new MediumBlob(); - case "LONGBLOB": - return new LongBlob(); - case "TINYTEXT": - return new TinyText(); - case "MEDIUMTEXT": - return new MediumText(); - case "LONGTEXT": - return new LongText(); - case "INT": - return new Int(Integer.valueOf(value)); - case "TINYINT": - return new TinyInt(Integer.valueOf(value)); - case "SMALLINT": - return new SmallInt(Integer.valueOf(value)); - case "MEDIUMINT": - return new MediumInt(Integer.valueOf(value)); - case "BIGINT": - return new BigInt(Integer.valueOf(value)); - case "BIT": - return new TinyInt(1); - case "FLOAT": - return new Float(); - case "DOUBLE": - return new Double(); - case "DECIMAL": - return new Decimal(); - case "DATE": - return new Date(); - case "DATETIME": - return new DateTime(); - case "TIME": - return new Time(); - case "TIMESTAMP": - return new TimeStamp(); - case "YEAR": - return new Year(); - } - return null; - } -} diff --git a/src/com/redstoner/misc/mysql/types/date/Date.java b/src/com/redstoner/misc/mysql/types/date/Date.java deleted file mode 100644 index 9943333..0000000 --- a/src/com/redstoner/misc/mysql/types/date/Date.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.date; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Date extends MysqlType { - @Override - public String getName() { - return "DATE"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/date/DateTime.java b/src/com/redstoner/misc/mysql/types/date/DateTime.java deleted file mode 100644 index b4d9623..0000000 --- a/src/com/redstoner/misc/mysql/types/date/DateTime.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.date; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class DateTime extends MysqlType { - @Override - public String getName() { - return "DATETIME"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/date/Time.java b/src/com/redstoner/misc/mysql/types/date/Time.java deleted file mode 100644 index 4ead72c..0000000 --- a/src/com/redstoner/misc/mysql/types/date/Time.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.date; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Time extends MysqlType { - @Override - public String getName() { - return "TIME"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/date/TimeStamp.java b/src/com/redstoner/misc/mysql/types/date/TimeStamp.java deleted file mode 100644 index 56205af..0000000 --- a/src/com/redstoner/misc/mysql/types/date/TimeStamp.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.date; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class TimeStamp extends MysqlType { - @Override - public String getName() { - return "TIMESTAMP"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/date/Year.java b/src/com/redstoner/misc/mysql/types/date/Year.java deleted file mode 100644 index 4c2ce1a..0000000 --- a/src/com/redstoner/misc/mysql/types/date/Year.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.date; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Year extends MysqlType { - @Override - public String getName() { - return "YEAR"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/number/BigInt.java b/src/com/redstoner/misc/mysql/types/number/BigInt.java deleted file mode 100644 index 71086fd..0000000 --- a/src/com/redstoner/misc/mysql/types/number/BigInt.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -public class BigInt extends Int { - public BigInt(int maxSize) { - super(maxSize); - } - - @Override - public String getName() { - return "BIG" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/number/Decimal.java b/src/com/redstoner/misc/mysql/types/number/Decimal.java deleted file mode 100644 index 4e4dbb6..0000000 --- a/src/com/redstoner/misc/mysql/types/number/Decimal.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Decimal extends MysqlType { - @Override - public String getName() { - return "DECIMAL"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/number/Double.java b/src/com/redstoner/misc/mysql/types/number/Double.java deleted file mode 100644 index b4b1dda..0000000 --- a/src/com/redstoner/misc/mysql/types/number/Double.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Double extends MysqlType { - @Override - public String getName() { - return "DOUBLE"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/number/Float.java b/src/com/redstoner/misc/mysql/types/number/Float.java deleted file mode 100644 index ea3047e..0000000 --- a/src/com/redstoner/misc/mysql/types/number/Float.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Float extends MysqlType { - @Override - public String getName() { - return "FLOAT"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/number/Int.java b/src/com/redstoner/misc/mysql/types/number/Int.java deleted file mode 100644 index 4256f7b..0000000 --- a/src/com/redstoner/misc/mysql/types/number/Int.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Int extends MysqlType { - private int maxSize; - - public Int(int maxSize) { - this.maxSize = maxSize; - } - - @Override - public String getName() { - return "INT(" + maxSize + ")"; - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/number/MediumInt.java b/src/com/redstoner/misc/mysql/types/number/MediumInt.java deleted file mode 100644 index fbcb0f4..0000000 --- a/src/com/redstoner/misc/mysql/types/number/MediumInt.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -public class MediumInt extends Int { - public MediumInt(int maxSize) { - super(maxSize); - } - - @Override - public String getName() { - return "MEDIUM" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/number/SmallInt.java b/src/com/redstoner/misc/mysql/types/number/SmallInt.java deleted file mode 100644 index 01bf97d..0000000 --- a/src/com/redstoner/misc/mysql/types/number/SmallInt.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -public class SmallInt extends Int { - public SmallInt(int maxSize) { - super(maxSize); - } - - @Override - public String getName() { - return "SMALL" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/number/TinyInt.java b/src/com/redstoner/misc/mysql/types/number/TinyInt.java deleted file mode 100644 index 63ad700..0000000 --- a/src/com/redstoner/misc/mysql/types/number/TinyInt.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.redstoner.misc.mysql.types.number; - -public class TinyInt extends Int { - public TinyInt(int maxSize) { - super(maxSize); - } - - @Override - public String getName() { - return "TINY" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/text/Blob.java b/src/com/redstoner/misc/mysql/types/text/Blob.java deleted file mode 100644 index d56ee45..0000000 --- a/src/com/redstoner/misc/mysql/types/text/Blob.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Blob extends MysqlType { - @Override - public String getName() { - return "BLOB"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/text/Char.java b/src/com/redstoner/misc/mysql/types/text/Char.java deleted file mode 100644 index ece068c..0000000 --- a/src/com/redstoner/misc/mysql/types/text/Char.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Char extends MysqlType { - private int size; - - public Char(int size) { - this.size = size; - } - - @Override - public String getName() { - return "CHAR(" + size + ")"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/text/Enum.java b/src/com/redstoner/misc/mysql/types/text/Enum.java deleted file mode 100644 index e68476d..0000000 --- a/src/com/redstoner/misc/mysql/types/text/Enum.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Enum extends MysqlType { - private String[] possibleValues; - - public Enum(String... possibleValues) { - this.possibleValues = possibleValues; - } - - @Override - public String getName() { - String name = "ENUM("; - - for (int i = 0; i < possibleValues.length; i++) { - name += "'" + possibleValues[i] + "'"; - - if (i != possibleValues.length - 1) { - name += ","; - } - } - - return name + ")"; - } - -} diff --git a/src/com/redstoner/misc/mysql/types/text/LongBlob.java b/src/com/redstoner/misc/mysql/types/text/LongBlob.java deleted file mode 100644 index 802caed..0000000 --- a/src/com/redstoner/misc/mysql/types/text/LongBlob.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -public class LongBlob extends Blob { - @Override - public String getName() { - return "LONG" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/text/LongText.java b/src/com/redstoner/misc/mysql/types/text/LongText.java deleted file mode 100644 index 5149ed2..0000000 --- a/src/com/redstoner/misc/mysql/types/text/LongText.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -public class LongText extends Text { - @Override - public String getName() { - return "LONG" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/text/MediumBlob.java b/src/com/redstoner/misc/mysql/types/text/MediumBlob.java deleted file mode 100644 index 6ae25a7..0000000 --- a/src/com/redstoner/misc/mysql/types/text/MediumBlob.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -public class MediumBlob extends Blob { - @Override - public String getName() { - return "MEDIUM" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/text/MediumText.java b/src/com/redstoner/misc/mysql/types/text/MediumText.java deleted file mode 100644 index a0f6525..0000000 --- a/src/com/redstoner/misc/mysql/types/text/MediumText.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -public class MediumText extends Text { - @Override - public String getName() { - return "MEDIUM" + super.getName(); - } -} \ No newline at end of file diff --git a/src/com/redstoner/misc/mysql/types/text/Set.java b/src/com/redstoner/misc/mysql/types/text/Set.java deleted file mode 100644 index 4e12ce6..0000000 --- a/src/com/redstoner/misc/mysql/types/text/Set.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Set extends MysqlType { - private String[] possibleValues; - - public Set(String... possibleValues) { - this.possibleValues = possibleValues; - } - - @Override - public String getName() { - String name = "SET("; - - for (int i = 0; i < possibleValues.length; i++) { - name += "'" + possibleValues[i] + "'"; - - if (i != possibleValues.length - 1) { - name += ","; - } - } - - return name + ")"; - } - -} diff --git a/src/com/redstoner/misc/mysql/types/text/Text.java b/src/com/redstoner/misc/mysql/types/text/Text.java deleted file mode 100644 index 7d1a38c..0000000 --- a/src/com/redstoner/misc/mysql/types/text/Text.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class Text extends MysqlType { - @Override - public String getName() { - return "TEXT"; - } -} diff --git a/src/com/redstoner/misc/mysql/types/text/TinyText.java b/src/com/redstoner/misc/mysql/types/text/TinyText.java deleted file mode 100644 index e78160c..0000000 --- a/src/com/redstoner/misc/mysql/types/text/TinyText.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -public class TinyText extends Text { - @Override - public String getName() { - return "TINY" + super.getName(); - } -} diff --git a/src/com/redstoner/misc/mysql/types/text/VarChar.java b/src/com/redstoner/misc/mysql/types/text/VarChar.java deleted file mode 100644 index cb28ad1..0000000 --- a/src/com/redstoner/misc/mysql/types/text/VarChar.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.redstoner.misc.mysql.types.text; - -import com.redstoner.misc.mysql.types.MysqlType; - -public class VarChar extends MysqlType { - private int maxSize; - - public VarChar(int maxSize) { - this.maxSize = maxSize; - } - - @Override - public String getName() { - return "VARCHAR(" + maxSize + ")"; - } -} \ No newline at end of file diff --git a/src/com/redstoner/modules/CoreModule.java b/src/com/redstoner/modules/CoreModule.java deleted file mode 100644 index 9f71557..0000000 --- a/src/com/redstoner/modules/CoreModule.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.redstoner.modules; - -import com.redstoner.annotations.Version; - -/** This class shall be used for "CoreModules", which are acting on a lower level than modules and are also exempted from being disabled or reloaded on the go.
- * Please note that CoreModules will not be known to the ModuleLoader itself!
- * Examples are the ModuleLoader and the Debugger. - * - * @author Pepich */ -@Version(major = 2, minor = 0, revision = 0, compatible = -1) -public interface CoreModule extends Module -{ - /** Core modules don't need to be enabled. */ - @Override - public default boolean onEnable() - { - return true; - } - - /** Core modules don't need to be disabled. */ - @Override - public default void onDisable() - {} -} diff --git a/src/com/redstoner/modules/Module.java b/src/com/redstoner/modules/Module.java deleted file mode 100644 index 1c89e15..0000000 --- a/src/com/redstoner/modules/Module.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.redstoner.modules; - -import com.redstoner.annotations.Version; -import com.redstoner.coremods.moduleLoader.ModuleLoader; - -/** Interface for the Module class. Modules must always have an empty constructor to be invoked by the ModuleLoader. - * - * @author Pepich */ -@Version(major = 4, minor = 0, revision = 0, compatible = 0) -public interface Module -{ - /** Will be called when the module gets enabled. */ - public default boolean onEnable() - { - return true; - } - - /** This methods gets called after all modules were enabled, please use this method to register commands and similar.
- * It will only get called if and only if the module was successfully enabled. */ - public default void postEnable() - {} - - /** Will be called when the module gets disabled. */ - public default void onDisable() - {} - - /** Gets called on registration of the module, when this option is selected for command registration - * - * @return The String used for the CommandManager to register the commands. */ - public default String getCommandString() - { - return null; - } - - public default ModuleLogger getLogger() - { - return ModuleLoader.getModuleLogger(this); - } - - /** This method gets run the very first time a module gets loaded. You can use this to set up file structures or background data. */ - public default void firstLoad() - {} - - /** This method gets run every time a module gets loaded and its version has changed. - * - * @param old The version of the previous module. */ - public default void migrate(Version old) - {} - - default void setPrefix(final String name) - { - getLogger().setName(name); - } -} diff --git a/src/com/redstoner/modules/ModuleLogger.java b/src/com/redstoner/modules/ModuleLogger.java deleted file mode 100644 index 8141976..0000000 --- a/src/com/redstoner/modules/ModuleLogger.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.redstoner.modules; - -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; - -import com.redstoner.annotations.Version; - -import net.nemez.chatapi.ChatAPI; -import net.nemez.chatapi.click.Message; - -@Version(major = 4, minor = 0, revision = 0, compatible = -1) -public class ModuleLogger -{ - public static final String PREFIX_WARN = "§8[§eWARN§8]:§7 "; - public static final String PREFIX_ERROR = "§8[§cERROR§8]:§7 "; - - private String name; - - public ModuleLogger(final String name) - { - this.name = name; - } - - public void info(final String message) - { - Bukkit.getConsoleSender().sendMessage(getPrefix() + ChatAPI.colorify(null, message)); - } - - public void warn(final String message) - { - Bukkit.getConsoleSender().sendMessage(PREFIX_WARN + getPrefix() + ChatAPI.colorify(null, message)); - } - - public void error(final String message) - { - Bukkit.getConsoleSender().sendMessage(PREFIX_ERROR + getPrefix() + ChatAPI.colorify(null, message)); - } - - public void message(final CommandSender recipient, final String... message) - { - message(recipient, false, message); - } - - public void message(final CommandSender recipient, final boolean error, final String... message) - { - Message m = new Message(recipient, null); - if (message.length == 1) - m.appendText(getPrefix(error) + message[0]); - else - { - m.appendText(getHeader()); - m.appendText("&7" + String.join("\n&7", message)); - } - m.send(); - } - - public String getPrefix() - { - return getPrefix(false); - } - - public String getPrefix(final boolean error) - { - return "§8[§" + (error ? 'c' : '2') + name + "§8]§7 "; - } - - public String getHeader() - { - return "§2--=[ " + name + " ]=--\n"; - } - - protected final void setName(final String name) - { - this.name = name; - } -} diff --git a/src/main/java/com/redstoner/annotations/AutoRegisterListener.java b/src/main/java/com/redstoner/annotations/AutoRegisterListener.java new file mode 100644 index 0000000..fabdb5f --- /dev/null +++ b/src/main/java/com/redstoner/annotations/AutoRegisterListener.java @@ -0,0 +1,15 @@ +package com.redstoner.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** The auto register annotation, to be put onto Classes that implement listener when you are too lazy to register the events yourself. + * + * @author Pepich */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Version(major = 1, minor = 0, revision = 1, compatible = 1) +public @interface AutoRegisterListener +{} diff --git a/src/main/java/com/redstoner/annotations/Commands.java b/src/main/java/com/redstoner/annotations/Commands.java new file mode 100644 index 0000000..537bff0 --- /dev/null +++ b/src/main/java/com/redstoner/annotations/Commands.java @@ -0,0 +1,15 @@ +package com.redstoner.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.redstoner.misc.CommandHolderType; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Commands +{ + CommandHolderType value(); +} diff --git a/src/main/java/com/redstoner/annotations/Version.java b/src/main/java/com/redstoner/annotations/Version.java new file mode 100644 index 0000000..52d5145 --- /dev/null +++ b/src/main/java/com/redstoner/annotations/Version.java @@ -0,0 +1,32 @@ +package com.redstoner.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** The Version annotation, to be applied to all Classes that are part of the project. + * + * @author Pepich */ +@Target(ElementType.TYPE) +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface Version +{ + /** The major indicator of the version. Will be used for compatibility detection. + * + * @return the major version as an int */ + int major(); + + int minor(); + + int revision(); + + /** The compatibility part of the version number. Will be used for compatibility detection.
+ * Set to -1 if it is supposed to be always compatible.
+ * Defaults to 1. + * + * @return the smallest compatible version as an int. */ + int compatible() default 1; +} diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd new file mode 100644 index 0000000..eadeeb7 --- /dev/null +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd @@ -0,0 +1,34 @@ +command modules { + [empty] { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run list; + } + list { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run list; + } + -v { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run listv; + } + list -v { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run listv; + } + load [string:name...] { + help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; + perm moduleloader.modules.admin; + run load name; + type console; + } + unload [string:name...] { + help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; + perm moduleloader.modules.admin; + run unload name; + type console; + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java new file mode 100644 index 0000000..b4fbbe4 --- /dev/null +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -0,0 +1,736 @@ +package com.redstoner.coremods.moduleLoader; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.Command.AsyncType; +import com.nemez.cmdmgr.CommandManager; +import com.redstoner.annotations.AutoRegisterListener; +import com.redstoner.annotations.Commands; +import com.redstoner.annotations.Version; +import com.redstoner.exceptions.MissingVersionException; +import com.redstoner.misc.Main; +import com.redstoner.misc.VersionHelper; +import com.redstoner.modules.CoreModule; +import com.redstoner.modules.Module; +import com.redstoner.modules.ModuleLogger; + +import net.nemez.chatapi.click.Message; + +/** The module loader, mother of all modules. Responsible for loading and taking care of all modules. + * + * @author Pepich */ +@Version(major = 4, minor = 0, revision = 1, compatible = 4) +public final class ModuleLoader implements CoreModule +{ + private static ModuleLoader instance; + private static final HashMap modules = new HashMap<>(); + private static URL[] urls; + private static URLClassLoader mainLoader; + private static HashMap loaders = new HashMap<>(); + private static File configFile; + private static FileConfiguration config; + private static boolean debugMode = false; + private static HashMap loggers = new HashMap<>(); + + private ModuleLoader() + { + try + { + config = Main.plugin.getConfig(); + configFile = new File(Main.plugin.getDataFolder(), "config.yml"); + urls = new URL[] {(new File(Main.plugin.getDataFolder(), "classes")).toURI().toURL()}; + mainLoader = new URLClassLoader(urls, this.getClass().getClassLoader()); + } + catch (MalformedURLException e) + { + System.out.println("Sumtin is wong with ya filesüstem m8. Fix eeeet or I won't werk!"); + Bukkit.getPluginManager().disablePlugin(Main.plugin); + } + } + + public static void init() + { + if (instance == null) + instance = new ModuleLoader(); + loggers.put(instance, new ModuleLogger("ModuleLoader")); + CommandManager.registerCommand(ModuleLoader.class.getResourceAsStream("ModuleLoader.cmd"), instance, + Main.plugin); + } + + public static final void loadFromConfig() + { + try + { + if (!configFile.exists()) + { + configFile.getParentFile().mkdirs(); + configFile.createNewFile(); + } + config.load(configFile); + } + catch (FileNotFoundException e) + {} + catch (IOException e) + { + e.printStackTrace(); + } + catch (InvalidConfigurationException e) + { + configFile.delete(); + try + { + configFile.createNewFile(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + instance.getLogger().error("Invalid config file! Creating new, blank file!"); + } + List coremods = config.getStringList("coremods"); + if (coremods == null || coremods.isEmpty()) + { + config.set("coremods", new String[] {"# Add the coremodules here!"}); + Main.plugin.saveConfig(); + try + { + config.save(configFile); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + List autoload = config.getStringList("autoload"); + if (autoload == null || autoload.isEmpty()) + { + config.set("autoload", new String[] {"# Add the modules here!"}); + Main.plugin.saveConfig(); + try + { + config.save(configFile); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + if (!config.contains("debugMode")) + { + config.set("debugMode", false); + try + { + config.save(configFile); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + debugMode = config.getBoolean("debugMode"); + for (String s : coremods) + if (!s.startsWith("#")) + if (!ModuleLoader.addDynamicModule(s)) + { + instance.getLogger().error("Couldn't autocomplete path for module name: " + s + + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); + + } + for (String s : autoload) + if (!s.startsWith("#")) + if (!ModuleLoader.addDynamicModule(s)) + { + instance.getLogger().error("Couldn't autocomplete path for module name: " + s + + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); + + } + updateConfig(); + } + + /** This method enables a specific module. If no module with that name is known to the loader yet it will be added to the list.
+ * This method is deprecated, use enableDynamicModule instead. When using this method, dynamic reloading of the module will not be supported. + * + * @param clazz The class of the module to be enabled. + * @return true, when the module was successfully enabled. */ + @Deprecated + public static final boolean enableModule(Class clazz) + { + for (Module module : modules.keySet()) + { + if (module.getClass().equals(clazz)) + { + if (modules.get(module)) + { + instance.getLogger().info("Module was already enabled! Ignoring module.!"); + return true; + } + if (module.onEnable()) + { + if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) + && (module instanceof Listener)) + { + Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); + } + instance.getLogger().info("Enabled module " + module.getClass().getName()); + instance.getLogger().info("Loaded module " + module.getClass().getName()); + modules.put(module, true); + return true; + } + else + { + instance.getLogger().error("Failed to enable module " + module.getClass().getName()); + return false; + } + } + } + try + { + Module m = clazz.newInstance(); + modules.put(m, false); + if (m.onEnable()) + { + if (m.getClass().isAnnotationPresent(AutoRegisterListener.class) && (m instanceof Listener)) + { + Bukkit.getPluginManager().registerEvents((Listener) m, Main.plugin); + } + instance.getLogger().info("Loaded and enabled module " + m.getClass().getName()); + instance.getLogger().info("Loaded module " + m.getClass().getName()); + return true; + } + else + { + instance.getLogger().error("Failed to enable module " + m.getClass().getName()); + return false; + } + } + catch (InstantiationException | IllegalAccessException e) + { + instance.getLogger() + .error("Could not add " + clazz.getName() + " to the list, constructor not accessible."); + return false; + } + } + + private static final void enableLoadedModule(Module module, Version oldVersion) + { + try + { + loggers.put(module, new ModuleLogger(module.getClass().getSimpleName())); + if (module.onEnable()) + { + modules.put(module, true); + if (VersionHelper.getString(oldVersion).equals("0.0.0.0")) + module.firstLoad(); + else if (!VersionHelper.getVersion(module.getClass()).equals(VersionHelper.getString(oldVersion))) + module.migrate(oldVersion); + if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 3), module.getClass())) + module.postEnable(); + if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 4), module.getClass())) + { + Commands ann = module.getClass().getAnnotation(Commands.class); + if (ann != null) + { + switch (ann.value()) + { + case File: + File f = new File("plugins/ModuleLoader/classes/" + + module.getClass().getName().replace(".", "/") + ".cmd"); + CommandManager.registerCommand(f, module, Main.plugin); + break; + case Stream: + InputStream stream = module.getClass() + .getResourceAsStream(module.getClass().getSimpleName() + ".cmd"); + CommandManager.registerCommand(stream, module, Main.plugin); + case String: + CommandManager.registerCommand(module.getCommandString(), module, Main.plugin); + break; + case None: + break; + } + } + } + instance.getLogger().info("Loaded module " + module.getClass().getName()); + if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) && (module instanceof Listener)) + Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin); + } + else + instance.getLogger().error("Failed to load module " + module.getClass().getName()); + } + catch (Exception e) + { + instance.getLogger().error("Failed to load module " + module.getClass().getName()); + e.printStackTrace(); + } + } + + /** This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. + * + * @param sender The person to send the info to, usually the issuer of the command or the console sender. + * @return true. */ + @Command(hook = "list", async = AsyncType.ALWAYS) + public boolean listModulesCommand(CommandSender sender) + { + Message m = new Message(sender, null); + m.appendText(getLogger().getHeader()); + m.appendText("§2Modules:\n&e"); + Module[] modules = ModuleLoader.modules.keySet().toArray(new Module[] {}); + for (int i = 0; i < modules.length; i++) + { + Module module = modules[i]; + String[] classPath = module.getClass().getName().split("\\."); + String classname = classPath[classPath.length - 1]; + m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname); + if (i + 1 < modules.length) + m.appendText("§7, "); + } + m.send(); + return true; + } + + /** This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. + * + * @param sender The person to send the info to, usually the issuer of the command or the console sender. + * @return true. */ + @Command(hook = "listv", async = AsyncType.ALWAYS) + public boolean listModulesCommandVersion(CommandSender sender) + { + Message m = new Message(sender, null); + m.appendText(getLogger().getHeader()); + m.appendText("§2Modules:\n&e"); + Module[] modules = ModuleLoader.modules.keySet().toArray(new Module[] {}); + for (int i = 0; i < modules.length; i++) + { + Module module = modules[i]; + String[] classPath = module.getClass().getName().split("\\."); + String classname = classPath[classPath.length - 1]; + try + { + m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname + "§e(" + + VersionHelper.getVersion(module.getClass()) + ")"); + } + catch (MissingVersionException e) + { + m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname + "§c" + "(Unknown Version)"); + } + if (i + 1 < modules.length) + m.appendText("§7, "); + } + m.send(); + return true; + } + + public static void disableModules() + { + for (Module module : modules.keySet()) + { + disableModule(module); + } + } + + public static void disableModule(Module module) + { + if (modules.get(module)) + { + module.onDisable(); + if (module.getClass().isAnnotationPresent(AutoRegisterListener.class) && (module instanceof Listener)) + { + HandlerList.unregisterAll((Listener) module); + } + String[] commands = getAllHooks(module).toArray(new String[] {}); + CommandManager.unregisterAll(commands); + try + { + URLClassLoader loader = loaders.get(module); + if (loader != null) + loader.close(); + } + catch (IOException e) + {} + finally + { + loaders.remove(module); + } + } + } + + private static ArrayList getAllHooks(Module module) + { + ArrayList commands = new ArrayList<>(); + for (Method m : module.getClass().getMethods()) + { + Command cmd = m.getDeclaredAnnotation(Command.class); + if (cmd == null) + continue; + commands.add(cmd.hook()); + } + return commands; + } + + @Command(hook = "load") + public boolean loadModule(CommandSender sender, String name) + { + if (!addDynamicModule(name)) + { + instance.getLogger().message(sender, true, "Couldn't autocomplete path for module name: " + name + + "! If you're on a case sensitive filesystem, please take note that case correction does not work. Make sure that the classname has proper capitalisation."); + + } + updateConfig(); + return true; + } + + @Command(hook = "unload") + public boolean unloadModule(CommandSender sender, String name) + { + if (!removeDynamicModule(name)) + instance.getLogger().error("Couldn't find module! Couldn't disable nonexisting module!"); + return true; + } + + public static final boolean addDynamicModule(String raw_name) + { + String[] raw = raw_name.split(" "); + String name = raw[0]; + Version oldVersion; + if (raw.length > 1) + oldVersion = VersionHelper.getVersion(raw[1]); + else + oldVersion = VersionHelper.create(0, 0, 0, 0); + for (Module m : modules.keySet()) + { + if (m.getClass().getName().equals(name)) + { + instance.getLogger().info( + "Found existing module, attempting override. WARNING! This operation will halt the main thread until it is completed."); + instance.getLogger() + .info("Attempting to load new class definition before disabling and removing the old module"); + boolean differs = false; + instance.getLogger().info("Old class definition: Class@" + m.getClass().hashCode()); + ClassLoader delegateParent = mainLoader.getParent(); + Class newClass = null; + URLClassLoader cl = new URLClassLoader(urls, delegateParent); + try + { + newClass = cl.loadClass(m.getClass().getName()); + instance.getLogger().info("Found new class definition: Class@" + newClass.hashCode()); + differs = m.getClass() != newClass; + } + catch (ClassNotFoundException e) + { + instance.getLogger().error("Could not find a class definition, aborting now!"); + e.printStackTrace(); + try + { + cl.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + return false; + } + if (!differs) + { + if (!debugMode) + { + instance.getLogger().warn( + "New class definition equals old definition, are you sure you did everything right?"); + instance.getLogger().info("Aborting now..."); + try + { + cl.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + return false; + } + else + instance.getLogger().warn( + "New class definition equals old definition, but debugMode is enabled. Loading anyways."); + } + else + instance.getLogger().info("Found new class definition, attempting to instantiate:"); + Module module = null; + try + { + module = (Module) newClass.newInstance(); + } + catch (InstantiationException | IllegalAccessException e) + { + instance.getLogger().error("Could not instantiate the module, aborting!"); + e.printStackTrace(); + try + { + cl.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + return false; + } + instance.getLogger().info("Instantiated new class definition, checking versions"); + oldVersion = m.getClass().getAnnotation(Version.class); + instance.getLogger().info("Current version: " + VersionHelper.getString(oldVersion)); + Version newVersion = module.getClass().getAnnotation(Version.class); + instance.getLogger().info("Version of remote class: " + VersionHelper.getString(newVersion)); + if (oldVersion.equals(newVersion)) + { + if (!debugMode) + { + instance.getLogger().error("Detected equal module versions, " + (debugMode + ? " aborting now... Set debugMode to true in your config if you want to continue!" + : " continueing anyways.")); + if (!debugMode) + { + try + { + cl.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + return false; + } + } + else + instance.getLogger() + .warn("New version equals old version, but debugMode is enabled. Loading anyways."); + } + else + instance.getLogger().info("Versions differ, disabling old module"); + disableModule(m); + instance.getLogger().info("Disabled module, overriding the implementation"); + modules.remove(m); + try + { + if (loaders.containsKey(m)) + loaders.remove(m).close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + modules.put(module, false); + loaders.put(module, cl); + instance.getLogger().info("Successfully updated class definition. Enabling new implementation:"); + enableLoadedModule(module, oldVersion); + return true; + } + } + ClassLoader delegateParent = mainLoader.getParent(); + URLClassLoader cl = new URLClassLoader(urls, delegateParent); + try + { + Class clazz = cl.loadClass(name); + Module module = (Module) clazz.newInstance(); + modules.put(module, false); + loaders.put(module, cl); + enableLoadedModule(module, oldVersion); + return true; + } + catch (NoClassDefFoundError | ClassNotFoundException | InstantiationException | IllegalAccessException e) + { + try + { + cl.close(); + } + catch (IOException e1) + {} + if (e instanceof NoClassDefFoundError) + { + NoClassDefFoundError exception = (NoClassDefFoundError) e; + String[] exMessage = exception.getMessage().split(" "); + String moduleName = exMessage[exMessage.length - 1] + .substring(0, exMessage[exMessage.length - 1].length() + - (exMessage[exMessage.length - 1].endsWith(")") ? 1 : 0)) + .replace("/", "."); + if (!moduleName.equalsIgnoreCase(name)) + { + instance.getLogger() + .error("Class &e" + moduleName + "&r couldn't be found! Suspecting a missing dependency!"); + return false; + } + else + instance.getLogger().warn( + "Couldn't find class definition, attempting to get proper classname from thrown Exception."); + if (addDynamicModule(moduleName)) + return true; + } + if (name.endsWith(".class")) + { + instance.getLogger().warn( + "Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix."); + if (addDynamicModule(name.replaceAll(".class$", ""))) + return true; + } + if (!name.contains(".")) + { + instance.getLogger().warn( + "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a package name and trying again."); + if (addDynamicModule(name.toLowerCase() + "." + name)) + return true; + } + if (!name.startsWith("com.redstoner.modules.") && name.contains(".")) + { + instance.getLogger().warn( + "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of package name and trying again."); + if (addDynamicModule("com.redstoner.modules." + name)) + return true; + } + } + return false; + } + + public static final boolean removeDynamicModule(String name) + { + for (Module m : modules.keySet()) + { + if (m.getClass().getName().equals(name)) + { + instance.getLogger().info( + "Found existing module, attempting unload. WARNING! This operation will halt the main thread until it is completed."); + instance.getLogger().info("Attempting to disable module properly:"); + disableModule(m); + modules.remove(m); + instance.getLogger().info("Disabled module."); + return true; + } + } + if (!name.startsWith("com.redstoner.modules.")) + { + if (name.endsWith(".class")) + { + instance.getLogger().warn( + "Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix."); + if (removeDynamicModule(name.replaceAll(".class$", ""))) + return true; + } + if (!name.contains(".")) + { + instance.getLogger().warn( + "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a package name and trying again."); + if (removeDynamicModule(name.toLowerCase() + "." + name)) + return true; + } + if (!name.startsWith("com.redstoner.modules.")) + { + instance.getLogger().warn( + "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of package name and trying again."); + if (removeDynamicModule("com.redstoner.modules." + name)) + return true; + } + } + return false; + } + + /** Finds a module by name for other modules to reference it. + * + * @param name the name of the module. Use the full path if you are not sure about the module's SimpleClassName being unique. + * @return the instance of the module or @null it none could be found */ + public static Module getModule(String name) + { + for (Module m : modules.keySet()) + if (m.getClass().getSimpleName().equalsIgnoreCase(name) || m.getClass().getName().equalsIgnoreCase(name)) + return m; + return null; + } + + /** Finds a module by name for other modules to reference it. + * + * @param name the name of the module. Use the full path if you are not sure about the module's SimpleClassName being unique. + * @return the instance of the module or @null it none could be found */ + public static boolean exists(String name) + { + for (Module m : modules.keySet()) + if (m.getClass().getSimpleName().equals(name) || m.getClass().getName().equals(name)) + return true; + return false; + } + + public static ModuleLogger getModuleLogger(Module module) + { + return loggers.get(module); + } + + public static void updateConfig() + { + List coremods = config.getStringList("coremods"); + ArrayList new_coremods = new ArrayList<>(); + List autoload = config.getStringList("autoload"); + ArrayList new_autoload = new ArrayList<>(); + + for (String s : coremods) + { + if (s.startsWith("#")) + { + new_coremods.add(s); + } + else + { + s = s.split(" ")[0]; + try + { + new_coremods.add(getModule(s).getClass().getName() + " " + + VersionHelper.getVersion(getModule(s).getClass())); + } + catch (Exception e) + { + new_coremods.add(s + " " + VersionHelper.getString(VersionHelper.create(0, 0, 0, 0))); + } + } + } + for (String s : autoload) + { + if (s.startsWith("#")) + { + new_autoload.add(s); + } + else + { + s = s.split(" ")[0]; + try + { + new_autoload.add(getModule(s).getClass().getName() + " " + + VersionHelper.getVersion(getModule(s).getClass())); + } + catch (Exception e) + { + new_autoload.add(s + " " + VersionHelper.getString(VersionHelper.create(0, 0, 0, 0))); + } + } + } + + config.set("coremods", new_coremods); + config.set("autoload", new_autoload); + try + { + config.save(configFile); + } + catch (IOException e) + { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/redstoner/exceptions/MissingVersionException.java b/src/main/java/com/redstoner/exceptions/MissingVersionException.java new file mode 100644 index 0000000..62032b6 --- /dev/null +++ b/src/main/java/com/redstoner/exceptions/MissingVersionException.java @@ -0,0 +1,22 @@ +package com.redstoner.exceptions; + +import com.redstoner.annotations.Version; + +/** To be thrown when a module is not annotated with its version. If this gets thrown, then oh boy, you're in trouble now. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 0, compatible = -1) +public class MissingVersionException extends Exception +{ + private static final long serialVersionUID = 4940161335512222539L; + + public MissingVersionException() + { + super(); + } + + public MissingVersionException(String message) + { + super(message); + } +} diff --git a/src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java b/src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java new file mode 100644 index 0000000..df33bff --- /dev/null +++ b/src/main/java/com/redstoner/exceptions/NonSaveableConfigException.java @@ -0,0 +1,9 @@ +package com.redstoner.exceptions; + +public class NonSaveableConfigException extends Exception { + private static final long serialVersionUID = -7271481973389455510L; + + public NonSaveableConfigException() { + super("This config does not support saving!"); + } +} diff --git a/src/main/java/com/redstoner/misc/BroadcastFilter.java b/src/main/java/com/redstoner/misc/BroadcastFilter.java new file mode 100644 index 0000000..1f0ce04 --- /dev/null +++ b/src/main/java/com/redstoner/misc/BroadcastFilter.java @@ -0,0 +1,14 @@ +package com.redstoner.misc; + +import org.bukkit.command.CommandSender; + +import com.redstoner.annotations.Version; + +/** Classes implementing this interface can be used to define a filter for the Utils.broadcast method for sending a message to more than one, but less than all users. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 0, compatible = 1) +public interface BroadcastFilter +{ + public boolean sendTo(CommandSender recipient); +} diff --git a/src/main/java/com/redstoner/misc/CommandHolderType.java b/src/main/java/com/redstoner/misc/CommandHolderType.java new file mode 100644 index 0000000..7c4383e --- /dev/null +++ b/src/main/java/com/redstoner/misc/CommandHolderType.java @@ -0,0 +1,13 @@ +package com.redstoner.misc; + +import com.redstoner.annotations.Version; + +/** @author Pepich */ +@Version(major = 4, minor = 0, revision = 0, compatible = -1) +public enum CommandHolderType +{ + Stream, + File, + String, + None +} diff --git a/src/main/java/com/redstoner/misc/JsonManager.java b/src/main/java/com/redstoner/misc/JsonManager.java new file mode 100644 index 0000000..13b51b6 --- /dev/null +++ b/src/main/java/com/redstoner/misc/JsonManager.java @@ -0,0 +1,149 @@ +package com.redstoner.misc; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.redstoner.annotations.Version; + +/** This class provides simple JSON handling, like storing and loading from and to files. + * + * @author Pepich */ +@Version(major = 1, minor = 0, revision = 2, compatible = -1) +public class JsonManager +{ + private JsonManager() + {} + + /** Loads a JSONObject from a file. + * + * @param source the file to load from. + * @return the JSONObject or null if the source does not contain a valid JSONObject. */ + public static JSONObject getObject(File source) + { + if (!source.exists()) + return null; + JSONParser parser = new JSONParser(); + try + { + FileReader reader = new FileReader(source); + Object rawObject = parser.parse(reader); + reader.close(); + JSONObject jsonObject = (JSONObject) rawObject; + return jsonObject; + } + catch (IOException | ParseException e) + {} + return null; + } + + /** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
+ * Note that this operation will be run on a different thread and you do not need to take care of that yourself. + * + * @param object the JSONObject to save. + * @param destination the file to write to. */ + public static void save(JSONObject object, File destination) + { + Thread t = new Thread(new Runnable() + { + @Override + public void run() + { + saveSync(object, destination); + } + }); + t.start(); + } + + /** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.
+ * Note that this operation will be run on the same thread that you are calling it from! + * + * @param object the JSONObject to save. + * @param destination the file to write to. */ + public static void saveSync(JSONObject object, File destination) + { + if (destination.exists()) + destination.delete(); + else if (!destination.getParentFile().exists()) + destination.getParentFile().mkdirs(); + try + { + destination.createNewFile(); + FileWriter writer = new FileWriter(destination); + String json_string = object.toJSONString(); + writer.write(json_string); + writer.flush(); + writer.close(); + } + catch (IOException e) + {} + } + + /** Loads a JSONArray from a file. + * + * @param source the file to load from. + * @return the JSONArray or null if the source does not contain a valid JSONArray. */ + public static JSONArray getArray(File source) + { + if (!source.exists()) + return null; + JSONParser parser = new JSONParser(); + try + { + Object rawObject = parser.parse(new FileReader(source)); + JSONArray jsonArray = (JSONArray) rawObject; + return jsonArray; + } + catch (IOException | ParseException e) + {} + return null; + } + + /** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
+ * Note that this operation will be run on a different thread and you do not need to take care of that yourself. + * + * @param object the JSONArray to save. + * @param destination the file to write to. */ + public static void save(JSONArray array, File destination) + { + Thread t = new Thread(new Runnable() + { + @Override + public void run() + { + saveSync(array, destination); + } + }); + t.start(); + } + + /** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.
+ * Note that this operation will be run on the same thread that you are calling it from! + * + * @param object the JSONArray to save. + * @param destination the file to write to. */ + public static void saveSync(JSONArray array, File destination) + { + if (destination.exists()) + destination.delete(); + else if (!destination.getParentFile().exists()) + destination.getParentFile().mkdirs(); + try + { + destination.createNewFile(); + FileWriter writer = new FileWriter(destination); + String json_string = array.toJSONString(); + writer.write(json_string); + writer.flush(); + writer.close(); + } + catch (IOException e) + {} + } +} diff --git a/src/main/java/com/redstoner/misc/Main.java b/src/main/java/com/redstoner/misc/Main.java new file mode 100644 index 0000000..b24e532 --- /dev/null +++ b/src/main/java/com/redstoner/misc/Main.java @@ -0,0 +1,36 @@ +package com.redstoner.misc; + +import org.bukkit.plugin.java.JavaPlugin; + +import com.redstoner.annotations.Version; +import com.redstoner.coremods.moduleLoader.ModuleLoader; +import com.redstoner.misc.mysql.MysqlHandler; + +import net.nemez.chatapi.ChatAPI; + +/** Main class. Duh. + * + * @author Pepich */ +@Version(major = 4, minor = 0, revision = 0, compatible = -1) +public class Main extends JavaPlugin +{ + public static JavaPlugin plugin; + + @Override + public void onEnable() + { + plugin = this; + ChatAPI.initialize(this); + // Configger.init(); + MysqlHandler.init(); + ModuleLoader.init(); + // Load modules from config + ModuleLoader.loadFromConfig(); + } + + @Override + public void onDisable() + { + ModuleLoader.disableModules(); + } +} diff --git a/src/main/java/com/redstoner/misc/Utils.java b/src/main/java/com/redstoner/misc/Utils.java new file mode 100644 index 0000000..8186bcb --- /dev/null +++ b/src/main/java/com/redstoner/misc/Utils.java @@ -0,0 +1,149 @@ +package com.redstoner.misc; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.redstoner.annotations.Version; + +/** The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more. + * + * @author Pepich */ +@Version(major = 4, minor = 0, revision = 2, compatible = 1) +public final class Utils +{ + /** The @SimpleDateFormat used for getting the current date. */ + public static SimpleDateFormat dateFormat = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]"); + + /** The Pattern for a UUID*/ + private static final Pattern UUID_pattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"); + private static final Pattern Class_pattern = Pattern.compile(".*\\."); + private static final Pattern NoDolarSign_pattern = Pattern.compile("\\$\\d*"); + + /** Hidden constructor. Do not instantiate UTILS classes! :) */ + private Utils() + {} + + /** This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
+ * If you want to, you can set a message that will be logged to console. Set to null to not log anything.
+ * You can still allow console in the filter to log the original message. + * + * @param prefix The prefix for the message. Set to NULL to let it auto generate. + * @param message the message to be sent around + * @param filter the BroadcastFilter to be applied.
+ * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. + * @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter). + * @return the amount of people that received the message. */ + public static int broadcast(String prefix, String message, BroadcastFilter filter) + { + if (prefix == null) + prefix = "§8[§2" + getCaller() + "§8]: "; + if (filter == null) + { + for (Player p : Bukkit.getOnlinePlayers()) + p.sendMessage(prefix + message); + Bukkit.getConsoleSender().sendMessage(prefix + message); + return Bukkit.getOnlinePlayers().size() + 1; + } + else + { + int count = 0; + for (Player p : Bukkit.getOnlinePlayers()) + if (filter.sendTo(p)) + { + p.sendMessage(prefix + message); + count++; + } + if (filter.sendTo(Bukkit.getConsoleSender())) + { + Bukkit.getConsoleSender().sendMessage(prefix + message); + count++; + } + return count; + } + } + + /** This method will find the next parent caller and return their class name, omitting package names. + * + * @return the Name of the calling class. */ + private static final String getCaller() + { + StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); + String classname = "Utils"; + for (int i = 0; classname.equals("Utils"); i++) + { + classname = Class_pattern.matcher(stackTrace[i].getClassName()).replaceAll(""); + } + return classname; + } + + /** This method will find the next parent caller and return their class name, omitting package names. + * + * @param directCaller used to prevent this method from returning the caller itself. Null if supposed to be ignored. + * @return the name of the calling class. */ + public static final String getCaller(String... directCaller) + { + if (directCaller == null || directCaller.length == 0) + return getCaller(); + StackTraceElement[] stackTrace = (new Exception()).getStackTrace(); + String classname = "Utils"; + List callers = Arrays.asList(directCaller); + for (int i = 0; callers.contains(classname) || classname.equals("Utils"); i++) + { + classname = Class_pattern.matcher(stackTrace[i].getClassName()).replaceAll(""); + } + classname = NoDolarSign_pattern.matcher(classname).replaceAll(""); + return classname; + } + + /** Provides a uniform way of getting the date for all modules. + * + * @return The current date in the format "[dd-mm-yyyy hh:mm:ss]" */ + public static String getDate() + { + Date date = new Date(System.currentTimeMillis()); + return dateFormat.format(date); + } + + /** Provides a uniform way of getting the (display)name of a @CommandSender. + * + * @param sender The @CommandSender to get the name of. + * @return The DisplayName of the @CommandSender or if not a @Player, the name in blue. */ + public static String getName(CommandSender sender) + { + if (sender instanceof Player) + return ((Player) sender).getDisplayName(); + else + return "§9" + sender.getName(); + } + + /** Provides a uniform way of getting the UUID of a @CommandSender. + * + * @param sender The @CommandSender to get the UUID of. + * @return The UUID of the @CommandSender or if not a player, "CONSOLE" in blue. */ + public static String getID(CommandSender sender) + { + String id; + if (sender instanceof Player) + id = ((Player) sender).getUniqueId().toString(); + else + id = "CONSOLE"; + return id; + } + + /** Checks if the string is a UUID. + * + * @param toCheck String to check. + * @return if the string is a UUID. + */ + public static boolean isUUID(String toCheck) + { + return UUID_pattern.matcher(toCheck).matches(); + } +} diff --git a/src/main/java/com/redstoner/misc/VersionHelper.java b/src/main/java/com/redstoner/misc/VersionHelper.java new file mode 100644 index 0000000..e4a9403 --- /dev/null +++ b/src/main/java/com/redstoner/misc/VersionHelper.java @@ -0,0 +1,151 @@ +package com.redstoner.misc; + +import java.lang.annotation.Annotation; + +import com.redstoner.annotations.Version; +import com.redstoner.exceptions.MissingVersionException; + +/** This class can be used to compare modules against the loader version or against each other to prevent dependency issues. + * + * @author Pepich */ +@Version(major = 2, minor = 1, revision = 3, compatible = 0) +public final class VersionHelper +{ + private VersionHelper() + {} + + /** Checks two classes versions for compatibility. + * + * @param base The API to compare to. + * @param module The module to compare. + * @return true, when the module is up to date with the API, or the API supports outdated modules. + * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ + public static boolean isCompatible(Class api, Class module) throws MissingVersionException + { + if (!api.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The API is not annotated with a version."); + if (!module.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The module is not annotated with a version."); + Version apiVersion = api.getAnnotation(Version.class); + Version moduleVersion = module.getAnnotation(Version.class); + return isCompatible(apiVersion, moduleVersion); + } + + /** Checks two classes versions for compatibility. + * + * @param base The API to compare to. + * @param module The module to compare. + * @return true, when the module is up to date with the API, or the API supports outdated modules. + * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ + public static boolean isCompatible(Version apiVersion, Class module) throws MissingVersionException + { + if (!module.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The module is not annotated with a version."); + Version moduleVersion = module.getAnnotation(Version.class); + return isCompatible(apiVersion, moduleVersion); + } + + /** Checks two classes versions for compatibility. + * + * @param base The API to compare to. + * @param module The module to compare. + * @return true, when the module is up to date with the API, or the API supports outdated modules. + * @throws MissingVersionException When one of the parameters is not annotated with a @Version annotation. */ + public static boolean isCompatible(Class api, Version moduleVersion) throws MissingVersionException + { + if (!api.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The API is not annotated with a version."); + Version apiVersion = api.getAnnotation(Version.class); + return isCompatible(apiVersion, moduleVersion); + } + + /** Checks two versions for compatibility. + * + * @param base The API version to compare to. + * @param module The module version to compare. + * @return true, when the module is up to date with the API, or the API supports outdated modules. */ + public static boolean isCompatible(Version apiVersion, Version moduleVersion) + { + if (apiVersion.major() >= moduleVersion.compatible()) + return true; + if (apiVersion.compatible() == -1) + return false; + if (apiVersion.compatible() <= moduleVersion.major()) + return true; + return false; + } + + /** Returns the version of a given class as a String. + * + * @param clazz The class to grab the version number from. + * @return The version number of the class in format major.minor.revision.compatible. + * @throws MissingVersionException If the class is not annotated with @Version. */ + public static String getVersion(Class clazz) throws MissingVersionException + { + if (!clazz.isAnnotationPresent(Version.class)) + throw new MissingVersionException("The given class is not associated with a version."); + Version ver = clazz.getAnnotation(Version.class); + return getString(ver); + } + + /** Returns the String representation of a version. + * + * @param ver The version to be represented. + * @return The String representation. */ + public static String getString(Version ver) + { + return ver.major() + "." + ver.minor() + "." + ver.revision() + "." + ver.compatible(); + } + + public static Version getVersion(String ver) + { + String[] raw = ver.split("\\."); + if (raw.length != 4) + return null; + return VersionHelper.create(Integer.parseInt(raw[0]), Integer.parseInt(raw[1]), Integer.parseInt(raw[2]), + Integer.parseInt(raw[3])); + } + + /** This method creates a new Version to use for compatibility checks. + * + * @param major The major version + * @param minor The minor version + * @param revision The revision + * @param compatible The compatibility tag + * @return */ + public static Version create(int major, int minor, int revision, int compatible) + { + return new Version() + { + @Override + public Class annotationType() + { + return Version.class; + } + + @Override + public int revision() + { + return revision; + } + + @Override + public int minor() + { + return minor; + } + + @Override + public int major() + { + return major; + } + + @Override + public int compatible() + { + return compatible; + } + }; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/Config.java b/src/main/java/com/redstoner/misc/mysql/Config.java new file mode 100644 index 0000000..d403c7b --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/Config.java @@ -0,0 +1,278 @@ +package com.redstoner.misc.mysql; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.redstoner.exceptions.NonSaveableConfigException; +import com.redstoner.misc.Main; + +public class Config +{ + private File file; + private JSONObject config; + private JSONParser parser; + + public Config() + { + file = null; + parser = new JSONParser(); + config = new JSONObject(); + } + + public Config(JSONObject config) + { + this.file = null; + this.parser = new JSONParser(); + this.config = config; + } + + private Config(File file) throws IOException, ParseException + { + this.file = file; + parser = new JSONParser(); + if (file.exists()) + { + config = loadConfig(file); + } + else + { + config = new JSONObject(); + } + } + + public static final Config getConfig(String fileName) throws IOException, ParseException + { + return new Config(new File(Main.plugin.getDataFolder(), fileName)); + } + + public static final Config getConfig(File file) throws IOException, ParseException + { + return new Config(file); + } + + private JSONObject loadConfig(File file) throws IOException, ParseException + { + FileReader reader = new FileReader(file); + return (JSONObject) parser.parse(reader); + } + + @Override + public String toString() + { + return config.toJSONString(); + } + + public JSONObject asObject() + { + return config; + } + + public void save() throws IOException, NonSaveableConfigException + { + if (file == null) + { + throw new NonSaveableConfigException(); + } + PrintWriter writer = new PrintWriter(file); + writer.write(config.toJSONString()); + writer.close(); + } + + public void refresh() throws IOException, ParseException, NonSaveableConfigException + { + if (file == null) + { + throw new NonSaveableConfigException(); + } + loadConfig(file); + } + + public void setFile(String fileName) + { + file = new File(Main.plugin.getDataFolder(), fileName); + } + + public void setFile(File file) + { + this.file = file; + } + + @SuppressWarnings("unchecked") + public void put(String key, String value) + { + config.put(key, value); + } + + @SuppressWarnings("unchecked") + public void put(String key, List value) + { + JSONArray array = new JSONArray(); + for (String entry : value) + { + array.add(entry); + } + config.put(key, array); + } + + @SuppressWarnings("unchecked") + public void putArray(String key, JSONArray value) + { + config.put(key, value); + } + + @SuppressWarnings("unchecked") + public void put(String key, Map value) + { + JSONObject object = new JSONObject(); + for (String valKey : value.keySet()) + { + String valVal = value.get(valKey); + object.put(valKey, valVal); + } + config.put(key, object); + } + + @SuppressWarnings("unchecked") + public void put(String key, JSONObject value) + { + config.put(key, value); + } + + @SuppressWarnings("unchecked") + public void putAll(Map entry) + { + for (String key : entry.keySet()) + { + String value = entry.get(key); + config.put(key, value); + } + } + + public boolean containsKey(String key) + { + return config.containsKey(key); + } + + public String get(String key) + { + if (containsKey(key)) + { + Object value = config.get(key); + if (value instanceof String) + { + return (String) value; + } + } + return null; + } + + public String getOrDefault(String key, String defaultValue) + { + if (containsKey(key)) + { + Object value = config.get(key); + if (value instanceof String) + { + return (String) value; + } + return null; + } + else + { + return defaultValue; + } + } + + @SuppressWarnings("unchecked") + public List getList(String key) + { + if (containsKey(key)) + { + Object value = config.get(key); + if (value instanceof JSONArray) + { + JSONArray array = (JSONArray) value; + List output = new ArrayList(); + for (String entry : (String[]) array.toArray(new String[0])) + { + output.add(entry); + } + return output; + } + } + return null; + } + + public JSONArray getArray(String key) + { + if (containsKey(key)) + { + Object value = config.get(key); + if (value instanceof JSONArray) + { + JSONArray array = (JSONArray) value; + return array; + } + } + return null; + } + + public Map getMap(String key) + { + if (containsKey(key)) + { + Object value = config.get(key); + if (value instanceof JSONObject) + { + JSONObject object = (JSONObject) value; + @SuppressWarnings("unchecked") + Set> entrySet = object.entrySet(); + Map output = new HashMap(); + for (Map.Entry entry : entrySet) + { + output.put(entry.getKey(), entry.getValue()); + } + return output; + } + } + return null; + } + + public JSONObject getObject(String key) + { + if (containsKey(key)) + { + Object value = config.get(key); + if (value instanceof JSONObject) + { + JSONObject object = (JSONObject) value; + return object; + } + } + return null; + } + + public void remove(String key) + { + config.remove(key); + } + + @SuppressWarnings("unchecked") + public Set> getAll() + { + return config.entrySet(); + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/JSONManager.java b/src/main/java/com/redstoner/misc/mysql/JSONManager.java new file mode 100644 index 0000000..ae248d5 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/JSONManager.java @@ -0,0 +1,107 @@ +package com.redstoner.misc.mysql; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.redstoner.misc.Main; + +public class JSONManager +{ + public static Map getConfiguration(String fileName) + { + File file = new File(Main.plugin.getDataFolder(), fileName); + if (!file.exists()) + { + try + { + PrintWriter writer = new PrintWriter(file.getAbsolutePath(), "UTF-8"); + writer.println("{}"); + writer.close(); + } + catch (FileNotFoundException | UnsupportedEncodingException e) + { + e.printStackTrace(); + } + } + try + { + return loadMap(file); + } + catch (IOException | ParseException e) + { + e.printStackTrace(); + return null; + } + } + + public static void saveConfiguration(Map config, String fileName) + { + try + { + saveMap(new File(Main.plugin.getDataFolder(), fileName), config); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + public static void saveList(File file, List entries) throws IOException + { + JSONArray array = new JSONArray(); + array.addAll(entries); + FileWriter writer = new FileWriter(file); + writer.write(array.toJSONString()); + writer.close(); + } + + public static List loadList(File file) throws IOException, ParseException + { + FileReader read = new FileReader(file); + List entries = new ArrayList<>(); + JSONArray array = (JSONArray) new JSONParser().parse(read); + for (Object o : array) + { + entries.add((Serializable) o); + } + return entries; + } + + @SuppressWarnings("unchecked") + public static void saveMap(File file, Map entries) throws IOException + { + JSONObject map = new JSONObject(); + map.putAll(entries); + FileWriter writer = new FileWriter(file); + writer.write(map.toJSONString()); + writer.close(); + } + + public static Map loadMap(File file) throws IOException, ParseException + { + FileReader reader = new FileReader(file); + JSONObject map = (JSONObject) new JSONParser().parse(reader); + Map entries = new HashMap<>(); + for (Object o : map.keySet()) + { + entries.put((Serializable) o, (Serializable) map.get(o)); + } + return entries; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/MysqlHandler.java b/src/main/java/com/redstoner/misc/mysql/MysqlHandler.java new file mode 100644 index 0000000..909d276 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/MysqlHandler.java @@ -0,0 +1,115 @@ +package com.redstoner.misc.mysql; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.json.simple.parser.ParseException; + +import com.redstoner.misc.Main; +import com.redstoner.misc.mysql.elements.MysqlDatabase; + +public class MysqlHandler +{ + public static MysqlHandler INSTANCE; + private String url, username, password; + + public MysqlHandler(String hostname, int port, String username, String password) + { + this.url = "jdbc:mysql://" + hostname + ":" + port + "/"; + this.username = username; + this.password = password; + } + + public static void init() + { + Map mysqlCredentials = new HashMap<>(); + File mysqlCredentialsFile = new File(Main.plugin.getDataFolder(), "mysqlCredentials.json"); + if (mysqlCredentialsFile.exists()) + { + try + { + mysqlCredentials = JSONManager.loadMap(mysqlCredentialsFile); + } + catch (IOException | ParseException e) + { + e.printStackTrace(); + } + } + else + { + Bukkit.getConsoleSender().sendMessage( + ChatColor.RED + "MySQL config does not exist, creating an example one, things might (will) break!"); + mysqlCredentials.put("hostname", "localhost"); + mysqlCredentials.put("port", "3306"); + mysqlCredentials.put("username", "your username here"); + mysqlCredentials.put("password", "your password here"); + try + { + JSONManager.saveMap(mysqlCredentialsFile, mysqlCredentials); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + String hostname = (String) mysqlCredentials.get("hostname"); + int port = Integer.valueOf((String) mysqlCredentials.get("port")); + String username = (String) mysqlCredentials.get("username"); + String password = (String) mysqlCredentials.get("password"); + INSTANCE = new MysqlHandler(hostname, port, username, password); + } + + private Connection getConnection(String databaseName) throws IllegalStateException + { + Connection connection = null; + try + { + connection = DriverManager.getConnection(url + databaseName, username, password); + } + catch (SQLException e) + { + throw new IllegalStateException("Cannot connect to the database!", e); + } + return connection; + } + + public MysqlDatabase getDatabase(String databaseName) + { + return new MysqlDatabase(getConnection(databaseName)); + } + + public List getDatabases() + { + try + { + List databases = new ArrayList<>(); + Connection connection = DriverManager.getConnection(url.substring(0, url.length()), username, password); + DatabaseMetaData metadata = connection.getMetaData(); + ResultSet queryResults = metadata.getCatalogs(); + while (queryResults.next()) + { + String databaseName = queryResults.getString("TABLE_CAT"); + databases.add(new MysqlDatabase(getConnection(databaseName))); + } + connection.close(); + return databases; + } + catch (SQLException e) + { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java b/src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java new file mode 100644 index 0000000..f89a08a --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/MysqlQueryHandler.java @@ -0,0 +1,33 @@ +package com.redstoner.misc.mysql; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class MysqlQueryHandler { + public static ResultSet queryResult(Connection connection, String query) { + try { + Statement statement = connection.createStatement(); + ResultSet results = statement.executeQuery(query); + + return results; + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } + + public static boolean queryNoResult(Connection connection, String query) { + try { + CallableStatement statement = connection.prepareCall(query); + statement.execute(); + + return true; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java b/src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java new file mode 100644 index 0000000..45cb33c --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/elements/ConstraintOperator.java @@ -0,0 +1,24 @@ +package com.redstoner.misc.mysql.elements; + +public enum ConstraintOperator { + LESS_THAN, GREATER_THAN, EQUAL, NOT_EQUAL, LESS_THAN_OR_EQUAL, GREATER_THAN_OR_EQUAL; + + public String toString() { + switch (this) { + case LESS_THAN: + return "<"; + case GREATER_THAN: + return ">"; + case EQUAL: + return "="; + case NOT_EQUAL: + return "!="; + case LESS_THAN_OR_EQUAL: + return "<="; + case GREATER_THAN_OR_EQUAL: + return ">="; + default: + return "="; + } + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java b/src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java new file mode 100644 index 0000000..d651344 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/elements/MysqlConstraint.java @@ -0,0 +1,24 @@ +package com.redstoner.misc.mysql.elements; + +public class MysqlConstraint { + private String fieldName, value; + private ConstraintOperator operator; + + public MysqlConstraint(String fieldName, ConstraintOperator operator, String value) { + this.fieldName = fieldName; + this.operator = operator; + this.value = value; + } + + public String getFieldName() { + return fieldName; + } + + public String getValue() { + return value; + } + + public ConstraintOperator getOperator() { + return operator; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java b/src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java new file mode 100644 index 0000000..91c0fe4 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/elements/MysqlDatabase.java @@ -0,0 +1,90 @@ +package com.redstoner.misc.mysql.elements; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import com.redstoner.misc.mysql.MysqlQueryHandler; + +public class MysqlDatabase { + private Connection connection; + + public MysqlDatabase(Connection connection) { + this.connection = connection; + } + + public String getName() { + try { + return connection.getCatalog(); + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } + + public MysqlTable getTable(String name) { + return new MysqlTable(this, name); + } + + public boolean createTable(String name, MysqlField... description) { + return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE `" + name + "` " + getDescription(description) + ";"); + } + + public boolean createTableIfNotExists(String name, MysqlField... description) { + return MysqlQueryHandler.queryNoResult(connection, "CREATE TABLE IF NOT EXISTS `" + name + "` " + getDescription(description) + ";"); + } + + public boolean dropTable(String name) { + return MysqlQueryHandler.queryNoResult(connection, "DROP TABLE `" + name + "`;"); + } + + public boolean drop() { + return MysqlQueryHandler.queryNoResult(connection, "DROP DATABASE `" + getName() + "`;"); + } + + public List getTables() { + try { + List tables = new ArrayList<>(); + DatabaseMetaData metadata = connection.getMetaData(); + ResultSet queryResults = metadata.getTables(null, null, "%", null); + + while (queryResults.next()) { + tables.add(new MysqlTable(this, queryResults.getString(3))); + } + + return tables; + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } + + protected Connection getConnection() { + return connection; + } + + private String getDescription(MysqlField... description) { + String desc = "("; + + for (int i = 0; i < description.length; i++) { + String nil = ""; + + if (description[i].canBeNull()) { + nil = " NOT NULL"; + } + + desc += "`" + description[i].getName() + "` " + description[i].getType().getName() + nil; + + if (i < description.length - 1) { + desc += ","; + } + } + + desc += ")"; + + return desc; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java b/src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java new file mode 100644 index 0000000..61cba2e --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/elements/MysqlField.java @@ -0,0 +1,33 @@ +package com.redstoner.misc.mysql.elements; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class MysqlField { + private String name; + private MysqlType type; + private boolean canBeNull; + + public MysqlField(String name, MysqlType type, boolean canBeNull) { + this.name = name; + this.type = type; + this.canBeNull = canBeNull; + } + + public MysqlField(String name, String type, boolean canBeNull) { + this.name = name; + this.type = MysqlType.getTypeFromString(type); + this.canBeNull = canBeNull; + } + + public String getName() { + return name; + } + + public MysqlType getType() { + return type; + } + + public boolean canBeNull() { + return canBeNull; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java b/src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java new file mode 100644 index 0000000..6db0769 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/elements/MysqlResult.java @@ -0,0 +1,16 @@ +package com.redstoner.misc.mysql.elements; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class MysqlResult { + private ResultSet results; + + public MysqlResult(ResultSet results) { + this.results = results; + } + + public Object getObject(int columnIndex, Class type) throws SQLException { + return results.getObject(columnIndex, type); + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java b/src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java new file mode 100644 index 0000000..6656fcd --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/elements/MysqlTable.java @@ -0,0 +1,133 @@ +package com.redstoner.misc.mysql.elements; + +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import com.redstoner.misc.mysql.MysqlQueryHandler; + +public class MysqlTable +{ + private MysqlDatabase database; + private String name; + + public MysqlTable(MysqlDatabase database, String name) + { + this.database = database; + this.name = name; + } + + public String getName() + { + return this.name; + } + + public MysqlField[] describe() + { + try + { + List description = new ArrayList<>(); + DatabaseMetaData metadata = database.getConnection().getMetaData(); + ResultSet queryResults = metadata.getColumns(null, null, name, null); + while (queryResults.next()) + { + description.add(new MysqlField(queryResults.getString(4), + queryResults.getString(6).split(" ")[0] + "(" + queryResults.getString(7) + ")", + queryResults.getBoolean(11))); + } + return description.toArray(new MysqlField[0]); + } + catch (SQLException e) + { + e.printStackTrace(); + return null; + } + } + + public boolean insert(String... values) + { + MysqlField[] description = describe(); + if (values.length > 0 && values.length == description.length) + { + String val = "(\"" + String.join("\",\"", values) + "\")"; + return MysqlQueryHandler.queryNoResult(database.getConnection(), + "INSERT INTO `" + name + "` VALUES " + val + ";"); + } + else + { + return false; + } + } + + public Object[] get(String fieldName, MysqlConstraint... constraints) + { + ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), + "SELECT " + fieldName + " FROM `" + name + "`" + getConstraints(constraints) + ";"); + List resObj = new ArrayList<>(); + try + { + while (results.next()) + { + resObj.add(results.getObject(1)); + } + } + catch (SQLException e) + { + e.printStackTrace(); + return new Object[0]; + } + return resObj.toArray(new Object[0]); + } + + public Object[] get(String statement) + { + ResultSet results = MysqlQueryHandler.queryResult(database.getConnection(), statement); + List resObj = new ArrayList<>(); + try + { + while (results.next()) + { + resObj.add(results.getObject(1)); + } + } + catch (SQLException e) + { + e.printStackTrace(); + return new Object[0]; + } + return resObj.toArray(new Object[0]); + } + + public boolean delete(MysqlConstraint... constraints) + { + return MysqlQueryHandler.queryNoResult(database.getConnection(), + "DELETE FROM `" + name + "`" + getConstraints(constraints) + ";"); + } + + public boolean drop() + { + return MysqlQueryHandler.queryNoResult(database.getConnection(), "DROP TABLE `" + name + "`;"); + } + + private String getConstraints(MysqlConstraint... constraints) + { + String cons = ""; + if (constraints.length > 0) + { + cons += " WHERE "; + for (int i = 0; i < constraints.length; i++) + { + MysqlConstraint constraint = constraints[i]; + cons += constraint.getFieldName() + constraint.getOperator().toString() + "\"" + constraint.getValue() + + "\""; + if (i < constraints.length - 1) + { + cons += " AND "; + } + } + } + return cons; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/MysqlType.java b/src/main/java/com/redstoner/misc/mysql/types/MysqlType.java new file mode 100644 index 0000000..86413f9 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/MysqlType.java @@ -0,0 +1,96 @@ +package com.redstoner.misc.mysql.types; + +import com.redstoner.misc.mysql.types.date.Date; +import com.redstoner.misc.mysql.types.date.DateTime; +import com.redstoner.misc.mysql.types.date.Time; +import com.redstoner.misc.mysql.types.date.TimeStamp; +import com.redstoner.misc.mysql.types.date.Year; +import com.redstoner.misc.mysql.types.number.BigInt; +import com.redstoner.misc.mysql.types.number.Decimal; +import com.redstoner.misc.mysql.types.number.Double; +import com.redstoner.misc.mysql.types.number.Float; +import com.redstoner.misc.mysql.types.number.Int; +import com.redstoner.misc.mysql.types.number.MediumInt; +import com.redstoner.misc.mysql.types.number.SmallInt; +import com.redstoner.misc.mysql.types.number.TinyInt; +import com.redstoner.misc.mysql.types.text.Blob; +import com.redstoner.misc.mysql.types.text.Char; +import com.redstoner.misc.mysql.types.text.Enum; +import com.redstoner.misc.mysql.types.text.LongBlob; +import com.redstoner.misc.mysql.types.text.LongText; +import com.redstoner.misc.mysql.types.text.MediumBlob; +import com.redstoner.misc.mysql.types.text.MediumText; +import com.redstoner.misc.mysql.types.text.Set; +import com.redstoner.misc.mysql.types.text.Text; +import com.redstoner.misc.mysql.types.text.TinyText; +import com.redstoner.misc.mysql.types.text.VarChar; + +public abstract class MysqlType +{ + public abstract String getName(); + + public static MysqlType getTypeFromString(String type) + { + String[] splitType = type.split("\\("); + String toSwitch = splitType[0].toUpperCase(); + String value = ""; + if (type.contains("(") && type.endsWith(")")) + { + value = splitType[1].substring(0, splitType[1].length() - 1); + } + switch (toSwitch) + { + case "CHAR": + return new Char(Integer.valueOf(value)); + case "ENUM": + return new Enum(value.replaceAll("'", "").split(",")); + case "VARCHAR": + return new VarChar(Integer.valueOf(value)); + case "SET": + return new Set(value.replaceAll("'", "").split(",")); + case "BLOB": + return new Blob(); + case "TEXT": + return new Text(); + case "MEDIUMBLOB": + return new MediumBlob(); + case "LONGBLOB": + return new LongBlob(); + case "TINYTEXT": + return new TinyText(); + case "MEDIUMTEXT": + return new MediumText(); + case "LONGTEXT": + return new LongText(); + case "INT": + return new Int(Integer.valueOf(value)); + case "TINYINT": + return new TinyInt(Integer.valueOf(value)); + case "SMALLINT": + return new SmallInt(Integer.valueOf(value)); + case "MEDIUMINT": + return new MediumInt(Integer.valueOf(value)); + case "BIGINT": + return new BigInt(Integer.valueOf(value)); + case "BIT": + return new TinyInt(1); + case "FLOAT": + return new Float(); + case "DOUBLE": + return new Double(); + case "DECIMAL": + return new Decimal(); + case "DATE": + return new Date(); + case "DATETIME": + return new DateTime(); + case "TIME": + return new Time(); + case "TIMESTAMP": + return new TimeStamp(); + case "YEAR": + return new Year(); + } + return null; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/Date.java b/src/main/java/com/redstoner/misc/mysql/types/date/Date.java new file mode 100644 index 0000000..9943333 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/date/Date.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.date; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Date extends MysqlType { + @Override + public String getName() { + return "DATE"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/DateTime.java b/src/main/java/com/redstoner/misc/mysql/types/date/DateTime.java new file mode 100644 index 0000000..b4d9623 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/date/DateTime.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.date; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class DateTime extends MysqlType { + @Override + public String getName() { + return "DATETIME"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/Time.java b/src/main/java/com/redstoner/misc/mysql/types/date/Time.java new file mode 100644 index 0000000..4ead72c --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/date/Time.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.date; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Time extends MysqlType { + @Override + public String getName() { + return "TIME"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/TimeStamp.java b/src/main/java/com/redstoner/misc/mysql/types/date/TimeStamp.java new file mode 100644 index 0000000..56205af --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/date/TimeStamp.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.date; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class TimeStamp extends MysqlType { + @Override + public String getName() { + return "TIMESTAMP"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/date/Year.java b/src/main/java/com/redstoner/misc/mysql/types/date/Year.java new file mode 100644 index 0000000..4c2ce1a --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/date/Year.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.date; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Year extends MysqlType { + @Override + public String getName() { + return "YEAR"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/BigInt.java b/src/main/java/com/redstoner/misc/mysql/types/number/BigInt.java new file mode 100644 index 0000000..71086fd --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/BigInt.java @@ -0,0 +1,12 @@ +package com.redstoner.misc.mysql.types.number; + +public class BigInt extends Int { + public BigInt(int maxSize) { + super(maxSize); + } + + @Override + public String getName() { + return "BIG" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Decimal.java b/src/main/java/com/redstoner/misc/mysql/types/number/Decimal.java new file mode 100644 index 0000000..4e4dbb6 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/Decimal.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.number; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Decimal extends MysqlType { + @Override + public String getName() { + return "DECIMAL"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Double.java b/src/main/java/com/redstoner/misc/mysql/types/number/Double.java new file mode 100644 index 0000000..b4b1dda --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/Double.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.number; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Double extends MysqlType { + @Override + public String getName() { + return "DOUBLE"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Float.java b/src/main/java/com/redstoner/misc/mysql/types/number/Float.java new file mode 100644 index 0000000..ea3047e --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/Float.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.number; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Float extends MysqlType { + @Override + public String getName() { + return "FLOAT"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/Int.java b/src/main/java/com/redstoner/misc/mysql/types/number/Int.java new file mode 100644 index 0000000..4256f7b --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/Int.java @@ -0,0 +1,16 @@ +package com.redstoner.misc.mysql.types.number; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Int extends MysqlType { + private int maxSize; + + public Int(int maxSize) { + this.maxSize = maxSize; + } + + @Override + public String getName() { + return "INT(" + maxSize + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/MediumInt.java b/src/main/java/com/redstoner/misc/mysql/types/number/MediumInt.java new file mode 100644 index 0000000..fbcb0f4 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/MediumInt.java @@ -0,0 +1,12 @@ +package com.redstoner.misc.mysql.types.number; + +public class MediumInt extends Int { + public MediumInt(int maxSize) { + super(maxSize); + } + + @Override + public String getName() { + return "MEDIUM" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/SmallInt.java b/src/main/java/com/redstoner/misc/mysql/types/number/SmallInt.java new file mode 100644 index 0000000..01bf97d --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/SmallInt.java @@ -0,0 +1,12 @@ +package com.redstoner.misc.mysql.types.number; + +public class SmallInt extends Int { + public SmallInt(int maxSize) { + super(maxSize); + } + + @Override + public String getName() { + return "SMALL" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/number/TinyInt.java b/src/main/java/com/redstoner/misc/mysql/types/number/TinyInt.java new file mode 100644 index 0000000..63ad700 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/number/TinyInt.java @@ -0,0 +1,12 @@ +package com.redstoner.misc.mysql.types.number; + +public class TinyInt extends Int { + public TinyInt(int maxSize) { + super(maxSize); + } + + @Override + public String getName() { + return "TINY" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Blob.java b/src/main/java/com/redstoner/misc/mysql/types/text/Blob.java new file mode 100644 index 0000000..d56ee45 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/Blob.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.text; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Blob extends MysqlType { + @Override + public String getName() { + return "BLOB"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Char.java b/src/main/java/com/redstoner/misc/mysql/types/text/Char.java new file mode 100644 index 0000000..ece068c --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/Char.java @@ -0,0 +1,16 @@ +package com.redstoner.misc.mysql.types.text; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Char extends MysqlType { + private int size; + + public Char(int size) { + this.size = size; + } + + @Override + public String getName() { + return "CHAR(" + size + ")"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Enum.java b/src/main/java/com/redstoner/misc/mysql/types/text/Enum.java new file mode 100644 index 0000000..e68476d --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/Enum.java @@ -0,0 +1,27 @@ +package com.redstoner.misc.mysql.types.text; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Enum extends MysqlType { + private String[] possibleValues; + + public Enum(String... possibleValues) { + this.possibleValues = possibleValues; + } + + @Override + public String getName() { + String name = "ENUM("; + + for (int i = 0; i < possibleValues.length; i++) { + name += "'" + possibleValues[i] + "'"; + + if (i != possibleValues.length - 1) { + name += ","; + } + } + + return name + ")"; + } + +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/LongBlob.java b/src/main/java/com/redstoner/misc/mysql/types/text/LongBlob.java new file mode 100644 index 0000000..802caed --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/LongBlob.java @@ -0,0 +1,8 @@ +package com.redstoner.misc.mysql.types.text; + +public class LongBlob extends Blob { + @Override + public String getName() { + return "LONG" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/LongText.java b/src/main/java/com/redstoner/misc/mysql/types/text/LongText.java new file mode 100644 index 0000000..5149ed2 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/LongText.java @@ -0,0 +1,8 @@ +package com.redstoner.misc.mysql.types.text; + +public class LongText extends Text { + @Override + public String getName() { + return "LONG" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/MediumBlob.java b/src/main/java/com/redstoner/misc/mysql/types/text/MediumBlob.java new file mode 100644 index 0000000..6ae25a7 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/MediumBlob.java @@ -0,0 +1,8 @@ +package com.redstoner.misc.mysql.types.text; + +public class MediumBlob extends Blob { + @Override + public String getName() { + return "MEDIUM" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/MediumText.java b/src/main/java/com/redstoner/misc/mysql/types/text/MediumText.java new file mode 100644 index 0000000..a0f6525 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/MediumText.java @@ -0,0 +1,8 @@ +package com.redstoner.misc.mysql.types.text; + +public class MediumText extends Text { + @Override + public String getName() { + return "MEDIUM" + super.getName(); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Set.java b/src/main/java/com/redstoner/misc/mysql/types/text/Set.java new file mode 100644 index 0000000..4e12ce6 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/Set.java @@ -0,0 +1,27 @@ +package com.redstoner.misc.mysql.types.text; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Set extends MysqlType { + private String[] possibleValues; + + public Set(String... possibleValues) { + this.possibleValues = possibleValues; + } + + @Override + public String getName() { + String name = "SET("; + + for (int i = 0; i < possibleValues.length; i++) { + name += "'" + possibleValues[i] + "'"; + + if (i != possibleValues.length - 1) { + name += ","; + } + } + + return name + ")"; + } + +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/Text.java b/src/main/java/com/redstoner/misc/mysql/types/text/Text.java new file mode 100644 index 0000000..7d1a38c --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/Text.java @@ -0,0 +1,10 @@ +package com.redstoner.misc.mysql.types.text; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class Text extends MysqlType { + @Override + public String getName() { + return "TEXT"; + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/TinyText.java b/src/main/java/com/redstoner/misc/mysql/types/text/TinyText.java new file mode 100644 index 0000000..e78160c --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/TinyText.java @@ -0,0 +1,8 @@ +package com.redstoner.misc.mysql.types.text; + +public class TinyText extends Text { + @Override + public String getName() { + return "TINY" + super.getName(); + } +} diff --git a/src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java b/src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java new file mode 100644 index 0000000..cb28ad1 --- /dev/null +++ b/src/main/java/com/redstoner/misc/mysql/types/text/VarChar.java @@ -0,0 +1,16 @@ +package com.redstoner.misc.mysql.types.text; + +import com.redstoner.misc.mysql.types.MysqlType; + +public class VarChar extends MysqlType { + private int maxSize; + + public VarChar(int maxSize) { + this.maxSize = maxSize; + } + + @Override + public String getName() { + return "VARCHAR(" + maxSize + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/modules/CoreModule.java b/src/main/java/com/redstoner/modules/CoreModule.java new file mode 100644 index 0000000..9f71557 --- /dev/null +++ b/src/main/java/com/redstoner/modules/CoreModule.java @@ -0,0 +1,24 @@ +package com.redstoner.modules; + +import com.redstoner.annotations.Version; + +/** This class shall be used for "CoreModules", which are acting on a lower level than modules and are also exempted from being disabled or reloaded on the go.
+ * Please note that CoreModules will not be known to the ModuleLoader itself!
+ * Examples are the ModuleLoader and the Debugger. + * + * @author Pepich */ +@Version(major = 2, minor = 0, revision = 0, compatible = -1) +public interface CoreModule extends Module +{ + /** Core modules don't need to be enabled. */ + @Override + public default boolean onEnable() + { + return true; + } + + /** Core modules don't need to be disabled. */ + @Override + public default void onDisable() + {} +} diff --git a/src/main/java/com/redstoner/modules/Module.java b/src/main/java/com/redstoner/modules/Module.java new file mode 100644 index 0000000..1c89e15 --- /dev/null +++ b/src/main/java/com/redstoner/modules/Module.java @@ -0,0 +1,54 @@ +package com.redstoner.modules; + +import com.redstoner.annotations.Version; +import com.redstoner.coremods.moduleLoader.ModuleLoader; + +/** Interface for the Module class. Modules must always have an empty constructor to be invoked by the ModuleLoader. + * + * @author Pepich */ +@Version(major = 4, minor = 0, revision = 0, compatible = 0) +public interface Module +{ + /** Will be called when the module gets enabled. */ + public default boolean onEnable() + { + return true; + } + + /** This methods gets called after all modules were enabled, please use this method to register commands and similar.
+ * It will only get called if and only if the module was successfully enabled. */ + public default void postEnable() + {} + + /** Will be called when the module gets disabled. */ + public default void onDisable() + {} + + /** Gets called on registration of the module, when this option is selected for command registration + * + * @return The String used for the CommandManager to register the commands. */ + public default String getCommandString() + { + return null; + } + + public default ModuleLogger getLogger() + { + return ModuleLoader.getModuleLogger(this); + } + + /** This method gets run the very first time a module gets loaded. You can use this to set up file structures or background data. */ + public default void firstLoad() + {} + + /** This method gets run every time a module gets loaded and its version has changed. + * + * @param old The version of the previous module. */ + public default void migrate(Version old) + {} + + default void setPrefix(final String name) + { + getLogger().setName(name); + } +} diff --git a/src/main/java/com/redstoner/modules/ModuleLogger.java b/src/main/java/com/redstoner/modules/ModuleLogger.java new file mode 100644 index 0000000..8141976 --- /dev/null +++ b/src/main/java/com/redstoner/modules/ModuleLogger.java @@ -0,0 +1,76 @@ +package com.redstoner.modules; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import com.redstoner.annotations.Version; + +import net.nemez.chatapi.ChatAPI; +import net.nemez.chatapi.click.Message; + +@Version(major = 4, minor = 0, revision = 0, compatible = -1) +public class ModuleLogger +{ + public static final String PREFIX_WARN = "§8[§eWARN§8]:§7 "; + public static final String PREFIX_ERROR = "§8[§cERROR§8]:§7 "; + + private String name; + + public ModuleLogger(final String name) + { + this.name = name; + } + + public void info(final String message) + { + Bukkit.getConsoleSender().sendMessage(getPrefix() + ChatAPI.colorify(null, message)); + } + + public void warn(final String message) + { + Bukkit.getConsoleSender().sendMessage(PREFIX_WARN + getPrefix() + ChatAPI.colorify(null, message)); + } + + public void error(final String message) + { + Bukkit.getConsoleSender().sendMessage(PREFIX_ERROR + getPrefix() + ChatAPI.colorify(null, message)); + } + + public void message(final CommandSender recipient, final String... message) + { + message(recipient, false, message); + } + + public void message(final CommandSender recipient, final boolean error, final String... message) + { + Message m = new Message(recipient, null); + if (message.length == 1) + m.appendText(getPrefix(error) + message[0]); + else + { + m.appendText(getHeader()); + m.appendText("&7" + String.join("\n&7", message)); + } + m.send(); + } + + public String getPrefix() + { + return getPrefix(false); + } + + public String getPrefix(final boolean error) + { + return "§8[§" + (error ? 'c' : '2') + name + "§8]§7 "; + } + + public String getHeader() + { + return "§2--=[ " + name + " ]=--\n"; + } + + protected final void setName(final String name) + { + this.name = name; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..5a3ff61 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,5 @@ +name: ModuleLoader +version: 4.0.0 +authors: [pepich1851] +main: com.redstoner.misc.Main +softdepend: [Vault] \ No newline at end of file -- cgit v1.2.3 From 41741bebc47ddcdc4ff62a2b2af0cf4c50480833 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 7 Nov 2018 17:47:29 +0100 Subject: gitignore + created gradle build file and moved manifest props into it --- .gitignore | 2 ++ build.gradle | 33 +++++++++++++++++++++++++++++++++ manifest.mf | 3 --- 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 build.gradle delete mode 100644 manifest.mf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f06dfad --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.gradle +build \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..08dc139 --- /dev/null +++ b/build.gradle @@ -0,0 +1,33 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + classpath "com.github.jengelman.gradle.plugins:shadow:4.0.2" + } +} + +apply plugin: "com.github.johnrengelman.shadow" +apply plugin: "java" + +repositories { + jcenter() + maven { url "https://jitpack.io" } + + maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" } + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } +} + +dependencies { + implementation "com.github.RedstonerServer:CommandManager:master-SNAPSHOT" + implementation "com.github.RedstonerServer:ChatAPI:master-SNAPSHOT" + implementation "com.github.RedstonerServer:ChestAPI:master-SNAPSHOT" + + compileOnly 'org.spigotmc:spigot-api:1.13.1-R0.1-SNAPSHOT' +} + +jar { + manifest { + attributes "Class-Path": "../lib/CommandManager.jar ../lib/ChatAPI.jar ../lib/ChestAPI.jar" + } +} \ No newline at end of file diff --git a/manifest.mf b/manifest.mf deleted file mode 100644 index c8b23f2..0000000 --- a/manifest.mf +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Class-Path: ../lib/CommandManager.jar ../lib/ChatAPI.jar ../lib/ChestAPI.jar - -- cgit v1.2.3 From f2a6c967ba6b32a267b58989cd9379aa964db274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Sat, 10 Nov 2018 21:26:36 +0100 Subject: Added stuff to gitignore --- .gitignore | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f06dfad..0c9a815 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ .gradle -build \ No newline at end of file +.classpath +.project + +/.settings/ + +/build/ +/bin/ -- cgit v1.2.3 From 919d4870e5dfb00eb5d2fb0efc5b109fe62340f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Sat, 10 Nov 2018 21:26:57 +0100 Subject: Added the sourceJar gradle task --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 08dc139..aa99102 100644 --- a/build.gradle +++ b/build.gradle @@ -30,4 +30,9 @@ jar { manifest { attributes "Class-Path": "../lib/CommandManager.jar ../lib/ChatAPI.jar ../lib/ChestAPI.jar" } +} + +task sourceJar(type: Jar, dependsOn: classes) { + classifier 'sources' + from sourceSets.main.allSource } \ No newline at end of file -- cgit v1.2.3 From d838bc4963a22b7301d72b861486ed4c9174c704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Tue, 13 Nov 2018 23:11:34 +0100 Subject: Updated spigot to 1.13.2 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index aa99102..bd7d0bb 100644 --- a/build.gradle +++ b/build.gradle @@ -23,7 +23,7 @@ dependencies { implementation "com.github.RedstonerServer:ChatAPI:master-SNAPSHOT" implementation "com.github.RedstonerServer:ChestAPI:master-SNAPSHOT" - compileOnly 'org.spigotmc:spigot-api:1.13.1-R0.1-SNAPSHOT' + compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' } jar { @@ -35,4 +35,4 @@ jar { task sourceJar(type: Jar, dependsOn: classes) { classifier 'sources' from sourceSets.main.allSource -} \ No newline at end of file +} -- cgit v1.2.3 From 9326b93fbbf75d997b0765a152994a1970f9abc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Wed, 14 Nov 2018 00:43:38 +0100 Subject: Moved ModuleLoader command file to resources --- .../coremods/moduleLoader/ModuleLoader.cmd | 34 ---------------------- .../coremods/moduleLoader/ModuleLoader.cmd | 34 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 34 deletions(-) delete mode 100644 src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd create mode 100644 src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd deleted file mode 100644 index eadeeb7..0000000 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd +++ /dev/null @@ -1,34 +0,0 @@ -command modules { - [empty] { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - list { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - -v { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listv; - } - list -v { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listv; - } - load [string:name...] { - help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run load name; - type console; - } - unload [string:name...] { - help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run unload name; - type console; - } -} \ No newline at end of file diff --git a/src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd new file mode 100644 index 0000000..eadeeb7 --- /dev/null +++ b/src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd @@ -0,0 +1,34 @@ +command modules { + [empty] { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run list; + } + list { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run list; + } + -v { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run listv; + } + list -v { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run listv; + } + load [string:name...] { + help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; + perm moduleloader.modules.admin; + run load name; + type console; + } + unload [string:name...] { + help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; + perm moduleloader.modules.admin; + run unload name; + type console; + } +} \ No newline at end of file -- cgit v1.2.3 From 0ef0d4f74ef17c7a7dabf118248f14e4843edd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Wed, 14 Nov 2018 00:43:55 +0100 Subject: Added .idea to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0c9a815..0e1715c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .gradle .classpath .project +.idea /.settings/ -- cgit v1.2.3 From da695a7fc0928b3fdf7a5d47a755d64b8818fa39 Mon Sep 17 00:00:00 2001 From: Minenash Date: Tue, 11 Dec 2018 18:41:11 -0500 Subject: Added ChatAPI Message in broadcasts --- src/main/java/com/redstoner/misc/Utils.java | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/main/java/com/redstoner/misc/Utils.java b/src/main/java/com/redstoner/misc/Utils.java index 8186bcb..d950d67 100644 --- a/src/main/java/com/redstoner/misc/Utils.java +++ b/src/main/java/com/redstoner/misc/Utils.java @@ -12,6 +12,9 @@ import org.bukkit.entity.Player; import com.redstoner.annotations.Version; +import net.nemez.chatapi.ChatAPI; +import net.nemez.chatapi.click.Message; + /** The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more. * * @author Pepich */ @@ -69,6 +72,45 @@ public final class Utils } } + /** This method broadcasts a message to all players and console that are allowed by the filter. Set the filter to NULL to broadcast to everyone.
+ * If you want to, you can set a message that will be logged to console. Set to null to not log anything.
+ * You can still allow console in the filter to log the original message. + * + * @param prefix The prefix for the message. Set to NULL to let it auto generate. + * @param message the message to be sent around + * @param filter the BroadcastFilter to be applied.
+ * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient. + * @param logmessage the log message to appear in console. Set to null to not log this (you can still log the original message by returning true in the filter). + */ + public static int broadcast(String prefix, Message message, BroadcastFilter filter) + { + if (prefix == null) + prefix = "§8[§2" + getCaller() + "§8]: "; + if (filter == null) + { + for (Player p : Bukkit.getOnlinePlayers()) + ChatAPI.createMessage(p).appendText(prefix).appendMessage(message).send(); + Bukkit.getConsoleSender().sendMessage(prefix + message); + return Bukkit.getOnlinePlayers().size() + 1; + } + else + { + int count = 0; + for (Player p : Bukkit.getOnlinePlayers()) + if (filter.sendTo(p)) + { + ChatAPI.createMessage(p).appendText(prefix).appendMessage(message).send(); + count++; + } + if (filter.sendTo(Bukkit.getConsoleSender())) + { + Bukkit.getConsoleSender().sendMessage(prefix + message); + count++; + } + return count; + } + } + /** This method will find the next parent caller and return their class name, omitting package names. * * @return the Name of the calling class. */ -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 -- cgit v1.2.3 From 82fbf34f3ae12c59d27b516c476e938f33298e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Sat, 15 Dec 2018 22:08:28 +0100 Subject: Added getPlugin function --- src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java index b4fbbe4..062bda2 100644 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -33,6 +33,7 @@ import com.redstoner.modules.Module; import com.redstoner.modules.ModuleLogger; import net.nemez.chatapi.click.Message; +import org.bukkit.plugin.java.JavaPlugin; /** The module loader, mother of all modules. Responsible for loading and taking care of all modules. * @@ -733,4 +734,8 @@ public final class ModuleLoader implements CoreModule e.printStackTrace(); } } + + public static JavaPlugin getPlugin() { + return Main.plugin; + } } -- cgit v1.2.3 From f0713d781ad98a50f3a0e8fc58517269537a37e2 Mon Sep 17 00:00:00 2001 From: Minenash Date: Fri, 28 Dec 2018 12:53:24 -0500 Subject: Added Descriptor Files and redid `/modules [list]` --- .../coremods/moduleLoader/ModuleLoader.cmd | 24 ++++ .../coremods/moduleLoader/ModuleLoader.java | 124 ++++++++++++--------- src/main/java/com/redstoner/misc/ModuleInfo.java | 81 ++++++++++++++ .../coremods/moduleLoader/ModuleLoader.cmd | 34 ------ 4 files changed, 178 insertions(+), 85 deletions(-) create mode 100644 src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd create mode 100644 src/main/java/com/redstoner/misc/ModuleInfo.java delete mode 100644 src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd new file mode 100644 index 0000000..4e06bd0 --- /dev/null +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd @@ -0,0 +1,24 @@ +command modules { + [empty] { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run list; + } + list { + help Lists all modules. Color indicates status: §aENABLED §cDISABLED; + perm moduleloader.modules.list; + run list; + } + load [string:name...] { + help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; + perm moduleloader.modules.admin; + run load name; + type console; + } + unload [string:name...] { + help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; + perm moduleloader.modules.admin; + run unload name; + type console; + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java index 062bda2..4281d58 100644 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -1,6 +1,7 @@ package com.redstoner.coremods.moduleLoader; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -9,6 +10,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -18,6 +20,7 @@ import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; import com.nemez.cmdmgr.Command; import com.nemez.cmdmgr.Command.AsyncType; @@ -25,15 +28,14 @@ import com.nemez.cmdmgr.CommandManager; import com.redstoner.annotations.AutoRegisterListener; import com.redstoner.annotations.Commands; import com.redstoner.annotations.Version; -import com.redstoner.exceptions.MissingVersionException; import com.redstoner.misc.Main; +import com.redstoner.misc.ModuleInfo; import com.redstoner.misc.VersionHelper; import com.redstoner.modules.CoreModule; import com.redstoner.modules.Module; import com.redstoner.modules.ModuleLogger; import net.nemez.chatapi.click.Message; -import org.bukkit.plugin.java.JavaPlugin; /** The module loader, mother of all modules. Responsible for loading and taking care of all modules. * @@ -43,6 +45,8 @@ public final class ModuleLoader implements CoreModule { private static ModuleLoader instance; private static final HashMap modules = new HashMap<>(); + private static HashMap moduleInfos = new HashMap<>(); + private static HashMap> categorizes = new HashMap<>(); private static URL[] urls; private static URLClassLoader mainLoader; private static HashMap loaders = new HashMap<>(); @@ -71,7 +75,9 @@ public final class ModuleLoader implements CoreModule { if (instance == null) instance = new ModuleLoader(); - loggers.put(instance, new ModuleLogger("ModuleLoader")); + ModuleInfo info = new ModuleInfo(ModuleLoader.class.getResourceAsStream("module.info"), instance); + moduleInfos.put(instance, info); + loggers.put(instance, new ModuleLogger(info.getDisplayName())); CommandManager.registerCommand(ModuleLoader.class.getResourceAsStream("ModuleLoader.cmd"), instance, Main.plugin); } @@ -234,7 +240,33 @@ public final class ModuleLoader implements CoreModule { try { - loggers.put(module, new ModuleLogger(module.getClass().getSimpleName())); + String basePath = "plugins/ModuleLoader/classes/" + module.getClass().getName().replace(".", "/"); + + InputStream file; + try { + file = new FileInputStream( + new File(basePath.substring(0, basePath.lastIndexOf('/')+1) + "module.info")); + } + catch(Exception e) { + file = null; + } + + ModuleInfo info = new ModuleInfo(file, module); + + moduleInfos.put(module, info); + + String category = info.getCategory(); + if (!categorizes.containsKey(category)) + categorizes.put(category, new ArrayList<>(Arrays.asList(module))); + else { + List modsInCat = categorizes.get(category); + modsInCat.add(module); + categorizes.put(category, modsInCat); + } + + loggers.put(module, new ModuleLogger(info.getDisplayName())); + + if (module.onEnable()) { modules.put(module, true); @@ -242,9 +274,9 @@ public final class ModuleLoader implements CoreModule module.firstLoad(); else if (!VersionHelper.getVersion(module.getClass()).equals(VersionHelper.getString(oldVersion))) module.migrate(oldVersion); - if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 3), module.getClass())) + if (VersionHelper.isCompatible(VersionHelper.create(5, 0, 0, 3), module.getClass())) module.postEnable(); - if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 4), module.getClass())) + if (VersionHelper.isCompatible(VersionHelper.create(5, 0, 0, 4), module.getClass())) { Commands ann = module.getClass().getAnnotation(Commands.class); if (ann != null) @@ -289,50 +321,31 @@ public final class ModuleLoader implements CoreModule @Command(hook = "list", async = AsyncType.ALWAYS) public boolean listModulesCommand(CommandSender sender) { - Message m = new Message(sender, null); - m.appendText(getLogger().getHeader()); - m.appendText("§2Modules:\n&e"); - Module[] modules = ModuleLoader.modules.keySet().toArray(new Module[] {}); - for (int i = 0; i < modules.length; i++) - { - Module module = modules[i]; - String[] classPath = module.getClass().getName().split("\\."); - String classname = classPath[classPath.length - 1]; - m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname); - if (i + 1 < modules.length) - m.appendText("§7, "); - } - m.send(); - return true; - } - - /** This method lists all modules to the specified CommandSender. The modules will be color coded correspondingly to their enabled status. - * - * @param sender The person to send the info to, usually the issuer of the command or the console sender. - * @return true. */ - @Command(hook = "listv", async = AsyncType.ALWAYS) - public boolean listModulesCommandVersion(CommandSender sender) - { - Message m = new Message(sender, null); - m.appendText(getLogger().getHeader()); - m.appendText("§2Modules:\n&e"); - Module[] modules = ModuleLoader.modules.keySet().toArray(new Module[] {}); - for (int i = 0; i < modules.length; i++) - { - Module module = modules[i]; - String[] classPath = module.getClass().getName().split("\\."); - String classname = classPath[classPath.length - 1]; - try - { - m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname + "§e(" - + VersionHelper.getVersion(module.getClass()) + ")"); - } - catch (MissingVersionException e) - { - m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname + "§c" + "(Unknown Version)"); - } - if (i + 1 < modules.length) - m.appendText("§7, "); + boolean hasCategorys = hasCategories(); + Message m = new Message(sender, null); + ModuleInfo ml_info = moduleInfos.get(instance); + + m.appendText("§2--=[ ") + .appendTextHover("§2" + ml_info.getDisplayName(), ml_info.getModuleInfoHover()) + .appendText("§2 ]=--\nModules:\n"); + + for (String cat: categorizes.keySet()) { + if (hasCategorys) + m.appendText("\n&7" + cat + ":\n"); + + int curModule = 1; + List mods = categorizes.get(cat); + for (Module mod : mods) { + + ModuleInfo info = moduleInfos.get(mod); + m.appendTextHover((modules.get(mod) ? "§a" : "§c") + info.getDisplayName(), info.getModuleInfoHover()); + + if (curModule != mods.size()) + m.appendText("&7, "); + curModule++; + } + m.appendText("\n"); + } m.send(); return true; @@ -524,6 +537,9 @@ public final class ModuleLoader implements CoreModule disableModule(m); instance.getLogger().info("Disabled module, overriding the implementation"); modules.remove(m); + categorizes.get(moduleInfos.get(m).getCategory()).remove(m); + moduleInfos.remove(m); + try { if (loaders.containsKey(m)) @@ -615,6 +631,8 @@ public final class ModuleLoader implements CoreModule instance.getLogger().info("Attempting to disable module properly:"); disableModule(m); modules.remove(m); + categorizes.get(moduleInfos.get(m).getCategory()).remove(m); + moduleInfos.remove(m); instance.getLogger().info("Disabled module."); return true; } @@ -734,8 +752,12 @@ public final class ModuleLoader implements CoreModule e.printStackTrace(); } } - + public static JavaPlugin getPlugin() { return Main.plugin; } + + public static boolean hasCategories() { + return !(categorizes.size() == 1 && categorizes.containsKey("Other")); + } } diff --git a/src/main/java/com/redstoner/misc/ModuleInfo.java b/src/main/java/com/redstoner/misc/ModuleInfo.java new file mode 100644 index 0000000..e96e813 --- /dev/null +++ b/src/main/java/com/redstoner/misc/ModuleInfo.java @@ -0,0 +1,81 @@ +package com.redstoner.misc; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import com.redstoner.coremods.moduleLoader.ModuleLoader; +import com.redstoner.exceptions.MissingVersionException; +import com.redstoner.modules.Module; + +public class ModuleInfo { + + private String simpleName; + private String displayName; + private String category; + private String description; + private String version; + + private String warning; + + public ModuleInfo(InputStream descriptor, Module module) { + try { + InputStreamReader reader = new InputStreamReader(descriptor); + FileConfiguration config = YamlConfiguration.loadConfiguration(reader); + + displayName = config.getString("displayName"); + category = config.getString("category"); + description = config.getString("description"); + } + catch (Exception e) { + warning = "Descriptor file could not be loaded, using the class's name."; + } + + simpleName = module.getClass().getSimpleName(); + + if (displayName == null) + displayName = simpleName; + + if (category == null) + category = "Other"; + + try { + version = VersionHelper.getVersion(module.getClass()); + } catch (MissingVersionException e) {} + } + + public String getSimpleName() { + return simpleName; + } + + public String getDisplayName() { + return displayName; + } + + public String getCategory() { + return category; + } + + public String getDescription() { + return description; + } + + public String getWarning() { + return warning; + } + + public String getVersion() { + return version; + } + + public String getModuleInfoHover() { + return "&8&o" + getSimpleName() + "\n" + + "&r&e" + (getVersion() == null? "&cVersion Missing" : getVersion()) + + "&r&9" + (ModuleLoader.hasCategories()? "\n" + getCategory() : "") + + "&r&7" + (getDescription() == null? "" : "\n\n" + getDescription()); + } + + +} diff --git a/src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd b/src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd deleted file mode 100644 index eadeeb7..0000000 --- a/src/main/resources/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd +++ /dev/null @@ -1,34 +0,0 @@ -command modules { - [empty] { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - list { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run list; - } - -v { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listv; - } - list -v { - help Lists all modules. Color indicates status: §aENABLED §cDISABLED; - perm moduleloader.modules.list; - run listv; - } - load [string:name...] { - help (Re)-Loads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run load name; - type console; - } - unload [string:name...] { - help Unloads a module. WARNING: Handle with care! This has direct affect on code being executed. This command will temporarily halt the main thread until the class loading operation was completed.; - perm moduleloader.modules.admin; - run unload name; - type console; - } -} \ No newline at end of file -- cgit v1.2.3 From 57998e85502d116df2d9a780a7303947ecca85cc Mon Sep 17 00:00:00 2001 From: Minenash Date: Fri, 28 Dec 2018 13:01:52 -0500 Subject: Added prefix for logger's info --- src/main/java/com/redstoner/modules/ModuleLogger.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/redstoner/modules/ModuleLogger.java b/src/main/java/com/redstoner/modules/ModuleLogger.java index 8141976..11d71b6 100644 --- a/src/main/java/com/redstoner/modules/ModuleLogger.java +++ b/src/main/java/com/redstoner/modules/ModuleLogger.java @@ -13,6 +13,7 @@ public class ModuleLogger { public static final String PREFIX_WARN = "§8[§eWARN§8]:§7 "; public static final String PREFIX_ERROR = "§8[§cERROR§8]:§7 "; + public static final String PREFIX_INFO = "§8[§fINFO§8]:§7 "; private String name; @@ -23,7 +24,7 @@ public class ModuleLogger public void info(final String message) { - Bukkit.getConsoleSender().sendMessage(getPrefix() + ChatAPI.colorify(null, message)); + Bukkit.getConsoleSender().sendMessage(PREFIX_INFO + getPrefix() + ChatAPI.colorify(null, message)); } public void warn(final String message) -- cgit v1.2.3 From 47e0796eff750e30a75ee0045988a1665ed2e87e Mon Sep 17 00:00:00 2001 From: Minenash Date: Fri, 28 Dec 2018 15:33:20 -0500 Subject: Now only looks for the info file if the module has a major version of 5 --- .../coremods/moduleLoader/ModuleLoader.java | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java index 4281d58..8b3ca6f 100644 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -240,18 +240,20 @@ public final class ModuleLoader implements CoreModule { try { - String basePath = "plugins/ModuleLoader/classes/" + module.getClass().getName().replace(".", "/"); + InputStream infoFile = null; - InputStream file; - try { - file = new FileInputStream( - new File(basePath.substring(0, basePath.lastIndexOf('/')+1) + "module.info")); - } - catch(Exception e) { - file = null; - } + if (VersionHelper.isCompatible(VersionHelper.create(5, 0, 0, 5), module.getClass())) { + String basePath = "plugins/ModuleLoader/classes/" + module.getClass().getName().replace(".", "/"); - ModuleInfo info = new ModuleInfo(file, module); + try { + infoFile = new FileInputStream( + new File(basePath.substring(0, basePath.lastIndexOf('/')+1) + "module.info")); + } + catch(Exception e) { + infoFile = null; + } + } + ModuleInfo info = new ModuleInfo(infoFile, module); moduleInfos.put(module, info); -- cgit v1.2.3 From 259c4b8d376e93087a8fb025fadeea27821c9fab Mon Sep 17 00:00:00 2001 From: Minenash Date: Sun, 30 Dec 2018 15:54:33 -0500 Subject: Fixed Version --- src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java index 8b3ca6f..109fc27 100644 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -40,7 +40,7 @@ import net.nemez.chatapi.click.Message; /** The module loader, mother of all modules. Responsible for loading and taking care of all modules. * * @author Pepich */ -@Version(major = 4, minor = 0, revision = 1, compatible = 4) +@Version(major = 5, minor = 0, revision = 0, compatible = 5) public final class ModuleLoader implements CoreModule { private static ModuleLoader instance; -- cgit v1.2.3 From bf0b5994f0db5e3550583de49daf6b489d63c790 Mon Sep 17 00:00:00 2001 From: Minenash Date: Sat, 12 Jan 2019 18:05:11 -0500 Subject: Fixed broadcast(String, Message, BroadcastFilter) sending to console --- src/main/java/com/redstoner/misc/Utils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/redstoner/misc/Utils.java b/src/main/java/com/redstoner/misc/Utils.java index d950d67..fa94bc0 100644 --- a/src/main/java/com/redstoner/misc/Utils.java +++ b/src/main/java/com/redstoner/misc/Utils.java @@ -90,7 +90,7 @@ public final class Utils { for (Player p : Bukkit.getOnlinePlayers()) ChatAPI.createMessage(p).appendText(prefix).appendMessage(message).send(); - Bukkit.getConsoleSender().sendMessage(prefix + message); + Bukkit.getConsoleSender().sendMessage(prefix + message.getRawMessage()); return Bukkit.getOnlinePlayers().size() + 1; } else @@ -104,7 +104,7 @@ public final class Utils } if (filter.sendTo(Bukkit.getConsoleSender())) { - Bukkit.getConsoleSender().sendMessage(prefix + message); + Bukkit.getConsoleSender().sendMessage(prefix + message.getRawMessage()); count++; } return count; -- cgit v1.2.3 From ae5494f203e2141197a1b6e5472612032c409fb1 Mon Sep 17 00:00:00 2001 From: Minenash Date: Sun, 13 Jan 2019 00:42:29 -0500 Subject: Fixed module loading, with caveats*. * Unfortunately it still won't remove the commands from the TabComplete * ChatAPI's error message for now unregistered commands, have been changed to lessen the confusion. --- .../redstoner/coremods/moduleLoader/ModuleLoader.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java index 109fc27..0a4cdf9 100644 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -5,7 +5,6 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -40,7 +39,7 @@ import net.nemez.chatapi.click.Message; /** The module loader, mother of all modules. Responsible for loading and taking care of all modules. * * @author Pepich */ -@Version(major = 5, minor = 0, revision = 0, compatible = 5) +@Version(major = 5, minor = 1, revision = 0, compatible = 5) public final class ModuleLoader implements CoreModule { private static ModuleLoader instance; @@ -370,8 +369,7 @@ public final class ModuleLoader implements CoreModule { HandlerList.unregisterAll((Listener) module); } - String[] commands = getAllHooks(module).toArray(new String[] {}); - CommandManager.unregisterAll(commands); + CommandManager.unregisterAllWithFallback(module.getClass().getSimpleName()); try { URLClassLoader loader = loaders.get(module); @@ -387,19 +385,6 @@ public final class ModuleLoader implements CoreModule } } - private static ArrayList getAllHooks(Module module) - { - ArrayList commands = new ArrayList<>(); - for (Method m : module.getClass().getMethods()) - { - Command cmd = m.getDeclaredAnnotation(Command.class); - if (cmd == null) - continue; - commands.add(cmd.hook()); - } - return commands; - } - @Command(hook = "load") public boolean loadModule(CommandSender sender, String name) { -- cgit v1.2.3 From c402986304796a1777379d305d0b0cb77268b7fb Mon Sep 17 00:00:00 2001 From: Minenash Date: Fri, 1 Feb 2019 23:16:25 -0500 Subject: Added the ability to hide or replace the log message for commands Mainly used for sensitive information, like passwords --- .../coremods/moduleLoader/ModuleLoader.java | 4 +- .../java/com/redstoner/logging/Log4JFilter.java | 54 +++++++++++++ .../com/redstoner/logging/PrivateLogManager.java | 89 ++++++++++++++++++++++ src/main/java/com/redstoner/misc/Main.java | 6 +- src/main/java/com/redstoner/misc/Utils.java | 12 +++ 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/redstoner/logging/Log4JFilter.java create mode 100644 src/main/java/com/redstoner/logging/PrivateLogManager.java diff --git a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java index 0a4cdf9..3886dd1 100644 --- a/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java +++ b/src/main/java/com/redstoner/coremods/moduleLoader/ModuleLoader.java @@ -27,6 +27,7 @@ import com.nemez.cmdmgr.CommandManager; import com.redstoner.annotations.AutoRegisterListener; import com.redstoner.annotations.Commands; import com.redstoner.annotations.Version; +import com.redstoner.logging.PrivateLogManager; import com.redstoner.misc.Main; import com.redstoner.misc.ModuleInfo; import com.redstoner.misc.VersionHelper; @@ -39,7 +40,7 @@ import net.nemez.chatapi.click.Message; /** The module loader, mother of all modules. Responsible for loading and taking care of all modules. * * @author Pepich */ -@Version(major = 5, minor = 1, revision = 0, compatible = 5) +@Version(major = 5, minor = 2, revision = 0, compatible = 5) public final class ModuleLoader implements CoreModule { private static ModuleLoader instance; @@ -370,6 +371,7 @@ public final class ModuleLoader implements CoreModule HandlerList.unregisterAll((Listener) module); } CommandManager.unregisterAllWithFallback(module.getClass().getSimpleName()); + PrivateLogManager.unregister(module); try { URLClassLoader loader = loaders.get(module); diff --git a/src/main/java/com/redstoner/logging/Log4JFilter.java b/src/main/java/com/redstoner/logging/Log4JFilter.java new file mode 100644 index 0000000..1ebed09 --- /dev/null +++ b/src/main/java/com/redstoner/logging/Log4JFilter.java @@ -0,0 +1,54 @@ +package com.redstoner.logging; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.Logger; +import org.apache.logging.log4j.core.filter.AbstractFilter; +import org.apache.logging.log4j.message.Message; + +public class Log4JFilter extends AbstractFilter { + + private static final long serialVersionUID = -5594073755007974254L; + + private static Result validateMessage(Message message) { + if (message == null) { + return Result.NEUTRAL; + } + return validateMessage(message.getFormattedMessage()); + } + + private static Result validateMessage(String message) { + return PrivateLogManager.isHidden(message) + ? Result.DENY + : Result.NEUTRAL; + } + + @Override + public Result filter(LogEvent event) { + Message candidate = null; + if (event != null) { + candidate = event.getMessage(); + } + return validateMessage(candidate); + } + + @Override + public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { + return validateMessage(msg); + } + + @Override + public Result filter(Logger logger, Level level, Marker marker, String msg, Object... params) { + return validateMessage(msg); + } + + @Override + public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { + String candidate = null; + if (msg != null) { + candidate = msg.toString(); + } + return validateMessage(candidate); + } +} \ No newline at end of file diff --git a/src/main/java/com/redstoner/logging/PrivateLogManager.java b/src/main/java/com/redstoner/logging/PrivateLogManager.java new file mode 100644 index 0000000..e8451e0 --- /dev/null +++ b/src/main/java/com/redstoner/logging/PrivateLogManager.java @@ -0,0 +1,89 @@ +package com.redstoner.logging; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.logging.log4j.LogManager; + +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; +import com.redstoner.modules.ModuleLogger; + +public class PrivateLogManager { + + private static Map registrar = new HashMap<>(); + private static Map commands = new HashMap<>(); + + private static final String ISSUED_COMMAND_TEXT = "issued server command: /"; + private static final int ISSUED_COMMAND_TEXT_LENGTH = ISSUED_COMMAND_TEXT.length(); + + private static ModuleLogger logger; + + public static void initialize() { + org.apache.logging.log4j.core.Logger logger; + logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); + logger.addFilter(new Log4JFilter()); + PrivateLogManager.logger = new ModuleLogger("PrivateLogManager"); + } + + public static void register(Module module, String command, String replacement) { + command = command.toLowerCase(); + registrar.put(command, module); + commands.put(command, replacement); + logger.info(module.getClass().getSimpleName() + " registered &e/" + command + + (replacement.equals("")? "&7. Command will not be logged!" + : "&7, using replacement, &e" + replacement + "&7.")); + } + + public static void unregister(Module module) { + String unregestered = ""; + Iterator> i = registrar.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry entry = i.next(); + if (entry.getValue() == module) { + i.remove(); + commands.remove(entry.getKey()); + unregestered += "&e" + entry.getKey() + "&7, "; + } + } + if (!unregestered.equals("")) + logger.info("Unregistered " + unregestered.substring(0, unregestered.length() - 2) + "&7 for module, " + module.getClass().getSimpleName() + "."); + } + + public static void unregister(Module module, String... toRemove) { + String unregestered = ""; + for (int i = 0; i < toRemove.length; i++) { + String command = toRemove[i].toLowerCase(); + registrar.remove(command); + if (commands.remove(command) != null) + unregestered += "&e" + command + "&7, "; + } + if (!unregestered.equals("")) + logger.info(module.getClass().getSimpleName() + " unregistered " + unregestered.substring(0, unregestered.length() - 2) + "&7."); + } + + public static boolean isHidden(String message) { + if (message == null) + return false; + + int index = message.indexOf(ISSUED_COMMAND_TEXT); + if (index == -1) + return false; + + String command = message.substring(index + ISSUED_COMMAND_TEXT_LENGTH); + + int spaceIndex = command.indexOf(" "); + command = spaceIndex == -1? command.toLowerCase() : command.substring(0, spaceIndex).toLowerCase(); + + String replacement = commands.get(command); + if (replacement == null) + return false; + if (replacement.equals("")) + return true; + + String player = message.substring(0, message.indexOf(" ")); + Utils.run(() -> System.out.println(replacement.replace("$s", player))); + return true; + } +} diff --git a/src/main/java/com/redstoner/misc/Main.java b/src/main/java/com/redstoner/misc/Main.java index b24e532..40894ee 100644 --- a/src/main/java/com/redstoner/misc/Main.java +++ b/src/main/java/com/redstoner/misc/Main.java @@ -4,6 +4,7 @@ import org.bukkit.plugin.java.JavaPlugin; import com.redstoner.annotations.Version; import com.redstoner.coremods.moduleLoader.ModuleLoader; +import com.redstoner.logging.PrivateLogManager; import com.redstoner.misc.mysql.MysqlHandler; import net.nemez.chatapi.ChatAPI; @@ -11,7 +12,7 @@ import net.nemez.chatapi.ChatAPI; /** Main class. Duh. * * @author Pepich */ -@Version(major = 4, minor = 0, revision = 0, compatible = -1) +@Version(major = 5, minor = 1, revision = 0, compatible = -1) public class Main extends JavaPlugin { public static JavaPlugin plugin; @@ -20,6 +21,9 @@ public class Main extends JavaPlugin public void onEnable() { plugin = this; + + PrivateLogManager.initialize(); + ChatAPI.initialize(this); // Configger.init(); MysqlHandler.init(); diff --git a/src/main/java/com/redstoner/misc/Utils.java b/src/main/java/com/redstoner/misc/Utils.java index fa94bc0..e3fd68c 100644 --- a/src/main/java/com/redstoner/misc/Utils.java +++ b/src/main/java/com/redstoner/misc/Utils.java @@ -11,6 +11,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import com.redstoner.annotations.Version; +import com.redstoner.coremods.moduleLoader.ModuleLoader; import net.nemez.chatapi.ChatAPI; import net.nemez.chatapi.click.Message; @@ -188,4 +189,15 @@ public final class Utils { return UUID_pattern.matcher(toCheck).matches(); } + + public static void run(Runnable r) { + run(r, 0); + } + + public static void run(Runnable r, int delay) { + Bukkit.getScheduler().scheduleSyncDelayedTask(ModuleLoader.getPlugin(), r, delay); + } + + + } -- cgit v1.2.3 From 46be8ab62c7cd8567cfef174105808d32d4fc225 Mon Sep 17 00:00:00 2001 From: Logan Fick Date: Thu, 7 Feb 2019 16:40:44 -0500 Subject: Added Travis CI configuration file. --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ab48fcd --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: java + +jdk: + - openjdk8 + - oraclejdk8 -- cgit v1.2.3 From bdd8ee823396e1aab0a2c864d9d80853f7a16cbd Mon Sep 17 00:00:00 2001 From: Logan Fick Date: Fri, 8 Feb 2019 08:43:42 -0500 Subject: Added Gradle wrapper. --- gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 56172 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 +++++++++++++++++++++++++++++++ gradlew.bat | 84 +++++++++++++++ 4 files changed, 261 insertions(+) create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..28861d2 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..115e6ac --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega -- cgit v1.2.3 From 335a5b57d322a0a9e3b43729e240206af05c09bb Mon Sep 17 00:00:00 2001 From: Logan Fick Date: Fri, 8 Feb 2019 09:30:00 -0500 Subject: Added missing Log4j dependency. --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index bd7d0bb..bc4ba04 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,8 @@ dependencies { implementation "com.github.RedstonerServer:CommandManager:master-SNAPSHOT" implementation "com.github.RedstonerServer:ChatAPI:master-SNAPSHOT" implementation "com.github.RedstonerServer:ChestAPI:master-SNAPSHOT" + + compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.11.1' compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' } -- cgit v1.2.3