#include "l_squirrel.h" #include "l_squirrel_register.hpp" #include #include #include #include #include #include #include #include "SqrReqScript.hpp" #define WEBSCRIPT true; using asio::ip::tcp; static char szGamePathA[256]; void setupLogger() { getConfigPath(szGamePathA, sizeof(szGamePathA)); std::string Path = std::string(szGamePathA); std::string log_filename = "log/dps_log/" + Path.substr(Path.find("cfg") + 4) + "/log_"; char time_buffer[100]; std::time_t now = std::time(nullptr); std::tm *local_time = std::localtime(&now); strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d_%H-%M-%S", local_time); log_filename += std::string(time_buffer) + ".txt"; auto console_sink = std::make_shared(); console_sink->set_level(spdlog::level::info); console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v"); auto file_sink = std::make_shared(log_filename, true); file_sink->set_level(spdlog::level::info); file_sink->set_pattern("[%Y-%m-%d %H:%M:%S] [%^%l%$] %v"); auto logger = std::make_shared("logger", spdlog::sinks_init_list{console_sink, file_sink}); logger->set_level(spdlog::level::info); logger->flush_on(spdlog::level::info); // logger->info("欢迎使用Dps插件"); spdlog::register_logger(logger); spdlog::set_default_logger(logger); } // 虚拟机对象 HSQUIRRELVM v; // Lock std::recursive_mutex SqMtx; static void printfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list vl; va_start(vl, s); char buf[1024]; vsnprintf(buf, sizeof(buf), s, vl); va_end(vl); spdlog::info(buf); } static void errorfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list vl; va_start(vl, s); char buf[1024]; vsnprintf(buf, sizeof(buf), s, vl); va_end(vl); spdlog::error(buf); } // 加密函数 static std::string encryptDecrypt(const std::string &input, const std::string &key) { std::string output = input; for (size_t i = 0; i < input.size(); i++) { output[i] = input[i] ^ key[i % key.size()]; // 使用异或运算进行加密 } return output; } // 判断是否处理加密 static std::string IsencryptDecrypt(const std::string &input, const std::string &FileName) { if (FileName.find(".nut") != std::string::npos) return input; else return encryptDecrypt(input, "Rindro-Aurora"); } static void ReloadingScript(HSQUIRRELVM v, std::string FilePath) { // 爬取出所有的脚本文件 std::vector vec = Tool::GetListFilesR(FilePath); std::map SquirrelFilePath; for (auto it = vec.cbegin(); it != vec.cend(); ++it) { std::string FileName = FilePath + *it; if (FileName.find(".nut") == std::string::npos && FileName.find(".sut") == std::string::npos) continue; std::fstream F; F.open((FileName).c_str(), std::ios::in); std::stringstream ContentStringStream; ContentStringStream << F.rdbuf(); std::string ContentString(ContentStringStream.str()); F.close(); std::string RealContentString = IsencryptDecrypt(ContentString, FileName); SquirrelFilePath[FileName] = RealContentString; } std::map SquirrelLastFilePath; for (auto it = SquirrelFilePath.begin(); it != SquirrelFilePath.end(); it++) { std::string Sourcename = it->first; std::string ContentString = it->second; if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true))) { sq_pushroottable(v); sq_call(v, 1, 1, 1); sq_pop(v, 1); } else { SquirrelLastFilePath[Sourcename] = ContentString; } } while (SquirrelLastFilePath.size() > 0) { std::map FailMapBuffer; for (auto it = SquirrelLastFilePath.begin(); it != SquirrelLastFilePath.end(); it++) { std::string Sourcename = it->first; std::string ContentString = it->second; if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true))) { sq_pushroottable(v); if (SQ_FAILED(sq_call(v, 1, 1, 1))) { FailMapBuffer[Sourcename] = ContentString; }; sq_pop(v, 1); }; } SquirrelLastFilePath.clear(); if (FailMapBuffer.size() > 0) { for (auto it = FailMapBuffer.begin(); it != FailMapBuffer.end(); it++) { std::string Sourcename = it->first; std::string ContentString = it->second; SquirrelLastFilePath[Sourcename] = ContentString; } } } } static SQInteger SqReloadScript(HSQUIRRELVM v) { if ((access("/dp_s/lib/db.ini", F_OK) != -1)) { ReloadingScript(v, "/dp_s/Dps_A/"); ReloadingScript(v, "/dp_s/Dps_B/"); ReloadingScript(v, "/dp_s/Dps_C/"); } else { ReqSquirrelScript(v); } // #ifdef WEBSCRIPT // ReqSquirrelScript(v); // #else // ReloadingScript(v, "/dp_s/Dps_A/"); // ReloadingScript(v, "/dp_s/Dps_B/"); // ReloadingScript(v, "/dp_s/Dps_C/"); // #endif return 0; } void InitSquirrel() { std::lock_guard lock(SqMtx); v = sq_open(4096); // 创建虚拟机,其栈的初始大小为1024 sq_pushroottable(v); sqstd_register_bloblib(v); sqstd_register_iolib(v); sqstd_register_systemlib(v); sqstd_register_mathlib(v); sqstd_register_stringlib(v); sqstd_seterrorhandlers(v); setupLogger(); sq_setprintfunc(v, printfunc, errorfunc); // sets the print function // 输出版本信息 // scfprintf(stdout, _SC("%s %s (%d bits)\n"), SQUIRREL_VERSION, SQUIRREL_COPYRIGHT, (int)sizeof(SQInteger) * 8); // 注册全局NutApi GlobaRegisterSquirrel(v); // #ifdef WEBSCRIPT // // 从网络加载脚本 // ReqSquirrelScript(v); // #else // // 加载基础脚本文件 // ReloadingScript(v, "/dp_s/Dps_A/"); // ReloadingScript(v, "/dp_s/Dps_B/"); // ReloadingScript(v, "/dp_s/Dps_C/"); // #endif if ((access("/dp_s/lib/db.ini", F_OK) != -1)) { ReloadingScript(v, "/dp_s/Dps_A/"); ReloadingScript(v, "/dp_s/Dps_B/"); ReloadingScript(v, "/dp_s/Dps_C/"); } else { ReqSquirrelScript(v); } // 执行虚拟机Main函数 SQInteger top = sq_gettop(v); // saves the stack size before the call sq_pushroottable(v); // pushes the global table sq_pushstring(v, _SC("main"), -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { // gets the field 'foo' from the global table sq_pushroottable(v); // push the 'this' (in this case is the global table) sq_call(v, 1, SQFalse, SQTrue); // calls the function } sq_settop(v, top); // restores the original stack size sq_pushroottable(v); sq_pushstring(v, "sq_ReloadScript", -1); sq_newclosure(v, SqReloadScript, 0); // create a new function sq_newslot(v, -3, SQFalse); sq_pop(v, 1); // pops the root table }