void Shoebill::OnShoebillLoad() const { if (!callbackHandlerObject) return; JNIEnv *env; jvm->AttachCurrentThread((void **) &env, NULL); static jmethodID jmid = env->GetMethodID(callbackHandlerClass, "onShoebillLoad", "()V"); if (!jmid) return; env->CallVoidMethod(callbackHandlerObject, jmid); jni_jvm_printExceptionStack(env); }
void Shoebill::OnProcessTick() const { if (!callbackHandlerObject) return; JNIEnv *env = nullptr; jvm->AttachCurrentThread((void **) &env, nullptr); static auto jmid = env->GetMethodID(callbackHandlerClass, "onProcessTick", "()V"); if (!jmid) return; env->CallVoidMethod(callbackHandlerObject, jmid); jni_jvm_printExceptionStack(env); }
void Shoebill::OnAmxUnload(AMX *amx) const { AmxInstanceManager::GetInstance().UnregisterAmx(amx); if (!callbackHandlerObject) return; JNIEnv *env; jvm->AttachCurrentThread((void **) &env, NULL); static jmethodID jmid = env->GetMethodID(callbackHandlerClass, "onAmxUnload", "(I)V"); if (!jmid) return; env->CallVoidMethod(callbackHandlerObject, jmid, amx); jni_jvm_printExceptionStack(env); }
void Shoebill::OnAmxLoad(AMX *amx) const { amx_Register(amx, PluginExports, -1); AmxInstanceManager::GetInstance().RegisterAmx(amx); if (!callbackHandlerObject) return; JNIEnv *env; jvm->AttachCurrentThread((void **) &env, nullptr); static auto jmid = env->GetMethodID(callbackHandlerClass, "onAmxLoad", "(I)V"); if (!jmid) return; env->CallVoidMethod(callbackHandlerObject, jmid, amx); jni_jvm_printExceptionStack(env); }
int jni_jvm_constructObject(JNIEnv *env, jclass jcls, jobject *pjobj) { if (!jvm) return -1; jmethodID jmid = env->GetMethodID(jcls, "<init>", "()V"); if (!jmid) return -2; *pjobj = env->NewObject(jcls, jmid); if (!*pjobj) { jni_jvm_printExceptionStack(env); return -3; } return 0; }
int Shoebill::CallRegisteredFunction(AMX *amx, std::string functionName, jobjectArray parameters) const { if (!callbackHandlerObject) return -1; JNIEnv *env = NULL; jvm->AttachCurrentThread((void **) &env, NULL); static jmethodID jmid = env->GetMethodID(callbackHandlerClass, "onRegisteredFunctionCall", "(ILjava/lang/String;[Ljava/lang/Object;)I"); if (!jmid) return -1; auto jstr = env->NewStringUTF(functionName.c_str()); int result = env->CallIntMethod(callbackHandlerObject, jmid, amx, jstr, parameters); jni_jvm_printExceptionStack(env); return result; }
bool Shoebill::OnPluginUnload() { if (!callbackHandlerObject) return false; JNIEnv *env; jvm->AttachCurrentThread((void **) &env, NULL); static jmethodID jmid = env->GetMethodID(callbackHandlerClass, "onShoebillUnload", "()V"); if (!jmid) return false; env->CallVoidMethod(callbackHandlerObject, jmid); jni_jvm_printExceptionStack(env); Uninitialize(env); if (jni_jvm_destroy(env) >= 0) { sampgdk_logprintf(" > The Java VM has been successfully destroyed."); return true; } return false; }
int Shoebill::Initialize(JNIEnv *env) { if (initialized) { LOG("[DEBUG SHOEBILL] Shoebill is already initialized."); return -2; } shoebillLauncherClass = env->FindClass(LAUNCHER_CLASS_NAME); if (!shoebillLauncherClass) { sampgdk_logprintf(" > Error: Can't find launcher class [%s].", LAUNCHER_CLASS_NAME); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -1; } static jmethodID loadNativeLibraryMethodID = env->GetStaticMethodID(shoebillLauncherClass, LOAD_NATIVE_LIBRARY_METHOD_NAME, LOAD_NATIVE_LIBRARY_METHOD_SIGN); if (!loadNativeLibraryMethodID) { sampgdk_logprintf(" > Error: Can't find launcher method [%s::%s%s].", LAUNCHER_CLASS_NAME, LOAD_NATIVE_LIBRARY_METHOD_NAME, LOAD_NATIVE_LIBRARY_METHOD_SIGN); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -6; } env->CallStaticVoidMethod(shoebillLauncherClass, loadNativeLibraryMethodID); if (env->ExceptionCheck()) { jni_jvm_printExceptionStack(env); sampgdk_logprintf(" > Error: Could not load the native library from the launcher class."); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -7; } shoebillLauncherClass = (jclass) (env->NewGlobalRef(shoebillLauncherClass)); jvm->AttachCurrentThread((void **) &env, NULL); Start(); initialized = true; return 0; }
int Shoebill::CreateShoebillObject(JNIEnv *env) { if (initialized) { LOG("[SHOEBILL DEBUG] Shoebill is already initialized."); return -9; } static jmethodID resolveDependenciesMethodID = env->GetStaticMethodID(shoebillLauncherClass, RESOLVE_DEPENDENCIES_METHOD_NAME, RESOLVE_DEPENDENCIES_METHOD_SIGN); if (!resolveDependenciesMethodID) { sampgdk_logprintf(" > Error: Can't find launcher method [%s::%s%s].", LAUNCHER_CLASS_NAME, RESOLVE_DEPENDENCIES_METHOD_NAME, RESOLVE_DEPENDENCIES_METHOD_SIGN); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -8; } jobject context = env->CallStaticObjectMethod(shoebillLauncherClass, resolveDependenciesMethodID); if (!context) { jni_jvm_printExceptionStack(env); sampgdk_logprintf(" > Error: Shoebill couldn't resolve dependencies."); sampgdk_logprintf( " > Please make sure that you use the correct launcher and dependency manager for this plugin."); return -2; } static jmethodID createShoebillMethodID = env->GetStaticMethodID(shoebillLauncherClass, CREATE_SHOEBILL_METHOD_NAME, CREATE_SHOEBILL_METHOD_SIGN); if (!createShoebillMethodID) { sampgdk_logprintf(" > Error: Can't find launcher method [%s::%s%s]", LAUNCHER_CLASS_NAME, CREATE_SHOEBILL_METHOD_NAME, CREATE_SHOEBILL_METHOD_SIGN); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -3; } std::unordered_set<AMX *> amxInstances = AmxInstanceManager::GetInstance().GetInstances(); jsize size = amxInstances.size(); jint *array = new jint[size]; { int i = 0; for (std::unordered_set<AMX *>::iterator it = amxInstances.begin(); it != amxInstances.end() && i < size; it++, i++) { array[i] = (jint) (*it); } } jintArray amxHandleArray = env->NewIntArray(size); env->SetIntArrayRegion(amxHandleArray, 0, size, array); delete[] array; shoebillObject = env->CallStaticObjectMethod(shoebillLauncherClass, createShoebillMethodID, context, amxHandleArray); if (!shoebillObject) { jni_jvm_printExceptionStack(env); sampgdk_logprintf(" > Error: Couldn't create Shoebill object."); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -4; } shoebillClass = env->GetObjectClass(shoebillObject); if (!shoebillClass) { sampgdk_logprintf(" > Error: Couldn't get Shoebill class."); sampgdk_logprintf(" > Please make sure that you use the correct launcher for this plugin."); return -5; } #if defined(LINUX) std::ifstream codepageFile(CODEPAGE_FILE_PATH, std::ifstream::in); if (codepageFile.is_open()) { char input[256], charset[256]; unsigned int code = 0; while (codepageFile.good()) { codepageFile.getline(input, 256); sscanf(input, "%u %s", &code, charset); if (code && charset[0]) { if (codepages.find(code) != codepages.end()) sampgdk_logprintf(" > Error: Codepage is already in use, %d=%s", code, codepages[code].c_str()); else { codepages[code] = std::string(charset); } } code = 0; charset[0] = 0; } codepageFile.close(); } else { sampgdk_logprintf(" > Error: Can't open %s.", CODEPAGE_FILE_PATH); } #endif static jmethodID getCallbackHandlerMethodID = env->GetMethodID(shoebillClass, "getCallbackHandler", "()Lnet/gtaun/shoebill/samp/SampCallbackHandler;"); if (!getCallbackHandlerMethodID) { sampgdk_logprintf(" > Error: Couldn't find the main callbackHandler."); sampgdk_logprintf(" > Please make sure that you use the correct API and Runtime for this plugin."); return -6; } callbackHandlerObject = env->CallObjectMethod(shoebillObject, getCallbackHandlerMethodID); if (callbackHandlerObject == NULL) { sampgdk_logprintf(" > Error: Couldn't find the main callbackHandler."); sampgdk_logprintf(" > Please make sure that you use the correct API and Runtime for this plugin."); return -7; } shoebillObject = env->NewGlobalRef(shoebillObject); shoebillClass = (jclass) (env->NewGlobalRef(shoebillClass)); callbackHandlerObject = env->NewGlobalRef(callbackHandlerObject); callbackHandlerClass = (jclass) (env->NewGlobalRef(env->GetObjectClass(callbackHandlerObject))); initialized = true; OnShoebillLoad(); sampgdk_logprintf(" > Shoebill has been initialized successfully."); return 0; }