endlich
This commit is contained in:
parent
4c8cf080e7
commit
e0407d9f5f
|
@ -5,3 +5,8 @@ target
|
|||
*.jar
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
#eclipse stuff
|
||||
.cproject
|
||||
.project
|
||||
.settings/
|
4
Makefile
4
Makefile
|
@ -3,7 +3,7 @@ CFLAGS = -Wall -pedantic-errors -std=c++17 -g #-O2
|
|||
SRCDIR = src/main/cpp/src/
|
||||
BUILDDIR = target/
|
||||
INCDIR = src/main/cpp/inc/
|
||||
LDFLAGS = -I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -I$(INCDIR) -Iinc/
|
||||
LDFLAGS = -I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -I$(INCDIR) -Iinc/ #-ldl
|
||||
NAME = libplugin.so
|
||||
|
||||
SRCFILES = $(wildcard $(SRCDIR)*.cpp)
|
||||
|
@ -12,7 +12,7 @@ OBJFILES = $(patsubst $(SRCDIR)%, $(BUILDDIR)%, $(patsubst %.cpp,%.so,$(SRCFILES
|
|||
all: createhfiles $(BUILDDIR)$(NAME)
|
||||
|
||||
$(BUILDDIR)%.so: $(SRCDIR)%.cpp $(BUILDDIR)
|
||||
$(CXX) -fPIC -shared $(CFLAGS) $(SRCDIR)$*.cpp $(LDFLAGS) -o $@
|
||||
$(CXX) -fPIC -shared $(CFLAGS) $(SRCDIR)*.cpp -o $@ $(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)%: $(SRCDIR)%.cpp $(BUILDDIR)
|
||||
$(CXX) $(CFLAGS) $(SRCDIR)$*.cpp -o $@
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
class CppPlugin {
|
||||
public:
|
||||
virtual void onLoad() = 0;
|
||||
virtual void onEnable() = 0;
|
||||
virtual void onDisable() = 0;
|
||||
};
|
||||
|
||||
|
||||
typedef CppPlugin* (*initfptr)();
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
#include <jni.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
//extern "C" {
|
||||
|
||||
jclass CPPPLUGINCLASS;
|
||||
jclass EVENTCLASS;
|
||||
jclass MAPCLASS;
|
||||
jclass LISTENERCLASS;
|
||||
jfieldID EVENTDATAF;
|
||||
jfieldID EVENTNAMEF;
|
||||
jmethodID MAPGET;
|
||||
jmethodID MAPPUT;
|
||||
jmethodID LISTENERCONTR;
|
||||
|
||||
CppPlugin* plugin; //what happens, with more than one plugin?
|
||||
|
||||
//} //extern "C"
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
#include <jni.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class CppPlugin {
|
||||
public:
|
||||
void* handle;
|
||||
virtual void onLoad() = 0;
|
||||
virtual void onEnable() = 0;
|
||||
virtual void onDisable() = 0;
|
||||
//virtual ~CppPlugin();
|
||||
};
|
||||
|
||||
class Event {
|
||||
private:
|
||||
std::string name; //name of the event
|
||||
jobject input; //original Event object (type CppEvent)
|
||||
std::map<std::string, void*> data;
|
||||
public:
|
||||
jobject getMap(JNIEnv* env);
|
||||
const std::string& getName();
|
||||
void* getData(JNIEnv* env, const std::string& name);
|
||||
void setData(const std::string& name, void* data);
|
||||
|
||||
void reapply(JNIEnv* env, jobject jevent);
|
||||
|
||||
Event(JNIEnv* env, jobject jevent);
|
||||
//virtual ~Event();
|
||||
};
|
||||
|
||||
//function pointer
|
||||
typedef void (*eventfptr)(CppPlugin*, Event*);
|
||||
typedef std::map<std::string, eventfptr> (*getEventsfptr)();
|
||||
typedef CppPlugin* (*initfptr)();
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
mvn package
|
||||
rm target/*.so
|
||||
make -j1 all #that makefile is not paralllizable
|
||||
mkdir -p testserver/plugins/CppPlugins
|
||||
cp target/Cppplugin-0.1-SNAPSHOT-final.jar testserver/plugins/
|
||||
|
|
|
@ -4,32 +4,28 @@
|
|||
#include <iostream>
|
||||
#include <dlfcn.h> //dynamic linking
|
||||
|
||||
#include "cppplugin.h" //plugin definitions
|
||||
#include <libplugin.h>
|
||||
|
||||
//jfieldID DATAFIELDID = 0;
|
||||
jclass CPPPLUGINCLASS = 0;
|
||||
CppPlugin* plugin = 0;
|
||||
|
||||
/*
|
||||
void setData(CppPlugin* d, JNIEnv* env, jobject thisobj) {
|
||||
std::cout << "set data: " << DATAFIELDID << std::endl;
|
||||
env->SetLongField(thisobj, DATAFIELDID, reinterpret_cast<jlong>(d));
|
||||
}
|
||||
|
||||
CppPlugin* getData(JNIEnv* env, jobject thisobj) {
|
||||
std::cout << "get data: " << DATAFIELDID << std::endl;
|
||||
return reinterpret_cast<CppPlugin*>(env->GetLongField(thisobj, DATAFIELDID));
|
||||
}*/
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_init_1(JNIEnv* env, jobject thisobj) {
|
||||
std::cout << "init!! aus cpp!!!" << std::endl;
|
||||
std::cout << "init libplugin loading java references, 1 = good, 0 = bad" << std::endl;
|
||||
|
||||
CPPPLUGINCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin");
|
||||
std::cout << "findclass: " << (!CPPPLUGINCLASS) << std::endl;
|
||||
//DATAFIELDID = env->GetFieldID(CPPPLUGINCLASS, "data", "J");
|
||||
//std::cout << "findfield " << (!DATAFIELDID) << std::endl;
|
||||
EVENTCLASS = env->FindClass("de/mrbesen/cppplugins/CppEvent");
|
||||
MAPCLASS = env->FindClass("java/util/Map");
|
||||
LISTENERCLASS = env->FindClass("de/mrbesen/cppplugins/CppPlugin$CppListener");
|
||||
std::cout << "find classes: " << (!!CPPPLUGINCLASS) << (!!EVENTCLASS) << (!!MAPCLASS) << (!!LISTENERCLASS) << std::endl;
|
||||
|
||||
return true;
|
||||
EVENTDATAF = env->GetFieldID(EVENTCLASS, "data", "Ljava/util/Map;");
|
||||
EVENTNAMEF = env->GetFieldID(EVENTCLASS, "name", "Ljava/lang/String;");
|
||||
std::cout << "findfields: " << (!!EVENTDATAF) << (!!EVENTNAMEF) << std::endl;
|
||||
|
||||
MAPGET = env->GetMethodID(MAPCLASS, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
MAPPUT = env->GetMethodID(MAPCLASS, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
LISTENERCONTR = env->GetMethodID(LISTENERCLASS, "<init>", "(Ljava/lang/String;J)V");
|
||||
std::cout << "find methods: " << (!!MAPGET) << (!!MAPPUT) << (!!LISTENERCONTR) << std::endl;
|
||||
|
||||
return ((!CPPPLUGINCLASS) + (!EVENTCLASS) + (!MAPCLASS) + (!EVENTDATAF) + (!EVENTNAMEF) + (!MAPGET) + (!MAPPUT) + (!LISTENERCONTR)) == 0; //one nullptr -> inverted to 1 -> ends up at end -> false
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,24 +40,27 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_loadPlugin(JNIEn
|
|||
//open plugin
|
||||
std::cout << "open plugin " << cpath << std::endl;
|
||||
void* handle = dlopen(cpath, RTLD_LAZY);
|
||||
if (!handle)
|
||||
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" << std::endl;
|
||||
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);
|
||||
|
||||
return true;
|
||||
std::cout << "plugin: " << (bool)plugin << std::endl;
|
||||
return (bool) plugin; // converted to boolean here
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -95,6 +94,7 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv*
|
|||
//TODO
|
||||
std::cout << "lib::onDisable()" << std::endl;
|
||||
plugin->onDisable();
|
||||
dlclose(plugin->handle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -102,9 +102,26 @@ JNIEXPORT void JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onDisable_1(JNIEnv*
|
|||
* 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 event, jint functionid) {
|
||||
//TODO
|
||||
return event;
|
||||
JNIEXPORT jobject JNICALL Java_de_mrbesen_cppplugins_CppPlugin_fireEvent(JNIEnv* env, jobject thisobj, jobject jevent, jlong functionid) {
|
||||
std::cout << "lib::fireEvent()" << std::endl;
|
||||
if(functionid == 0) {
|
||||
std::cout << "invalid function id" << std::endl;
|
||||
return jevent;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -123,7 +140,90 @@ JNIEXPORT jboolean JNICALL Java_de_mrbesen_cppplugins_CppPlugin_onCmd(JNIEnv* en
|
|||
* Signature: ()[Lde/mrbesen/cppplugins/CppPlugin/CppListener;
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL Java_de_mrbesen_cppplugins_CppPlugin_getListener(JNIEnv* env, jobject thisobj) {
|
||||
//call getEvents
|
||||
std::map<std::string, eventfptr> events;
|
||||
getEventsfptr getEventsf = (getEventsfptr) dlsym(plugin->handle, "getEvents");
|
||||
if(getEventsf) {
|
||||
//only non null
|
||||
events = getEventsf();
|
||||
}
|
||||
|
||||
//create array
|
||||
jclass clas = env->FindClass("de/mrbesen/cppplugins/CppPlugin/CppListener");
|
||||
jobjectArray arr = env->NewObjectArray(0, clas, 0);
|
||||
jobjectArray arr = env->NewObjectArray(events.size(), clas, 0);
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////// EVENTS
|
||||
|
||||
jobject Event::getMap(JNIEnv* env) {
|
||||
return env->GetObjectField(input, EVENTDATAF);
|
||||
}
|
||||
|
||||
const std::string& Event::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void* Event::getData(JNIEnv* env, const std::string& name) {
|
||||
std::cout << "Try to access " << name << std::endl;
|
||||
//search in map
|
||||
auto it = data.find(name);
|
||||
if(it == data.end()) {
|
||||
//search in original object
|
||||
//construct string
|
||||
jstring term = env->NewStringUTF(name.c_str());
|
||||
|
||||
//call data.get()
|
||||
jobject map = getMap(env);
|
||||
jobject content = env->CallObjectMethod(map, MAPGET, term);
|
||||
|
||||
//data.insert for next time
|
||||
data.insert({name, content});
|
||||
|
||||
//delete string
|
||||
env->DeleteLocalRef(term);
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Event::setData(const std::string& name, void* d) {
|
||||
//just put it in the map
|
||||
data.insert({name, d});
|
||||
}
|
||||
|
||||
void Event::reapply(JNIEnv* env, jobject jevent) {
|
||||
jobject map = getMap(env);
|
||||
for(auto it : data) {
|
||||
std::cout << "write back to java: " << it.first << std::endl;
|
||||
jstring key = env->NewStringUTF(it.first.c_str());
|
||||
|
||||
env->CallObjectMethod(map, MAPPUT, key, it.second);
|
||||
env->DeleteLocalRef(key);
|
||||
}
|
||||
}
|
||||
|
||||
Event::Event(JNIEnv* env, jobject jevent) {
|
||||
//get name
|
||||
jstring name = (jstring) env->GetObjectField(jevent, EVENTNAMEF);
|
||||
this->name = std::string(env->GetStringUTFChars(name, 0));
|
||||
input = jevent;
|
||||
}
|
|
@ -100,7 +100,7 @@ public class CppLoader implements PluginLoader {
|
|||
|
||||
private class AdapterExecutor implements EventExecutor {
|
||||
CppPlugin plugin;
|
||||
int functionid;
|
||||
long functionid;
|
||||
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package de.mrbesen.cppplugins;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
@ -35,7 +36,7 @@ public class CppPlugin implements Plugin {
|
|||
public native void onLoad();
|
||||
public native void onEnable_();
|
||||
public native void onDisable_();
|
||||
protected native CppEvent fireEvent(CppEvent e, int functionid);
|
||||
protected native CppEvent fireEvent(CppEvent e, long functionid);
|
||||
protected native boolean onCmd(CommandSender sender, Command cmd, String label, String[] args);
|
||||
|
||||
native CppListener[] getListener();
|
||||
|
@ -165,8 +166,9 @@ public class CppPlugin implements Plugin {
|
|||
return null;
|
||||
}
|
||||
|
||||
public class CppListener implements Listener {
|
||||
@AllArgsConstructor
|
||||
static class CppListener implements Listener {
|
||||
String eventfilter;
|
||||
int functionid;
|
||||
long functionid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@ package de.mrbesen.cppplugins;
|
|||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.InvalidPluginException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CppPlugins extends JavaPlugin {
|
||||
|
||||
|
@ -28,8 +27,8 @@ public class CppPlugins extends JavaPlugin {
|
|||
System.out.println("loaded verysimpleplugin.so");
|
||||
|
||||
//TODO: trigger onLoad in those Plugins
|
||||
} catch (InvalidDescriptionException | InvalidPluginException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable e) {
|
||||
getLogger().log(Level.SEVERE, "Error ocoured during loading verysimpleplugin.so", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
CFLAGS = -Wall -O2 -pedantic-errors -std=c++17 -g
|
||||
CFLAGS = -Wall -pedantic-errors -std=c++17 -g
|
||||
SRCDIR = src/
|
||||
INCDIR = ../../inc
|
||||
LDFLAGS = -I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -I$(INCDIR)
|
||||
LDFLAGS = -I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -I$(INCDIR) -I../../src/main/cpp/inc
|
||||
NAME = verysimpleplugin.so
|
||||
|
||||
all:
|
||||
g++ -fPIC -shared $(CFLAGS) $(SRCDIR)*.cpp $(LDFLAGS) -o $(NAME)
|
||||
g++ -fPIC -shared $(CFLAGS) $(SRCDIR)*.cpp $(LDFLAGS) ../../src/main/cpp/src/libplugin.cpp -o $(NAME)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "cppplugin.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#include <iostream>
|
||||
extern "C" {
|
||||
|
||||
extern "C" {
|
||||
|
||||
class MyPlugin : public CppPlugin {
|
||||
public:
|
||||
|
@ -28,4 +28,8 @@ CppPlugin* init() {
|
|||
return new MyPlugin();
|
||||
}
|
||||
|
||||
void eventJoin(CppPlugin* pl, Event* e) {
|
||||
std::cout << "join " << e->getName() << std::endl;
|
||||
}
|
||||
|
||||
}//extern "C"
|
Loading…
Reference in New Issue