#include "l_squirrel.h" #include "l_squirrel_register.hpp" // 虚拟机对象 HSQUIRRELVM v; // Lock std::recursive_mutex SqMtx; static void printfunc(HSQUIRRELVM v, const SQChar *s, ...) { fflush(stdout); va_list vl; va_start(vl, s); scvprintf(stdout, s, vl); va_end(vl); printf("\n"); fflush(stdout); } static void errorfunc(HSQUIRRELVM v, const SQChar *s, ...) { fflush(stderr); va_list vl; va_start(vl, s); scvprintf(stderr, s, vl); va_end(vl); printf("\n"); fflush(stderr); } // 加密函数 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) { ReloadingScript(v, "/dp_s/Dps_A/"); ReloadingScript(v, "/dp_s/Dps_B/"); ReloadingScript(v, "/dp_s/Dps_C/"); 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); 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); // 加载基础脚本文件 ReloadingScript(v, "/dp_s/Dps_A/"); ReloadingScript(v, "/dp_s/Dps_B/"); ReloadingScript(v, "/dp_s/Dps_C/"); // 执行虚拟机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 }