242 lines
6.2 KiB
C++
242 lines
6.2 KiB
C++
#include "de_mrbesen_cppplugins_CppPlugin.h"
|
|
#include "de_mrbesen_cppplugins_CppPlugin_CppListener.h"
|
|
|
|
#include <iostream>
|
|
#include <dlfcn.h> //dynamic linking
|
|
|
|
#include <thread> //thread id
|
|
|
|
#include "libplugin.h"
|
|
#include "plugin.h"
|
|
|
|
jclass CPPPLUGINCLASS;
|
|
jclass EVENTCLASS;
|
|
jclass MAPCLASS;
|
|
jclass LISTENERCLASS;
|
|
jfieldID EVENTDATAF;
|
|
jfieldID EVENTNAMEF;
|
|
jmethodID MAPGET;
|
|
jmethodID MAPPUT;
|
|
jmethodID LISTENERCONTR;
|
|
jmethodID LISTENERSMALLCONTR;
|
|
|
|
CppPlugin* plugin; //what happens, with more than one plugin?
|
|
|
|
/*
|
|
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
|
|
DEB("onload" );
|
|
JNIEnv* env;
|
|
vm->GetEnv((void**) &env, JNI_VERSION_1_8);
|
|
|
|
|
|
return JNI_VERSION_1_8;
|
|
}*/
|
|
|
|
void fixcap(JNIEnv* env) {
|
|
DEB("ensure 1024" );
|
|
env->EnsureLocalCapacity(1024);
|
|
|
|
DEB("push frame 1024" );
|
|
env->PushLocalFrame(1024);
|
|
|
|
}
|
|
/*
|
|
operator long()(JNIDATA d) {
|
|
return (long) d;
|
|
}
|
|
|
|
long operator|(JNIDATA a, JNIDATA b) {
|
|
return (long) a | (long) b;
|
|
}
|
|
|
|
long operator|(long a, JNIDATA b) {
|
|
return a | (long) b;
|
|
}
|
|
|
|
long operator&(long a, JNIDATA b) {
|
|
return a & (long) b;
|
|
}*/
|
|
|
|
void load(JNIEnv* env, long data) {
|
|
|
|
DEB("loading with mask: " << data);
|
|
|
|
|
|
if(data & JNI_PLUGINCLASS)
|
|
CPPPLUGINCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin");
|
|
if(data & JNI_EVENTCLASS)
|
|
EVENTCLASS = env->FindClass("de/mrbesen/cppplugins/CppEvent");
|
|
if(data & JNI_MAPCLASS)
|
|
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_MAPGETMETH)
|
|
MAPGET = env->GetMethodID(MAPCLASS, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
|
if(data & JNI_MAPPUTMETH)
|
|
MAPPUT = env->GetMethodID(MAPCLASS, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
|
if(data & JNI_LISTENERCONSTR)
|
|
LISTENERCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "(Ljava/lang/String;J)V");
|
|
if(data & JNI_LISTENERSMALLCONSTR)
|
|
LISTENERSMALLCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "()V");
|
|
|
|
DEB("find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!LISTENERCONTR) << (!!LISTENERSMALLCONTR));
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_init_1(JNIEnv* env, jobject thisobj) {
|
|
load(env, JNI_ALL);
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: loadPlugin
|
|
* Signature: (Ljava/lang/String;)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEnv* env, jobject thisobj, jstring path) {
|
|
const char* cpath = env->GetStringUTFChars(path, 0);
|
|
|
|
//open plugin
|
|
DEB("open plugin " << cpath );
|
|
void* handle = dlopen(cpath, RTLD_LAZY);
|
|
if (!handle) {
|
|
std::cout << "could not create handle of: " << cpath << " error: " << dlerror() << std::endl;
|
|
return false;
|
|
}
|
|
//throw std::string("Error: plugin could not be opend. ") + dlerror();
|
|
|
|
//load function pointer
|
|
initfptr initf = (initfptr) dlsym(handle, "init");
|
|
if(!initf) {
|
|
std::cout << "Could not find function init: " << dlerror() << std::endl;
|
|
dlclose(handle);
|
|
return false;
|
|
}
|
|
|
|
plugin = initf();
|
|
plugin->handle = handle;
|
|
|
|
//store data
|
|
//setData(data, env, thisobj);
|
|
DEB("plugin: " << (bool)plugin);
|
|
return (bool) plugin; // converted to boolean here
|
|
}
|
|
|
|
/*
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: onLoad
|
|
* Signature: ()V
|
|
*/
|
|
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onLoad(JNIEnv* env, jobject thisobj) {
|
|
//TODO
|
|
DEB("lib::onLoad()");
|
|
plugin->onLoad();
|
|
}
|
|
|
|
/*
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: onEnable_
|
|
* Signature: ()V
|
|
*/
|
|
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onEnable_1(JNIEnv* env, jobject thisobj) {
|
|
//TODO
|
|
DEB("lib::onEnable()");
|
|
plugin->onEnable();
|
|
}
|
|
|
|
/*
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: onDisable_
|
|
* Signature: ()V
|
|
*/
|
|
JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv* env, jobject thisobj) {
|
|
//TODO
|
|
DEB("lib::onDisable()" );
|
|
plugin->onDisable();
|
|
dlclose(plugin->handle);
|
|
}
|
|
|
|
/*
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: fireEvent
|
|
* Signature: (Lde/mrbesen/cppplugins/CppEvent;I)Lde/mrbesen/cppplugins/CppEvent;
|
|
*/
|
|
JNIEXPORT jobject JNICALL Java_de_mrbesen_cppplugins_CppPlugin_fireEvent(JNIEnv* env, jobject thisobj, jobject jevent, jlong functionid) {
|
|
DEB("lib::fireEvent()" );
|
|
if(functionid == 0) {
|
|
DEB("invalid function id");
|
|
return jevent;
|
|
}
|
|
|
|
load(env, JNI_EVENT | JNI_MAP);
|
|
|
|
//cast function
|
|
eventfptr f = reinterpret_cast<eventfptr>(functionid);
|
|
|
|
//cast event
|
|
Event event(env, jevent);
|
|
|
|
//call it
|
|
f(plugin, &event);
|
|
|
|
//put changed fields back in the jevent
|
|
event.reapply(env, jevent);
|
|
|
|
return jevent;
|
|
}
|
|
|
|
/*
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: onCmd
|
|
* Signature: (Lorg/bukkit/command/CommandSender;Lorg/bukkit/command/Command;Ljava/lang/String;[Ljava/lang/String;)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onCmd(JNIEnv* env, jobject thisobj, jobject sender, jobject cmd, jstring label, jobjectArray args) {
|
|
//TODO
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Class: de_mrbesen_cppplugins_CppPlugin
|
|
* Method: getListener
|
|
* Signature: ()[Lde/mrbesen/cppplugins/CppPlugin/CppListener;
|
|
*/
|
|
JNIEXPORT jobjectArray JNICALL Java_de_mrbesen_cppplugins_CppPlugin_getListener(JNIEnv* env, jobject thisobj) {
|
|
load(env, JNI_LISTENER);
|
|
|
|
//call getEvents
|
|
std::map<std::string, eventfptr> events = plugin->getEvents();
|
|
DEB("found " << events.size() << " Events");
|
|
|
|
//create array
|
|
jobject initial = env->NewObject(LISTENERCLASS, LISTENERSMALLCONTR);
|
|
jobjectArray arr = env->NewObjectArray(events.size(), LISTENERCLASS, initial);
|
|
|
|
DEB("populate array");
|
|
//populate array
|
|
int i = 0;
|
|
for(auto it : events) {
|
|
//create object
|
|
jstring eventname = env->NewStringUTF(it.first.c_str());
|
|
jobject listener = env->NewObject(LISTENERCLASS, LISTENERCONTR, eventname, it.second);
|
|
env->DeleteLocalRef(eventname);
|
|
|
|
//set array
|
|
env->SetObjectArrayElement(arr, i++, listener);
|
|
}
|
|
|
|
DEB("Array finished");
|
|
|
|
return arr;
|
|
}
|
|
|