diff --git a/inc/libplugin.h b/inc/libplugin.h index eca3ab0..6f2959d 100644 --- a/inc/libplugin.h +++ b/inc/libplugin.h @@ -1,6 +1,7 @@ #pragma once #include +#include #define DEBUG 1 @@ -16,6 +17,7 @@ extern jclass MAPCLASS; extern jclass LISTENERCLASS; extern jfieldID EVENTDATAF; extern jfieldID EVENTNAMEF; +extern jfieldID PLUGINIDF; extern jmethodID MAPGET; extern jmethodID MAPPUT; extern jmethodID MAPCLEAR; @@ -31,11 +33,12 @@ enum JNIDATA : long { JNI_LISTENERCLASS = 8, JNI_EVENTDATAFIELD = 16 | JNI_EVENTCLASS, JNI_EVENTNAMEFIELD = 32 | JNI_EVENTCLASS, - JNI_MAPGETMETH = 64 | JNI_MAPCLASS, - JNI_MAPPUTMETH = 128 | JNI_MAPCLASS, - JNI_MAPCLEARMETH = 256 | JNI_MAPCLASS, - JNI_LISTENERCONSTR = 512 | JNI_LISTENERCLASS, - JNI_LISTENERSMALLCONSTR = 1024 | JNI_LISTENERCLASS, + JNI_PLUGINIDFIELD = 64 | JNI_PLUGINCLASS, + JNI_MAPGETMETH = 128 | JNI_MAPCLASS, + JNI_MAPPUTMETH = 256 | JNI_MAPCLASS, + JNI_MAPCLEARMETH = 512 | JNI_MAPCLASS, + JNI_LISTENERCONSTR = 1024 | JNI_LISTENERCLASS, + JNI_LISTENERSMALLCONSTR = 2048 | JNI_LISTENERCLASS, JNI_EVENT = JNI_EVENTCLASS | JNI_EVENTDATAFIELD | JNI_EVENTNAMEFIELD, JNI_MAP = JNI_MAPCLASS | JNI_MAPGETMETH | JNI_MAPPUTMETH, @@ -49,4 +52,6 @@ long operator|(long a, JNIDATA b); long operator&(long a, JNIDATA b);*/ class CppPlugin; -extern CppPlugin* plugin; //what happens, with more than one plugin? +extern std::vector plugins; + +CppPlugin* getPlugin(JNIEnv* env = 0, jobject thisobj = 0, int id = -1); \ No newline at end of file diff --git a/inc/plugin.h b/inc/plugin.h index 4c5f2ca..03b9e70 100644 --- a/inc/plugin.h +++ b/inc/plugin.h @@ -16,6 +16,7 @@ typedef CppPlugin* (*initfptr)(); class CppPlugin { public: void* handle; + std::string name; virtual void onLoad(); virtual void onEnable(); virtual void onDisable(); @@ -23,4 +24,3 @@ public: virtual ~CppPlugin(); }; - diff --git a/src/main/cpp/src/libplugin.cpp b/src/main/cpp/src/libplugin.cpp index 0fda318..7d09b13 100644 --- a/src/main/cpp/src/libplugin.cpp +++ b/src/main/cpp/src/libplugin.cpp @@ -3,6 +3,7 @@ #include #include //dynamic linking +#include //basename #include //thread id @@ -15,15 +16,15 @@ jclass MAPCLASS; jclass LISTENERCLASS; jfieldID EVENTDATAF; jfieldID EVENTNAMEF; +jfieldID PLUGINIDF; jmethodID MAPGET; jmethodID MAPPUT; jmethodID MAPCLEAR; jmethodID LISTENERCONTR; jmethodID LISTENERSMALLCONTR; -CppPlugin* plugin; //what happens, with more than one plugin? - - +std::vector plugins; +/* void fixcap(JNIEnv* env) { DEB("ensure 1024" ); env->EnsureLocalCapacity(1024); @@ -31,6 +32,15 @@ void fixcap(JNIEnv* env) { DEB("push frame 1024" ); env->PushLocalFrame(1024); +}*/ + +CppPlugin* getPlugin(JNIEnv* env, jobject thisobj, int id) { + //get id + if(id < 0) { + load(env, JNI_PLUGINIDFIELD); + id = env->GetIntField(thisobj, PLUGINIDF); + } + return plugins.at(id); } void load(JNIEnv* env, long data) { @@ -42,13 +52,15 @@ void load(JNIEnv* env, long data) { MAPCLASS = env->FindClass("java/util/Map"); if(data & JNI_LISTENERCLASS) LISTENERCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin$CppListener"); - DEB("find classes: " << (!!CPPPLUGINCLASS) << (!!EVENTCLASS) << (!!MAPCLASS) << (!!LISTENERCLASS)); + if(data & JNI_EVENTDATAFIELD) EVENTDATAF = env->GetFieldID(EVENTCLASS, "data", "Ljava/util/Map;"); if(data & JNI_EVENTNAMEFIELD) EVENTNAMEF = env->GetFieldID(EVENTCLASS, "name", "Ljava/lang/String;"); - DEB("findfields: " << (!!EVENTDATAF) << (!!EVENTNAMEF)); + if(data & JNI_PLUGINIDFIELD) + PLUGINIDF = env->GetFieldID(CPPPLUGINCLASS, "id", "I"); + if(data & JNI_MAPGETMETH) MAPGET = env->GetMethodID(MAPCLASS, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); @@ -61,7 +73,16 @@ void load(JNIEnv* env, long data) { if(data & JNI_LISTENERSMALLCONSTR) LISTENERSMALLCONTR = env->GetMethodID(LISTENERCLASS, "", "()V"); - DEB("find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!MAPCLEAR) << (!!LISTENERCONTR) << (!!LISTENERSMALLCONTR)); + + if(((!CPPPLUGINCLASS) + (!EVENTCLASS) + (!MAPCLASS) + (!LISTENERCLASS) //wenn eins == nullptr ist -> wird zu 1 -> endergebniss != 0 -> fehler + + (!EVENTDATAF) + (!EVENTNAMEF) + (!PLUGINIDF) + + (!MAPGET) + (!MAPPUT) + (!MAPCLEAR) + (!LISTENERCONTR) + (!LISTENERSMALLCONTR)) == 0) { + + DEB("Error loading a information: "); + DEB("find classes: " << (!!CPPPLUGINCLASS) << (!!EVENTCLASS) << (!!MAPCLASS) << (!!LISTENERCLASS)); + DEB("findfields: " << (!!EVENTDATAF) << (!!EVENTNAMEF) << (!!PLUGINIDF)); + DEB("find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!MAPCLEAR) << (!!LISTENERCONTR) << (!!LISTENERSMALLCONTR)); + } } JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_init_1(JNIEnv* env, jobject thisobj) { @@ -95,11 +116,20 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEn return false; } - plugin = initf(); + CppPlugin* plugin = initf(); plugin->handle = handle; - - //store data - //setData(data, env, thisobj); + + //set name / handle id + plugin->name = std::string(cpath); + plugin->name = plugin->name.substr(plugin->name.rfind('/')); + + // add to vector + plugins.push_back(plugin); + + //store id + load(env, JNI_PLUGINIDFIELD); + env->SetIntField(thisobj, PLUGINIDF, plugins.size()-1); + return (bool) plugin; // converted to boolean here } @@ -109,9 +139,8 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEn * Signature: ()V */ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onLoad(JNIEnv* env, jobject thisobj) { - //TODO DEB("lib::onLoad()"); - plugin->onLoad(); + getPlugin(env, thisobj)->onLoad(); } /* @@ -120,9 +149,8 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onLoad(JNIEnv* env, * Signature: ()V */ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onEnable_1(JNIEnv* env, jobject thisobj) { - //TODO DEB("lib::onEnable()"); - plugin->onEnable(); + getPlugin(env, thisobj)->onEnable(); } /* @@ -133,6 +161,7 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onEnable_1(JNIEnv* e JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv* env, jobject thisobj) { //TODO DEB("lib::onDisable()" ); + CppPlugin* plugin = getPlugin(env, thisobj); plugin->onDisable(); dlclose(plugin->handle); } @@ -158,7 +187,7 @@ JNIEXPORT jobject JNICALL Java_de_mrbesen_cppplugins_CppPlugin_fireEvent(JNIEnv* Event event(env, jevent); //call it - f(env, plugin, &event); + f(env, getPlugin(env, thisobj), &event); //put changed fields back in the jevent event.reapply(env, jevent); @@ -185,7 +214,7 @@ JNIEXPORT jobjectArray JNICALL Java_de_mrbesen_cppplugins_CppPlugin_getListener( load(env, JNI_LISTENER); //call getEvents - std::map events = plugin->getEvents(); + std::map events = getPlugin(env, thisobj)->getEvents(); DEB("found " << events.size() << " Events"); //create array diff --git a/src/main/cpp/src/plugin.cpp b/src/main/cpp/src/plugin.cpp index cfdfbef..9ef165f 100644 --- a/src/main/cpp/src/plugin.cpp +++ b/src/main/cpp/src/plugin.cpp @@ -1,5 +1,7 @@ #include +#include + void CppPlugin::onLoad() { } @@ -13,6 +15,7 @@ void CppPlugin::onDisable() { } std::map CppPlugin::getEvents() { + std::cout << "Defaults::getEvents()" << std::endl; return std::map(); } diff --git a/src/main/java/de/mrbesen/cppplugins/CppEvent.java b/src/main/java/de/mrbesen/cppplugins/CppEvent.java index e95f56f..6b38b19 100644 --- a/src/main/java/de/mrbesen/cppplugins/CppEvent.java +++ b/src/main/java/de/mrbesen/cppplugins/CppEvent.java @@ -2,25 +2,28 @@ package de.mrbesen.cppplugins; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.bukkit.Bukkit; import org.bukkit.event.Event; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; +import java.util.logging.Logger; @RequiredArgsConstructor public class CppEvent { + @Getter private final String name; - Map data = new HashMap<>(); - + private Map data = new HashMap<>(); + private static Logger log = Bukkit.getLogger(); public static CppEvent cppify(Event e) { - System.out.println("cppifying event: " + e.getClass().getSimpleName()); + log.info("cppifying event: " + e.getClass().getSimpleName()); CppEvent cppe = new CppEvent(e.getClass().getSimpleName()); for(Field field : e.getClass().getDeclaredFields()) { - System.out.println("try to read Field: " + field.getName()); + log.fine("try to read Field: " + field.getName()); if(!field.isAccessible()) field.setAccessible(true); try { @@ -34,19 +37,19 @@ public class CppEvent { } public static void uncppify(CppEvent cppe, Event original) { - System.out.println("uncppifying event: " + original.getClass().getSimpleName() + " values: " + cppe.data.size()); + log.info("uncppifying event: " + original.getClass().getSimpleName() + " values: " + cppe.data.size()); if(!original.getClass().getSimpleName().equals(cppe.name)) throw new IllegalArgumentException("CppEvent does not match original event type!"); for(Field field : original.getClass().getDeclaredFields()) { - System.out.println("try to set Field: " + field.getName()); + log.fine("try to set Field: " + field.getName()); Object value = cppe.data.get(field.getName()); if(value == null) { - System.out.println("Data not available - skip"); + log.fine("Data not available - skip"); continue; } - System.out.println("value: " + value); + log.fine("value: " + value); if(!field.isAccessible()) field.setAccessible(true); @@ -56,6 +59,5 @@ public class CppEvent { e.printStackTrace(); } } - } } diff --git a/src/main/java/de/mrbesen/cppplugins/CppLoader.java b/src/main/java/de/mrbesen/cppplugins/CppLoader.java index baf1f50..f06841c 100644 --- a/src/main/java/de/mrbesen/cppplugins/CppLoader.java +++ b/src/main/java/de/mrbesen/cppplugins/CppLoader.java @@ -44,7 +44,7 @@ public class CppLoader implements PluginLoader { @Override public Plugin loadPlugin(File file) throws InvalidPluginException, UnknownDependencyException { - System.out.println("try to load: " + file.getName()); + log.info("try to load: " + file.getName()); return new CppPlugin(file, this); } @@ -61,11 +61,11 @@ public class CppLoader implements PluginLoader { @Override public Map, Set> createRegisteredListeners(Listener listenerabcdeg, Plugin plugin) { - System.out.println("register Listener for: " + plugin.getName()); + log.info("register Listener for: " + plugin.getName()); CppPlugin.CppListener[] listener = ((CppPlugin) plugin).getListener(); Map, Set> out = new HashMap<>(); - System.out.println("found " + listener.length + " Events"); + log.fine("found " + listener.length + " Events"); for(CppPlugin.CppListener lis : listener) { if(lis.functionid == 0) continue; @@ -73,11 +73,11 @@ public class CppLoader implements PluginLoader { //search for Class Class clas = findClass(lis.eventfilter); if(clas == null) { - System.out.println("Class " + lis.eventfilter + " is unknown event"); + log.warning("Class " + lis.eventfilter + " is unknown event"); continue; } - System.out.println("register event " + clas.getName() + " for function: " + lis.functionid ); + log.fine("register event " + clas.getName() + " for function: " + lis.functionid ); AdapterExecutor adapt = new AdapterExecutor((CppPlugin) plugin, lis.functionid); Bukkit.getPluginManager().registerEvent(clas, lis, EventPriority.NORMAL, adapt, plugin, true); diff --git a/src/main/java/de/mrbesen/cppplugins/CppPlugin.java b/src/main/java/de/mrbesen/cppplugins/CppPlugin.java index e5dfd98..f8cae69 100644 --- a/src/main/java/de/mrbesen/cppplugins/CppPlugin.java +++ b/src/main/java/de/mrbesen/cppplugins/CppPlugin.java @@ -18,12 +18,13 @@ import java.util.List; import java.util.logging.Logger; public class CppPlugin implements Plugin { + private boolean enabled = false; @Getter private String name; private static boolean initdone = false; private CppLoader loader; - private long data; //for JNI, do not remove + private int id; //for JNI, do not remove //library operations protected native boolean init_(); //false: failed, true: success @@ -56,7 +57,7 @@ public class CppPlugin implements Plugin { File folder = CppPlugins.getInstance().getDataFolder(); folder.mkdirs(); String path = folder.getAbsolutePath() + "/libplugin.so"; - System.out.println("load library from: " + path); + getLogger().info("load library from: " + path); try { System.load(path); return init_(); @@ -149,7 +150,7 @@ public class CppPlugin implements Plugin { @Override public Logger getLogger() { - return null; + return Logger.getLogger(getName().substring(0, 3)); } @Override diff --git a/src/main/java/de/mrbesen/cppplugins/CppPlugins.java b/src/main/java/de/mrbesen/cppplugins/CppPlugins.java index caa7c92..c964f72 100644 --- a/src/main/java/de/mrbesen/cppplugins/CppPlugins.java +++ b/src/main/java/de/mrbesen/cppplugins/CppPlugins.java @@ -6,12 +6,11 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; +import java.util.function.Consumer; import java.util.logging.Level; public class CppPlugins extends JavaPlugin { - public static String testplugin = "simpleevents.so"; - @Getter private static CppPlugins instance; @@ -24,14 +23,25 @@ public class CppPlugins extends JavaPlugin { Bukkit.getPluginManager().registerInterface(CppLoader.class); getLogger().info("registered"); - try { - Bukkit.getPluginManager().loadPlugin(new File("plugins/" + testplugin)); //TODO: do loading in another way - System.out.println("loaded " + testplugin); - - //TODO: trigger onLoad in those Plugins - } catch (Throwable e) { - getLogger().log(Level.SEVERE, "Error ocoured during loading " + testplugin, e); + File pluginsFolder = new File("plugins/"); + File[] pluginFiles = pluginsFolder.listFiles((dir, name) -> name.endsWith(".so")); + for(File pluginFile : pluginFiles) { + try { + Bukkit.getPluginManager().loadPlugin(pluginFile); + System.out.println("loaded " + pluginFile.getName()); + } catch (Throwable e) { + getLogger().log(Level.SEVERE, "Error occurred during loading in plugin: " + pluginFile.getName(), e); + } } + + //trigger on Load + forEach(pl -> { + try { + pl.onLoad(); + } catch (Throwable t) { + getLogger().log(Level.WARNING, "Error in onLoad() of Plugin: " + pl.getName(), t); + } + }); } @Override @@ -46,4 +56,14 @@ public class CppPlugins extends JavaPlugin { } } } + + //iteratoe over all CppPlugins + public void forEach(Consumer cons) { + Plugin[] pls = Bukkit.getPluginManager().getPlugins(); + for (int i = 0; i < pls.length; i++) { + if(pls[i] instanceof CppPlugin) { + cons.accept((CppPlugin) pls[i]); + } + } + } } diff --git a/testplugins/simpleEvents/src/plugin.cpp b/testplugins/simpleEvents/src/plugin.cpp index 656b692..8f0ea65 100644 --- a/testplugins/simpleEvents/src/plugin.cpp +++ b/testplugins/simpleEvents/src/plugin.cpp @@ -6,7 +6,7 @@ extern "C" { -class MyPlugin : public CppPlugin { +class EventsPlugin : public CppPlugin { public: virtual void onLoad(); virtual void onEnable(); @@ -14,21 +14,21 @@ public: virtual std::map getEvents(); }; -void MyPlugin::onLoad() { - std::cout << "onload();" << std::endl; +void EventsPlugin::onLoad() { + std::cout << "Events::onload();" << std::endl; } -void MyPlugin::onEnable() { - std::cout << "onEnable();" << std::endl; +void EventsPlugin::onEnable() { + std::cout << "Events::onEnable();" << std::endl; } -void MyPlugin::onDisable() { - std::cout << "onDisable();" << std::endl; +void EventsPlugin::onDisable() { + std::cout << "Events::onDisable();" << std::endl; } CppPlugin* init() { std::cout << "init im plugin!" << std::endl; - return new MyPlugin(); + return new EventsPlugin(); } void eventJoin(JNIEnv* env, CppPlugin* pl, Event* e) { @@ -43,8 +43,8 @@ void eventQuit(JNIEnv* env, CppPlugin* pl, Event* e) { std::cout << "quit " << e->getName() << std::endl; } -std::map MyPlugin::getEvents() { - std::cout << "MyPlugin::getEvents" << std::endl; +std::map EventsPlugin::getEvents() { + std::cout << "EventsPlugin::getEvents" << std::endl; std::map out; out.insert({"PlayerJoinEvent", eventJoin}); out.insert({"PlayerQuitEvent", eventQuit}); diff --git a/testplugins/verysimpleplugin/src/plugin.cpp b/testplugins/verysimpleplugin/src/plugin.cpp index 3f03e10..b8d2f1e 100644 --- a/testplugins/verysimpleplugin/src/plugin.cpp +++ b/testplugins/verysimpleplugin/src/plugin.cpp @@ -6,7 +6,7 @@ extern "C" { -class MyPlugin : public CppPlugin { +class SimplePlugin : public CppPlugin { public: virtual void onLoad(); virtual void onEnable(); @@ -14,21 +14,21 @@ public: //virtual std::map getEvents(); }; -void MyPlugin::onLoad() { +void SimplePlugin::onLoad() { std::cout << "onload();" << std::endl; } -void MyPlugin::onEnable() { +void SimplePlugin::onEnable() { std::cout << "onEnable();" << std::endl; } -void MyPlugin::onDisable() { +void SimplePlugin::onDisable() { std::cout << "onDisable();" << std::endl; } CppPlugin* init() { std::cout << "init im plugin!" << std::endl; - return new MyPlugin(); + return new SimplePlugin(); } }//extern "C" \ No newline at end of file