summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPepich <benedikt.abel@yahoo.de>2017-09-17 15:35:08 +0200
committerPepich <benedikt.abel@yahoo.de>2017-09-17 15:35:08 +0200
commit5ccfe4b121d4a29fa4d1b8b8880be3bfa756a710 (patch)
tree168d8135ddc0c637dd12308d0f1b4116328fd4c0
parenta5c54126bc3491dc1fb8f8fc206e7202d541dff0 (diff)
Update to APIv4. I hope this no borke git.
-rw-r--r--src/com/redstoner/annotations/Commands.java3
-rw-r--r--src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd21
-rw-r--r--src/com/redstoner/coremods/moduleLoader/ModuleLoader.java364
-rw-r--r--src/com/redstoner/misc/CommandHolderType.java2
-rw-r--r--src/com/redstoner/misc/JsonManager.java76
-rw-r--r--src/com/redstoner/misc/Main.java5
-rw-r--r--src/com/redstoner/misc/Utils.java170
-rw-r--r--src/com/redstoner/misc/VersionHelper.java9
-rw-r--r--src/com/redstoner/modules/Module.java27
-rw-r--r--src/com/redstoner/modules/ModuleLogger.java76
10 files changed, 443 insertions, 310 deletions
diff --git a/src/com/redstoner/annotations/Commands.java b/src/com/redstoner/annotations/Commands.java
index 1388de4..537bff0 100644
--- a/src/com/redstoner/annotations/Commands.java
+++ b/src/com/redstoner/annotations/Commands.java
@@ -1,11 +1,14 @@
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/coremods/moduleLoader/ModuleLoader.cmd b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd
index e88cafa..eadeeb7 100644
--- a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd
+++ b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.cmd
@@ -1,18 +1,33 @@
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 jutils.modules.list;
+ 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 jtuils.modules.admin;
+ 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 jutils.modules.admin;
+ perm moduleloader.modules.admin;
run unload name;
type console;
}
diff --git a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java
index 63878db..5666b2a 100644
--- a/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java
+++ b/src/com/redstoner/coremods/moduleLoader/ModuleLoader.java
@@ -25,16 +25,19 @@ 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.Utils;
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 = 0, compatible = 2)
+@Version(major = 4, minor = 0, revision = 0, compatible = 4)
public final class ModuleLoader implements CoreModule
{
private static ModuleLoader instance;
@@ -45,6 +48,7 @@ public final class ModuleLoader implements CoreModule
private static File configFile;
private static FileConfiguration config;
private static boolean debugMode = false;
+ private static HashMap<Module, ModuleLogger> loggers = new HashMap<Module, ModuleLogger>();
private ModuleLoader()
{
@@ -66,6 +70,7 @@ public final class ModuleLoader implements CoreModule
{
if (instance == null)
instance = new ModuleLoader();
+ loggers.put(instance, new ModuleLogger("ModuleLoader"));
CommandManager.registerCommand(ModuleLoader.class.getResourceAsStream("ModuleLoader.cmd"), instance,
Main.plugin);
}
@@ -98,7 +103,7 @@ public final class ModuleLoader implements CoreModule
{
e1.printStackTrace();
}
- Utils.error("Invalid config file! Creating new, blank file!");
+ instance.getLogger().error("Invalid config file! Creating new, blank file!");
}
List<String> coremods = config.getStringList("coremods");
if (coremods == null || coremods.isEmpty())
@@ -143,23 +148,21 @@ public final class ModuleLoader implements CoreModule
debugMode = config.getBoolean("debugMode");
for (String s : coremods)
if (!s.startsWith("#"))
- ModuleLoader.addDynamicModule(s);
- enableModules();
+ 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("#"))
- ModuleLoader.addDynamicModule(s);
- enableModules();
- }
-
- /** Call this to enable all not-yet enabled modules that are known to the loader. */
- public static final void enableModules()
- {
- for (Module module : modules.keySet())
- {
- if (modules.get(module))
- continue;
- enableLoadedModule(module);
- }
+ 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.</br>
@@ -176,7 +179,7 @@ public final class ModuleLoader implements CoreModule
{
if (modules.get(module))
{
- Utils.info("Module was already enabled! Ignoring module.!");
+ instance.getLogger().info("Module was already enabled! Ignoring module.!");
return true;
}
if (module.onEnable())
@@ -186,14 +189,14 @@ public final class ModuleLoader implements CoreModule
{
Bukkit.getPluginManager().registerEvents((Listener) module, Main.plugin);
}
- Utils.info("Enabled module " + module.getClass().getName());
- Utils.info("Loaded module " + module.getClass().getName());
+ instance.getLogger().info("Enabled module " + module.getClass().getName());
+ instance.getLogger().info("Loaded module " + module.getClass().getName());
modules.put(module, true);
return true;
}
else
{
- Utils.error("Failed to enable module " + module.getClass().getName());
+ instance.getLogger().error("Failed to enable module " + module.getClass().getName());
return false;
}
}
@@ -208,33 +211,36 @@ public final class ModuleLoader implements CoreModule
{
Bukkit.getPluginManager().registerEvents((Listener) m, Main.plugin);
}
- Utils.info("Loaded and enabled module " + m.getClass().getName());
- Utils.info("Loaded module " + m.getClass().getName());
+ instance.getLogger().info("Loaded and enabled module " + m.getClass().getName());
+ instance.getLogger().info("Loaded module " + m.getClass().getName());
return true;
}
else
{
- Utils.error("Failed to enable module " + m.getClass().getName());
+ instance.getLogger().error("Failed to enable module " + m.getClass().getName());
return false;
}
}
catch (InstantiationException | IllegalAccessException e)
{
- Utils.error("Could not add " + clazz.getName() + " to the list, constructor not accessible.");
+ instance.getLogger()
+ .error("Could not add " + clazz.getName() + " to the list, constructor not accessible.");
return false;
}
}
- @SuppressWarnings("deprecation")
- private static final void enableLoadedModule(Module module)
+ 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.isCompatible(VersionHelper.create(2, 0, 0, -1), module.getClass()))
- CommandManager.registerCommand(module.getCommandString(), module, Main.plugin);
+ if (oldVersion.toString().equals("0.0.0.0"))
+ module.firstLoad();
+ else if (!VersionHelper.getVersion(module.getClass()).equals(oldVersion))
+ module.migrate(oldVersion);
if (VersionHelper.isCompatible(VersionHelper.create(4, 0, 0, 3), module.getClass()))
{
module.postEnable();
@@ -247,7 +253,8 @@ public final class ModuleLoader implements CoreModule
switch (ann.value())
{
case File:
- File f = new File(module.getClass().getName() + ".cmd");
+ File f = new File("plugins/ModuleLoader/classes/"
+ + module.getClass().getName().replace(".", "/") + ".cmd");
CommandManager.registerCommand(f, module, Main.plugin);
break;
case Stream:
@@ -262,18 +269,16 @@ public final class ModuleLoader implements CoreModule
}
}
}
- Utils.info("Loaded module " + module.getClass().getName());
+ 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
- Utils.error("Failed to load module " + module.getClass().getName());
+ instance.getLogger().error("Failed to load module " + module.getClass().getName());
}
catch (Exception e)
{
- Utils.error("Failed to load module " + module.getClass().getName());
+ instance.getLogger().error("Failed to load module " + module.getClass().getName());
e.printStackTrace();
}
}
@@ -285,19 +290,52 @@ public final class ModuleLoader implements CoreModule
@Command(hook = "list", async = AsyncType.ALWAYS)
public boolean listModulesCommand(CommandSender sender)
{
- Utils.sendModuleHeader(sender);
- StringBuilder sb = new StringBuilder("Modules:\n");
- for (Module module : modules.keySet())
+ 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];
- sb.append(modules.get(module) ? "&a" : "&c");
- sb.append(classname);
- sb.append(", ");
+ m.appendText((ModuleLoader.modules.get(module) ? "§a" : "§c") + classname);
+ if (i + 1 < modules.length)
+ m.appendText("§7, ");
}
- sb.delete(sb.length() - 2, sb.length());
- Utils.sendMessage(sender, " §e", sb.toString(), '&');
- Utils.sendMessage(sender, " §7", "For more detailed information, consult the debugger.");
+ 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;
}
@@ -351,40 +389,55 @@ public final class ModuleLoader implements CoreModule
@Command(hook = "load")
public boolean loadModule(CommandSender sender, String name)
{
- addDynamicModule(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)
{
- removeDynamicModule(name);
+ if (!removeDynamicModule(name))
+ instance.getLogger().error("Couldn't find module! Couldn't disable nonexisting module!");
return true;
}
- public static final void addDynamicModule(String name)
+ 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))
{
- Utils.info(
+ instance.getLogger().info(
"Found existing module, attempting override. WARNING! This operation will halt the main thread until it is completed.");
- Utils.info("Attempting to load new class definition before disabling and removing the old module");
+ instance.getLogger()
+ .info("Attempting to load new class definition before disabling and removing the old module");
boolean differs = false;
- Utils.info("Old class definition: Class@" + m.getClass().hashCode());
+ 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());
- Utils.info("Found new class definition: Class@" + newClass.hashCode());
+ instance.getLogger().info("Found new class definition: Class@" + newClass.hashCode());
differs = m.getClass() != newClass;
}
catch (ClassNotFoundException e)
{
- Utils.error("Could not find a class definition, aborting now!");
+ instance.getLogger().error("Could not find a class definition, aborting now!");
e.printStackTrace();
try
{
@@ -394,15 +447,15 @@ public final class ModuleLoader implements CoreModule
{
e1.printStackTrace();
}
- return;
+ return false;
}
if (!differs)
{
if (!debugMode)
{
- Utils.warn(
+ instance.getLogger().warn(
"New class definition equals old definition, are you sure you did everything right?");
- Utils.info("Aborting now...");
+ instance.getLogger().info("Aborting now...");
try
{
cl.close();
@@ -411,14 +464,14 @@ public final class ModuleLoader implements CoreModule
{
e.printStackTrace();
}
- return;
+ return false;
}
else
- Utils.warn(
+ instance.getLogger().warn(
"New class definition equals old definition, but debugMode is enabled. Loading anyways.");
}
else
- Utils.info("Found new class definition, attempting to instantiate:");
+ instance.getLogger().info("Found new class definition, attempting to instantiate:");
Module module = null;
try
{
@@ -426,7 +479,7 @@ public final class ModuleLoader implements CoreModule
}
catch (InstantiationException | IllegalAccessException e)
{
- Utils.error("Could not instantiate the module, aborting!");
+ instance.getLogger().error("Could not instantiate the module, aborting!");
e.printStackTrace();
try
{
@@ -436,20 +489,21 @@ public final class ModuleLoader implements CoreModule
{
e1.printStackTrace();
}
- return;
+ return false;
}
- Utils.info("Instantiated new class definition, checking versions");
- Version oldVersion = m.getClass().getAnnotation(Version.class);
- Utils.info("Current version: " + VersionHelper.getString(oldVersion));
+ 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);
- Utils.info("Version of remote class: " + VersionHelper.getString(newVersion));
+ instance.getLogger().info("Version of remote class: " + VersionHelper.getString(newVersion));
if (oldVersion.equals(newVersion))
{
if (!debugMode)
{
- Utils.error("Detected equal module versions, " + (debugMode
- ? " aborting now... Set debugMode to true in your config if you want to continue!"
- : " continueing anyways."));
+ 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
@@ -460,16 +514,17 @@ public final class ModuleLoader implements CoreModule
{
e.printStackTrace();
}
- return;
+ return false;
}
}
else
- Utils.warn("New version equals old version, but debugMode is enabled. Loading anyways.");
+ instance.getLogger()
+ .warn("New version equals old version, but debugMode is enabled. Loading anyways.");
}
else
- Utils.info("Versions differ, disabling old module");
+ instance.getLogger().info("Versions differ, disabling old module");
disableModule(m);
- Utils.info("Disabled module, overriding the implementation");
+ instance.getLogger().info("Disabled module, overriding the implementation");
modules.remove(m);
try
{
@@ -482,81 +537,115 @@ public final class ModuleLoader implements CoreModule
}
modules.put(module, false);
loaders.put(module, cl);
- Utils.info("Successfully updated class definition. Enabling new implementation:");
- enableLoadedModule(module);
- return;
+ 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 = mainLoader.loadClass(name);
+ Class<?> clazz = cl.loadClass(name);
Module module = (Module) clazz.newInstance();
modules.put(module, false);
- enableLoadedModule(module);
+ loaders.put(module, cl);
+ enableLoadedModule(module, oldVersion);
+ return true;
}
- catch (ClassNotFoundException | InstantiationException | IllegalAccessException e)
+ 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"))
{
- Utils.warn(
+ instance.getLogger().warn(
"Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix.");
- addDynamicModule(name.replaceAll(".class$", ""));
+ if (addDynamicModule(name.replaceAll(".class$", "")))
+ return true;
}
if (!name.contains("."))
{
- Utils.warn(
- "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a packet name and trying again.");
- addDynamicModule(name.toLowerCase() + "." + name);
+ 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."))
+ if (!name.startsWith("com.redstoner.modules.") && name.contains("."))
{
- Utils.warn(
- "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of packet name and trying again.");
- addDynamicModule("com.redstoner.modules." + name);
+ 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;
}
- else
- e.printStackTrace();
}
+ return false;
}
- public static final void removeDynamicModule(String name)
+ public static final boolean removeDynamicModule(String name)
{
for (Module m : modules.keySet())
{
if (m.getClass().getName().equals(name))
{
- Utils.info(
+ instance.getLogger().info(
"Found existing module, attempting unload. WARNING! This operation will halt the main thread until it is completed.");
- Utils.info("Attempting to disable module properly:");
+ instance.getLogger().info("Attempting to disable module properly:");
disableModule(m);
modules.remove(m);
- Utils.info("Disabled module.");
- return;
+ instance.getLogger().info("Disabled module.");
+ return true;
}
}
if (!name.startsWith("com.redstoner.modules."))
{
if (name.endsWith(".class"))
{
- Utils.warn(
+ instance.getLogger().warn(
"Couldn't find class definition, but path ends with .class -> Attempting again with removed file suffix.");
- addDynamicModule(name.replaceAll(".class$", ""));
+ if (removeDynamicModule(name.replaceAll(".class$", "")))
+ return true;
}
if (!name.contains("."))
{
- Utils.warn(
- "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of path by adding a packet name and trying again.");
- addDynamicModule(name.toLowerCase() + "." + name);
+ 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."))
{
- Utils.warn(
- "Couldn't find class definition, suspecting incomplete path. Attempting autocompletion of packet name and trying again.");
- addDynamicModule("com.redstoner.modules." + name);
+ 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;
}
}
- else
- Utils.error("Couldn't find module! Couldn't disable nonexisting module!");
+ return false;
}
/** Finds a module by name for other modules to reference it.
@@ -566,7 +655,7 @@ public final class ModuleLoader implements CoreModule
public static Module getModule(String name)
{
for (Module m : modules.keySet())
- if (m.getClass().getSimpleName().equals(name) || m.getClass().getName().equals(name))
+ if (m.getClass().getSimpleName().equalsIgnoreCase(name) || m.getClass().getName().equalsIgnoreCase(name))
return m;
return null;
}
@@ -582,4 +671,69 @@ public final class ModuleLoader implements CoreModule
return true;
return false;
}
+
+ public static ModuleLogger getModuleLogger(Module module)
+ {
+ return loggers.get(module);
+ }
+
+ public static void updateConfig()
+ {
+ List<String> coremods = config.getStringList("coremods");
+ ArrayList<String> new_coremods = new ArrayList<String>();
+ List<String> autoload = config.getStringList("autoload");
+ ArrayList<String> new_autoload = new ArrayList<String>();
+
+ 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/misc/CommandHolderType.java b/src/com/redstoner/misc/CommandHolderType.java
index 19b9dda..7c4383e 100644
--- a/src/com/redstoner/misc/CommandHolderType.java
+++ b/src/com/redstoner/misc/CommandHolderType.java
@@ -8,6 +8,6 @@ public enum CommandHolderType
{
Stream,
File,
- @Deprecated String,
+ String,
None
}
diff --git a/src/com/redstoner/misc/JsonManager.java b/src/com/redstoner/misc/JsonManager.java
index 998d137..cad716c 100644
--- a/src/com/redstoner/misc/JsonManager.java
+++ b/src/com/redstoner/misc/JsonManager.java
@@ -55,25 +55,35 @@ public class JsonManager
@Override
public void run()
{
- if (destination.exists())
- destination.delete();
- else if (!destination.getParentFile().exists())
- destination.getParentFile().mkdirs();
- try
- {
- destination.createNewFile();
- FileWriter writer = new FileWriter(destination);
- object.writeJSONString(writer);
- writer.flush();
- writer.close();
- }
- catch (IOException e)
- {}
+ saveSync(object, destination);
}
});
t.start();
}
+ /** Saves a JSONObject to a file. Will create the necessary FileStructure like folders and the file itself.</br>
+ * 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);
+ object.writeJSONString(writer);
+ writer.flush();
+ writer.close();
+ }
+ catch (IOException e)
+ {}
+ }
+
/** Loads a JSONArray from a file.
*
* @param source the file to load from.
@@ -106,22 +116,32 @@ public class JsonManager
@Override
public void run()
{
- if (destination.exists())
- destination.delete();
- else if (!destination.getParentFile().exists())
- destination.getParentFile().mkdirs();
- try
- {
- destination.createNewFile();
- FileWriter writer = new FileWriter(destination);
- array.writeJSONString(writer);
- writer.flush();
- writer.close();
- }
- catch (IOException e)
- {}
+ saveSync(array, destination);
}
});
t.start();
}
+
+ /** Saves a JSONArray to a file. Will create the necessary FileStructure like folders and the file itself.</br>
+ * 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);
+ array.writeJSONString(writer);
+ writer.flush();
+ writer.close();
+ }
+ catch (IOException e)
+ {}
+ }
}
diff --git a/src/com/redstoner/misc/Main.java b/src/com/redstoner/misc/Main.java
index ddc8355..b24e532 100644
--- a/src/com/redstoner/misc/Main.java
+++ b/src/com/redstoner/misc/Main.java
@@ -6,6 +6,8 @@ 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 */
@@ -18,13 +20,12 @@ public class Main extends JavaPlugin
public void onEnable()
{
plugin = this;
+ ChatAPI.initialize(this);
// Configger.init();
MysqlHandler.init();
ModuleLoader.init();
// Load modules from config
ModuleLoader.loadFromConfig();
- // And enable them
- ModuleLoader.enableModules();
}
@Override
diff --git a/src/com/redstoner/misc/Utils.java b/src/com/redstoner/misc/Utils.java
index 80f5a8b..937ba1f 100644
--- a/src/com/redstoner/misc/Utils.java
+++ b/src/com/redstoner/misc/Utils.java
@@ -11,6 +11,8 @@ import org.bukkit.entity.Player;
import com.redstoner.annotations.Version;
+import net.nemez.chatapi.ChatAPI;
+
/** The utils class containing utility functions. Those include but are not limited to sending formatted messages, broadcasts and more.
*
* @author Pepich */
@@ -24,90 +26,6 @@ public final class Utils
private Utils()
{}
- /** This will send a message to the specified recipient. It will generate the module prefix.
- *
- * @param recipient Whom to sent the message to.
- * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. */
- public static void sendMessage(CommandSender recipient, String message)
- {
- sendMessage(recipient, null, message);
- }
-
- /** This will send a message to the specified recipient. It will generate the module prefix. Also, this will be logged to console as a warning.
- *
- * @param recipient Whom to sent the message to.
- * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. */
- public static void sendErrorMessage(CommandSender recipient, String message)
- {
- sendErrorMessage(recipient, null, message);
- }
-
- /** This will send a message to the specified recipient. It will generate the module prefix if you want it to.
- *
- * @param recipient Whom to sent the message to.
- * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&2MODULE&8]
- * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. */
- public static void sendMessage(CommandSender recipient, String prefix, String message)
- {
- if (prefix == null)
- prefix = "§8[§2" + getCaller() + "§8]: ";
- recipient.sendMessage(prefix + "§7" + message);
- }
-
- /** This will send a message to the specified recipient. It will generate the module prefix if you want it to. Also, this will be logged to console as a warning.
- *
- * @param recipient Whom to sent the message to.
- * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&cMODULE&8]
- * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise. */
- public static void sendErrorMessage(CommandSender recipient, String prefix, String message)
- {
- if (prefix == null)
- prefix = "§8[§c" + getCaller() + "§8]: ";
- recipient.sendMessage(prefix + "§7" + message);
- }
-
- /** Invokes sendMessage. This method will additionally translate alternate color codes for you.
- *
- * @param recipient Whom to sent the message to.
- * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&cMODULE&8]
- * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise.
- * @param alternateColorCode The alternate color code indicator to use. If set to '&' then "&7" would be translated to "§7". Works with any char. */
- public static void sendMessage(CommandSender recipient, String prefix, String message, char alternateColorCode)
- {
- if (prefix == null)
- prefix = "§8[§2" + getCaller() + "§8]: ";
- sendMessage(recipient, colorify(prefix, alternateColorCode), colorify(message, alternateColorCode));
- }
-
- /** Invokes sendErrorMessage. This method will additionally translate alternate color codes for you.
- *
- * @param recipient Whom to sent the message to.
- * @param prefix The prefix for the message. If null, the default prefix will be used: &8[&cMODULE&8]
- * @param message The message to sent. Will default to &7 (light_grey) if not specified otherwise.
- * @param alternateColorCode The alternate color code indicator to use. If set to '&' then "&7" would be translated to "§7". Works with any char. */
- public static void sendErrorMessage(CommandSender recipient, String prefix, String message, char alternateColorCode)
- {
- if (prefix == null)
- prefix = "§8[§c" + getCaller() + "§8]: ";
- sendErrorMessage(recipient, colorify(prefix, '&'), colorify(message, '&'));
- }
-
- /** 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.</br>
- * This will not be logged to console except when you return true in the filter.
- *
- * @param message the message to be sent around
- * @param filter the BroadcastFilter to be applied.</br>
- * Write a class implementing the interface and pass it to this method, the "sendTo()" method will be called for each recipient.
- * @param alternateColorCode The alternate color code indicator to use. If set to '&' then "&7" would be translated to "§7". Works with any char.
- * @return the amount of people that received the message. */
- public static int broadcast(String prefix, String message, BroadcastFilter filter, char alternateColorCode)
- {
- if (prefix == null)
- prefix = "§8[§2" + getCaller() + "§8]: ";
- message = colorify(message, alternateColorCode);
- return broadcast(prefix, message, filter);
- }
-
/** 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.</br>
* If you want to, you can set a message that will be logged to console. Set to null to not log anything.</br>
* You can still allow console in the filter to log the original message.
@@ -120,6 +38,7 @@ public final class Utils
* @return the amount of people that received the message. */
public static int broadcast(String prefix, String message, BroadcastFilter filter)
{
+ message = ChatAPI.colorify(null, message);
if (prefix == null)
prefix = "§8[§2" + getCaller() + "§8]: ";
if (filter == null)
@@ -147,45 +66,6 @@ public final class Utils
}
}
- /** Deprecated. Use Utils.info(message) instead.
- *
- * @param message The message to be put into console. Prefixes are automatically generated. */
- @Deprecated
- public static void log(String message)
- {
- info(message);
- }
-
- /** Prints an info message into console. Supports "&" color codes.
- *
- * @param message The message to be put into console. Prefixes are automatically generated. Color defaults to grey. */
- public static void info(String message)
- {
- String classname = getCaller();
- String prefix = "§8[§2" + classname + "§8]: ";
- Bukkit.getConsoleSender().sendMessage(colorify(prefix + "§7" + message, Bukkit.getConsoleSender(), '&'));
- }
-
- /** Prints a warning message into console. Supports "&" color codes.
- *
- * @param message The message to be put into console. Prefixes are automatically generated. Color defaults to grey. */
- public static void warn(String message)
- {
- String classname = getCaller();
- String prefix = "§e[WARN]: §8[§e" + classname + "§8]: ";
- Bukkit.getConsoleSender().sendMessage(colorify(prefix + "§7" + message, Bukkit.getConsoleSender(), '&'));
- }
-
- /** Used to make an error output to console. Supports "&" color codes.
- *
- * @param message The message to be put into console. Prefixes are automatically generated. Color defaults to red. */
- public static void error(String message)
- {
- String classname = getCaller();
- String prefix = "§c[ERROR]: §8[§c" + classname + "§8]: ";
- Bukkit.getConsoleSender().sendMessage(colorify(prefix + "§7" + message, Bukkit.getConsoleSender(), '&'));
- }
-
/** This method will find the next parent caller and return their class name, omitting package names.
*
* @return the Name of the calling class. */
@@ -218,25 +98,6 @@ public final class Utils
return classname;
}
- /** Displays the module header to the recipient.</br>
- * Format: &2--=[ %MODULE% ]=--
- *
- * @param recipient Whom to display the header to. */
- public static void sendModuleHeader(CommandSender recipient)
- {
- sendModuleHeader(recipient, getCaller());
- }
-
- /** Displays the module header to the recipient.</br>
- * Format: &2--=[ %HEADER% ]=--
- *
- * @param recipient Whom to display the header to.
- * @param header The module name. */
- public static void sendModuleHeader(CommandSender recipient, String header)
- {
- recipient.sendMessage("§2--=[ " + header + " ]=--");
- }
-
/** Provides a uniform way of getting the date for all modules.
*
* @return The current date in the format "[dd-mm-yyyy hh:mm:ss]" */
@@ -271,29 +132,4 @@ public final class Utils
id = "CONSOLE";
return id;
}
-
- /** This method "colorifies" a message.
- *
- * @param message the message to be colored.
- * @return the colorified message. */
- public static String colorify(String message, char alternateColorcode)
- {
- return colorify(message, Bukkit.getConsoleSender(), alternateColorcode);
- }
-
- /** This method "colorifies" a message using proper permissions.
- *
- * @param message the message to be colored.
- * @param sender the @CommandSender whose permissions shall be applied.
- * @return the colorified message. */
- public static String colorify(String message, CommandSender sender, char alternateColorcode)
- {
- if (sender.hasPermission("essentials.chat.color"))
- message = message.replaceAll(alternateColorcode + "([0-9a-fA-FrR])", "§$1");
- if (sender.hasPermission("essentials.chat.format"))
- message = message.replaceAll(alternateColorcode + "(l-oL-OrR)", "§$1");
- if (sender.hasPermission("essentials.chat.magic"))
- message = message.replaceAll(alternateColorcode + "([kKrR])", "§$1");
- return message.replace(alternateColorcode + "§", alternateColorcode + "");
- }
}
diff --git a/src/com/redstoner/misc/VersionHelper.java b/src/com/redstoner/misc/VersionHelper.java
index 1b20b16..e4a9403 100644
--- a/src/com/redstoner/misc/VersionHelper.java
+++ b/src/com/redstoner/misc/VersionHelper.java
@@ -97,6 +97,15 @@ public final class VersionHelper
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
diff --git a/src/com/redstoner/modules/Module.java b/src/com/redstoner/modules/Module.java
index 78488b7..1c89e15 100644
--- a/src/com/redstoner/modules/Module.java
+++ b/src/com/redstoner/modules/Module.java
@@ -1,11 +1,12 @@
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 = 3, minor = 0, revision = 0, compatible = 2)
+@Version(major = 4, minor = 0, revision = 0, compatible = 0)
public interface Module
{
/** Will be called when the module gets enabled. */
@@ -23,13 +24,31 @@ public interface Module
public default void onDisable()
{}
- /** Gets called on registration of the module.
- * THIS WAS ONLY KEPT FOR COMPATIBILITY REASONS. Please register commands yourself instead using the "postEnable" method.
+ /** 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. */
- @Deprecated
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
new file mode 100644
index 0000000..8141976
--- /dev/null
+++ b/src/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;
+ }
+}