mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-06 12:03:39 +00:00
377 lines
13 KiB
C++
377 lines
13 KiB
C++
#include "APIHelp.h"
|
|
#include <LiteLoader/Main/Config.h>
|
|
#include "LlAPI.h"
|
|
#include <Engine/GlobalShareData.h>
|
|
#include <Engine/EngineOwnData.h>
|
|
#include <Utils/NetworkHelper.h>
|
|
#include <PluginManager.h>
|
|
#include <Tools/Utils.h>
|
|
#include <LiteLoader/Main/Version.h>
|
|
#include <string>
|
|
#include <filesystem>
|
|
#include <map>
|
|
using namespace std;
|
|
|
|
|
|
//////////////////// Classes ////////////////////
|
|
|
|
ClassDefine<void> LlClassBuilder =
|
|
defineClass("ll")
|
|
.function("version", &LlClass::version)
|
|
.function("versionString", &LlClass::versionString)
|
|
.function("versionStatus", &LlClass::getVersionStatus)
|
|
.function("isDebugMode", &LlClass::isDebugMode)
|
|
.function("requireVersion", &LlClass::requireVersion)
|
|
.function("listPlugins", &LlClass::listPlugins)
|
|
.function("getAllPluginInfo", &LlClass::getAllPluginInfo)
|
|
.function("import", &LlClass::importFunc)
|
|
.function("export", &LlClass::exportFunc)
|
|
.function("hasExported", &LlClass::hasFuncExported)
|
|
.function("require", &LlClass::require)
|
|
.function("scriptEngineVersion", &LlClass::getScriptEngineVersion)
|
|
.function("eval", &LlClass::eval)
|
|
.function("registerPlugin", &LlClass::registerPlugin)
|
|
.function("getPluginInfo", &LlClass::getPluginInfo)
|
|
|
|
.function("checkVersion", &LlClass::requireVersion)
|
|
|
|
.property("language", &LlClass::getLanguage)
|
|
|
|
.build();
|
|
|
|
|
|
Local<Value> LlClass::registerPlugin(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
if (args.size() >= 2)
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
// if (args.size() >= 3)
|
|
// CHECK_ARG_TYPE(args[2], ValueKind::kObject);
|
|
if (args.size() >= 4)
|
|
CHECK_ARG_TYPE(args[3], ValueKind::kObject);
|
|
|
|
try {
|
|
string name = args[0].toStr();
|
|
string desc = args.size() >= 2 ? args[1].toStr() : "";
|
|
|
|
LL::Version ver = LL::Version(1, 0, 0);
|
|
if (args.size() >= 3) {
|
|
if (args[2].isArray()) {
|
|
Local<Array> verInfo = args[2].asArray();
|
|
if (verInfo.size() >= 1) {
|
|
Local<Value> major = verInfo.get(0);
|
|
if (major.isNumber())
|
|
ver.major = major.toInt();
|
|
}
|
|
if (verInfo.size() >= 2) {
|
|
Local<Value> minor = verInfo.get(1);
|
|
if (minor.isNumber())
|
|
ver.minor = minor.toInt();
|
|
}
|
|
if (verInfo.size() >= 3) {
|
|
Local<Value> revision = verInfo.get(2);
|
|
if (revision.isNumber())
|
|
ver.revision = revision.toInt();
|
|
}
|
|
} else if (args[2].isObject()) {
|
|
Local<Object> verInfo = args[2].asObject();
|
|
if (verInfo.has("major")) {
|
|
Local<Value> major = verInfo.get("major");
|
|
if (major.isNumber())
|
|
ver.major = major.toInt();
|
|
}
|
|
if (verInfo.has("minor")) {
|
|
Local<Value> minor = verInfo.get("minor");
|
|
if (minor.isNumber())
|
|
ver.minor = minor.toInt();
|
|
}
|
|
if (verInfo.has("revision")) {
|
|
Local<Value> revision = verInfo.get("revision");
|
|
if (revision.isNumber())
|
|
ver.revision = revision.toInt();
|
|
}
|
|
} else {
|
|
LOG_WRONG_ARG_TYPE();
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
}
|
|
|
|
map<string, string> other;
|
|
if (args.size() >= 4) {
|
|
Local<Object> otherInfo = args[3].asObject();
|
|
auto keys = otherInfo.getKeyNames();
|
|
for (auto& key : keys) {
|
|
other[key] = otherInfo.get(key).toStr();
|
|
}
|
|
}
|
|
|
|
ENGINE_OWN_DATA()->pluginName = ENGINE_OWN_DATA()->logger.title = name;
|
|
return Boolean::newBoolean(PluginManager::registerPlugin(ENGINE_OWN_DATA()->pluginFileOrDirPath,
|
|
name, desc, ver, other));
|
|
}
|
|
CATCH("Fail in LLSERegisterPlugin!");
|
|
}
|
|
|
|
Local<Value> LlClass::getPluginInfo(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
std::string name = args[0].toStr();
|
|
auto plugin = LL::getPlugin(name);
|
|
if (plugin) {
|
|
auto result = Object::newObject();
|
|
|
|
result.set("name", plugin->name);
|
|
result.set("desc", plugin->desc);
|
|
|
|
auto ver = Array::newArray();
|
|
ver.add(Number::newNumber(plugin->version.major));
|
|
ver.add(Number::newNumber(plugin->version.minor));
|
|
ver.add(Number::newNumber(plugin->version.revision));
|
|
|
|
result.set("version", ver);
|
|
result.set("versionStr", plugin->version.toString(true));
|
|
result.set("filePath", plugin->filePath);
|
|
|
|
auto others = Object::newObject();
|
|
for (auto& [k, v] : plugin->others) {
|
|
others.set(k, v);
|
|
}
|
|
result.set("others", others);
|
|
return result;
|
|
}
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in getPluginInfo");
|
|
}
|
|
|
|
Local<Value> LlClass::getVersionStatus(const Arguments& args) {
|
|
try {
|
|
int versionStatusValue;
|
|
|
|
if (LITELOADER_VERSION_STATUS == LL::Version::Status::Release) {
|
|
versionStatusValue = 0;
|
|
} else if (LITELOADER_VERSION_STATUS == LL::Version::Status::Beta) {
|
|
versionStatusValue = 1;
|
|
} else if (LITELOADER_VERSION_STATUS == LL::Version::Status::Dev) {
|
|
versionStatusValue = 2;
|
|
}
|
|
|
|
return Number::newNumber(versionStatusValue);
|
|
}
|
|
CATCH("Fail in LLSEGetVersionStatus")
|
|
}
|
|
|
|
Local<Value> LlClass::version(const Arguments& args) {
|
|
try {
|
|
Local<Object> ver = Object::newObject();
|
|
ver.set("major", LITELOADER_VERSION_MAJOR);
|
|
ver.set("minor", LITELOADER_VERSION_MINOR);
|
|
ver.set("revision", LITELOADER_VERSION_REVISION);
|
|
ver.set("isBeta", LITELOADER_VERSION_STATUS == LL::Version::Status::Beta);
|
|
ver.set("isRelease", LITELOADER_VERSION_STATUS == LL::Version::Status::Release);
|
|
ver.set("isDev", LITELOADER_VERSION_STATUS == LL::Version::Status::Dev);
|
|
return ver;
|
|
}
|
|
CATCH("Fail in LLSEGetVersion!")
|
|
}
|
|
|
|
Local<Value> LlClass::getLanguage() {
|
|
try {
|
|
return String::newString(PluginOwnData::getImpl<I18nBase>(LL::getLoaderHandle(), I18nBase::POD_KEY).defaultLocaleName);
|
|
}
|
|
CATCH("Fail in LLSEGetLanguage")
|
|
}
|
|
|
|
Local<Value> LlClass::isDebugMode(const Arguments& args) {
|
|
try {
|
|
return Boolean::newBoolean(LL::isDebugMode());
|
|
}
|
|
CATCH("Fail in LLSEGetIsDebugMode")
|
|
}
|
|
|
|
Local<Value> LlClass::versionString(const Arguments& args) {
|
|
try {
|
|
return String::newString(LL::getLoaderVersionString());
|
|
}
|
|
CATCH("Fail in LLSEGetVersionString!")
|
|
}
|
|
|
|
Local<Value> LlClass::requireVersion(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
if (args.size() >= 2)
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
if (args.size() >= 3)
|
|
CHECK_ARG_TYPE(args[2], ValueKind::kNumber);
|
|
|
|
try {
|
|
return Boolean::newBoolean(!IsVersionLess(LITELOADER_VERSION_MAJOR, LITELOADER_VERSION_MINOR, LITELOADER_VERSION_REVISION,
|
|
args[0].toInt(), (args.size() >= 2) ? args[1].toInt() : 0, (args.size() >= 3) ? args[2].toInt() : 0));
|
|
}
|
|
CATCH("Fail in LLSERequireVersion!")
|
|
}
|
|
|
|
Local<Value> LlClass::getAllPluginInfo(const Arguments& args) {
|
|
try {
|
|
Local<Array> plugins = Array::newArray();
|
|
auto list = PluginManager::getAllPlugins();
|
|
for (auto& plugin : list) {
|
|
// Create plugin object
|
|
auto pluginObject = Object::newObject();
|
|
|
|
pluginObject.set("name", plugin.second->name);
|
|
pluginObject.set("desc", plugin.second->desc);
|
|
|
|
auto ver = Array::newArray();
|
|
ver.add(Number::newNumber(plugin.second->version.major));
|
|
ver.add(Number::newNumber(plugin.second->version.minor));
|
|
ver.add(Number::newNumber(plugin.second->version.revision));
|
|
|
|
pluginObject.set("version", ver);
|
|
pluginObject.set("versionStr", plugin.second->version.toString(true));
|
|
pluginObject.set("filePath", plugin.second->filePath);
|
|
|
|
auto others = Object::newObject();
|
|
for (auto& [k, v] : plugin.second->others) {
|
|
others.set(k, v);
|
|
}
|
|
pluginObject.set("others", others);
|
|
|
|
// Add plugin object to list
|
|
plugins.add(pluginObject);
|
|
}
|
|
return plugins;
|
|
}
|
|
CATCH("Fail in LLSEGetAllPluginInfo!")
|
|
}
|
|
|
|
// For Compatibility
|
|
Local<Value> LlClass::listPlugins(const Arguments& args) {
|
|
try {
|
|
Local<Array> plugins = Array::newArray();
|
|
auto list = PluginManager::getAllPlugins();
|
|
for (auto& plugin : list) {
|
|
plugins.add(String::newString(plugin.second->name));
|
|
}
|
|
return plugins;
|
|
}
|
|
CATCH("Fail in LLSEListPlugins!")
|
|
}
|
|
|
|
Local<Value> LlClass::require(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString)
|
|
if (args.size() >= 2)
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString)
|
|
|
|
try {
|
|
bool existing = false;
|
|
string require = args[0].toStr();
|
|
string thisName = ENGINE_OWN_DATA()->pluginName;
|
|
|
|
//已加载插件
|
|
if (PluginManager::getPlugin(require) != nullptr) {
|
|
logger.info(tr("llse.api.ll.require.success", thisName, require));
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
|
|
//插件目录
|
|
existing = false;
|
|
string requirePath = "";
|
|
|
|
// Direct
|
|
std::error_code ec;
|
|
if (filesystem::exists(str2wstr(require), ec)) {
|
|
requirePath = require;
|
|
existing = true;
|
|
} else {
|
|
auto list = GetFileNameList(LLSE_PLUGINS_LOAD_DIR);
|
|
for (auto fileName : list) {
|
|
if (fileName == require) {
|
|
requirePath = string(LLSE_PLUGINS_LOAD_DIR) + "/" + require;
|
|
existing = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (existing) {
|
|
bool success = PluginManager::loadPlugin(requirePath);
|
|
if (success) {
|
|
logger.info(thisName + tr("llseapi.require.success") + require);
|
|
return Boolean::newBoolean(true);
|
|
} else {
|
|
logger.error(thisName + tr("llseapi.require.fail"));
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
}
|
|
|
|
//依赖库目录
|
|
existing = false;
|
|
auto list = GetFileNameList(LLSE_DEPENDS_DIR);
|
|
for (auto fileName : list) {
|
|
if (fileName == require) {
|
|
existing = true;
|
|
break;
|
|
}
|
|
}
|
|
if (existing) {
|
|
bool success = PluginManager::loadPlugin(string(LLSE_DEPENDS_DIR) + "/" + require);
|
|
if (success) {
|
|
logger.info(thisName + tr("llseapi.require.success") + require);
|
|
return Boolean::newBoolean(true);
|
|
} else {
|
|
logger.error(thisName + tr("llseapi.require.fail"));
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
}
|
|
|
|
// HTTP(s)下载
|
|
if (args.size() == 1) {
|
|
logger.error(thisName + tr("llseapi.require.fail"));
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
|
|
string remotePath = args[1].toStr();
|
|
int status;
|
|
string result, downloadPath = string(LLSE_DEPENDS_DIR) + "/" + require;
|
|
|
|
if (!HttpGetSync(remotePath, &status, &result) || status != 200) {
|
|
logger.error(thisName + tr("llseapi.require.network.fail") + to_string(status));
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
WriteAllFile(downloadPath, result, false);
|
|
|
|
logger.info(thisName + tr("llseapi.require.download.success") + downloadPath);
|
|
|
|
//下载完毕安装
|
|
bool success = PluginManager::loadPlugin(downloadPath);
|
|
if (success) {
|
|
logger.info(thisName + tr("llseapi.require.success") + require);
|
|
return Boolean::newBoolean(true);
|
|
} else {
|
|
logger.error(thisName + tr("llseapi.require.fail"));
|
|
return Boolean::newBoolean(false);
|
|
}
|
|
}
|
|
CATCH("Fail in LLSERequire!")
|
|
}
|
|
|
|
Local<Value> LlClass::getScriptEngineVersion(const Arguments& args) {
|
|
try {
|
|
return String::newString(EngineScope::currentEngine()->getEngineVersion());
|
|
}
|
|
CATCH("Fail in LLSEGetScriptEngineVerison")
|
|
}
|
|
|
|
Local<Value> LlClass::eval(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
try {
|
|
return EngineScope::currentEngine()->eval(args[0].toStr());
|
|
}
|
|
CATCH("Fail in LLSEEval!")
|
|
}
|