Ghetto module+lib loading
This commit is contained in:
parent
e97a43c9e2
commit
29b7a3cee7
@ -2,6 +2,11 @@ package cz.marwland.mc.core;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -18,6 +23,7 @@ import cz.marwland.mc.core.storage.StorageCredentials;
|
|||||||
import cz.marwland.mc.core.storage.impl.MariaDbConnectionFactory;
|
import cz.marwland.mc.core.storage.impl.MariaDbConnectionFactory;
|
||||||
import cz.marwland.mc.core.storage.impl.MySqlConnectionFactory;
|
import cz.marwland.mc.core.storage.impl.MySqlConnectionFactory;
|
||||||
import cz.marwland.mc.core.util.ConfigUtil;
|
import cz.marwland.mc.core.util.ConfigUtil;
|
||||||
|
import cz.marwland.mc.core.util.FileUtil;
|
||||||
|
|
||||||
public class MarwCore extends JavaPlugin {
|
public class MarwCore extends JavaPlugin {
|
||||||
|
|
||||||
@ -25,29 +31,33 @@ public class MarwCore extends JavaPlugin {
|
|||||||
private HashMap<String, Feature> features = new HashMap<>();
|
private HashMap<String, Feature> features = new HashMap<>();
|
||||||
private static MarwCore INSTANCE = null;
|
private static MarwCore INSTANCE = null;
|
||||||
private File modulesFolder = null;
|
private File modulesFolder = null;
|
||||||
|
private File libsFolder = null;
|
||||||
private ModuleClassLoader moduleClassLoader;
|
private ModuleClassLoader moduleClassLoader;
|
||||||
private SQLStorage sqlStorage;
|
private SQLStorage sqlStorage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
INSTANCE = this;
|
INSTANCE = this;
|
||||||
this.getCommand("marw").setExecutor(new MarwCommandExecutor());
|
modulesFolder = this.getModulesFolderPath().toFile();
|
||||||
|
modulesFolder.mkdirs();
|
||||||
|
libsFolder = this.getLibsFolderPath().toFile();
|
||||||
|
libsFolder.mkdir();
|
||||||
configManager = new ConfigManager(this);
|
configManager = new ConfigManager(this);
|
||||||
configManager.registerConfig("config.yml");
|
configManager.registerConfig("config.yml");
|
||||||
configManager.loadConfig("config.yml");
|
configManager.loadConfig("config.yml");
|
||||||
|
this.loadModulesAndLibs();
|
||||||
this.loadDatabase();
|
this.loadDatabase();
|
||||||
|
|
||||||
modulesFolder = this.getModulesFolderPath().toFile();
|
this.getCommand("marw").setExecutor(new MarwCommandExecutor());
|
||||||
modulesFolder.mkdirs();
|
this.enableModules();
|
||||||
this.loadAndEnableModules();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
this.features.forEach((k, v) -> v.onDisable());
|
this.features.forEach((k, v) -> v.onDisable());
|
||||||
this.configManager.save();
|
this.configManager.save();
|
||||||
this.sqlStorage.shutdown();
|
if (sqlStorage != null)
|
||||||
|
this.sqlStorage.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -56,13 +66,14 @@ public class MarwCore extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reload() {
|
public void reload() {
|
||||||
this.reloadConfig();
|
|
||||||
this.features.forEach((k, v) -> v.onDisable());
|
this.features.forEach((k, v) -> v.onDisable());
|
||||||
|
this.reloadConfig();
|
||||||
|
this.loadModulesAndLibs();
|
||||||
this.loadDatabase();
|
this.loadDatabase();
|
||||||
this.loadAndEnableModules();
|
this.enableModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadModules() {
|
public void loadModulesAndLibs() {
|
||||||
if (moduleClassLoader != null) {
|
if (moduleClassLoader != null) {
|
||||||
try {
|
try {
|
||||||
moduleClassLoader.close();
|
moduleClassLoader.close();
|
||||||
@ -71,10 +82,17 @@ public class MarwCore extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleClassLoader = new ModuleClassLoader();
|
URLClassLoader pluginClassLoader = (URLClassLoader) this.getClassLoader();
|
||||||
|
FileUtil.addFromDirectory(pluginClassLoader, libsFolder);
|
||||||
|
//FileUtil.addFromDirectory(pluginClassLoader, modulesFolder);
|
||||||
|
moduleClassLoader = new ModuleClassLoader(pluginClassLoader);
|
||||||
|
//moduleClassLoader.addFromDirectory(libsFolder);
|
||||||
moduleClassLoader.addFromDirectory(modulesFolder);
|
moduleClassLoader.addFromDirectory(modulesFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableModules() {
|
||||||
for (String modClass : configManager.getConfig("config.yml").getStringList("modules")) {
|
for (String modClass : configManager.getConfig("config.yml").getStringList("modules")) {
|
||||||
|
//Feature f = FileUtil.doConstructor((URLClassLoader) this.getClassLoader(), modClass, this);
|
||||||
Feature f = moduleClassLoader.doConstructor(modClass, this);
|
Feature f = moduleClassLoader.doConstructor(modClass, this);
|
||||||
if (f == null)
|
if (f == null)
|
||||||
continue;
|
continue;
|
||||||
@ -82,10 +100,6 @@ public class MarwCore extends JavaPlugin {
|
|||||||
this.addFeature(f);
|
this.addFeature(f);
|
||||||
this.getLogger().log(Level.INFO, "Loaded " + f.getName() + " @ " + modClass);
|
this.getLogger().log(Level.INFO, "Loaded " + f.getName() + " @ " + modClass);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void loadAndEnableModules() {
|
|
||||||
this.loadModules();
|
|
||||||
configManager.load();
|
configManager.load();
|
||||||
this.features.forEach((k, v) -> v.onEnable());
|
this.features.forEach((k, v) -> v.onEnable());
|
||||||
}
|
}
|
||||||
@ -114,6 +128,10 @@ public class MarwCore extends JavaPlugin {
|
|||||||
return this.getDataFolder().toPath().resolve("modules");
|
return this.getDataFolder().toPath().resolve("modules");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Path getLibsFolderPath() {
|
||||||
|
return this.getDataFolder().toPath().resolve("libs");
|
||||||
|
}
|
||||||
|
|
||||||
public ModuleClassLoader getModuleClassLoader() {
|
public ModuleClassLoader getModuleClassLoader() {
|
||||||
return this.moduleClassLoader;
|
return this.moduleClassLoader;
|
||||||
}
|
}
|
||||||
@ -141,7 +159,7 @@ public class MarwCore extends JavaPlugin {
|
|||||||
props
|
props
|
||||||
);
|
);
|
||||||
|
|
||||||
String method = cfg.getString("method");
|
String method = cfg.getString("dataSource.method");
|
||||||
if (method.equalsIgnoreCase("mariadb")) {
|
if (method.equalsIgnoreCase("mariadb")) {
|
||||||
this.sqlStorage = new SQLStorage(new MariaDbConnectionFactory(creds));
|
this.sqlStorage = new SQLStorage(new MariaDbConnectionFactory(creds));
|
||||||
} else if (method.equalsIgnoreCase("mysql")) {
|
} else if (method.equalsIgnoreCase("mysql")) {
|
||||||
|
@ -15,8 +15,8 @@ public class ModuleClassLoader extends URLClassLoader {
|
|||||||
|
|
||||||
private ArrayList<JarFile> jars = new ArrayList<>();
|
private ArrayList<JarFile> jars = new ArrayList<>();
|
||||||
|
|
||||||
public ModuleClassLoader() {
|
public ModuleClassLoader(ClassLoader parent) {
|
||||||
super(new URL[] { }, ModuleClassLoader.class.getClassLoader());
|
super(new URL[] { }, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFile(File file) throws IOException {
|
public void addFile(File file) throws IOException {
|
||||||
|
99
src/cz/marwland/mc/core/util/FileUtil.java
Normal file
99
src/cz/marwland/mc/core/util/FileUtil.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package cz.marwland.mc.core.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import cz.marwland.mc.core.features.Feature;
|
||||||
|
|
||||||
|
public class FileUtil {
|
||||||
|
|
||||||
|
public static String readFileFromJAR(Class<?> parent, String path) throws IOException {
|
||||||
|
InputStream in = parent.getResourceAsStream(path);
|
||||||
|
if (in == null) {
|
||||||
|
System.err.println("Invalid path: " + path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = in.read(buffer)) != -1) {
|
||||||
|
result.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
String ret = result.toString(StandardCharsets.UTF_8.name() );
|
||||||
|
in.close();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addFromDirectory(URLClassLoader cl, File modDir) {
|
||||||
|
if (!modDir.isDirectory())
|
||||||
|
throw new IllegalArgumentException("Provided 'modDir' argument is not a directory: " + modDir.getPath());
|
||||||
|
|
||||||
|
for (File mod : modDir.listFiles()) {
|
||||||
|
if (mod.isDirectory())
|
||||||
|
continue;
|
||||||
|
int lastdot = mod.getName().lastIndexOf('.');
|
||||||
|
if (lastdot < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!mod.getName().substring(lastdot + 1).equalsIgnoreCase("jar"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{ URL.class });
|
||||||
|
method.setAccessible(true);
|
||||||
|
method.invoke(cl, new Object[]{ mod.toURI().toURL() });
|
||||||
|
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | MalformedURLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println(">>> Loaded: " + mod.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Feature doConstructor(ClassLoader cl, String classPath)
|
||||||
|
throws ClassNotFoundException, ClassCastException, IllegalAccessException, InstantiationException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||||
|
Class<?> jarClass;
|
||||||
|
jarClass = Class.forName(classPath, true, cl);
|
||||||
|
|
||||||
|
Class<? extends Feature> pluginClass;
|
||||||
|
pluginClass = jarClass.asSubclass(Feature.class);
|
||||||
|
|
||||||
|
return pluginClass.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Feature doConstructor(ClassLoader cl, String classPath, JavaPlugin plugin) {
|
||||||
|
try {
|
||||||
|
return doConstructor(cl, classPath);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Cannot find class '" + classPath + "'!");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Class '" + classPath + "' does not extend Feature!");
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "No public constructor in '" + classPath + "'!");
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Cannot instantiate '" + classPath + "'!");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Illegal arguments to the constructor of '" + classPath + "'!");
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Error occured whilst initializing '" + classPath + "'!");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "Class '" + classPath + "' does not have a public constructor!");
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
plugin.getLogger().log(Level.SEVERE, "SecurityException occured whilst initializing '" + classPath + "'!");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user