#include "squirrel/SquirrelEx.h" #include #include #include #include "SquirrelEx.h" #include "Asset/Asset_Script.h" SquirrelEx::SquirrelEx() { } SquirrelEx::~SquirrelEx() { } void SquirrelEx::printfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list vl; va_start(vl, s); int len = vsnprintf(NULL, 0, (const char *)s, vl); if (len <= 0) { va_end(vl); return; } char *buf = (char *)malloc(len + 1); if (!buf) { va_end(vl); return; } va_end(vl); va_start(vl, s); vsnprintf(buf, len + 1, (const char *)s, vl); va_end(vl); SDL_Log("%s", buf); va_end(vl); } void SquirrelEx::errorfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list vl; va_start(vl, s); int len = vsnprintf(NULL, 0, (const char *)s, vl); if (len <= 0) { va_end(vl); return; } char *buf = (char *)malloc(len + 1); if (!buf) { va_end(vl); return; } va_end(vl); va_start(vl, s); vsnprintf(buf, len + 1, (const char *)s, vl); va_end(vl); SDL_LogError(0, "%s", buf); va_end(vl); } bool SquirrelEx::Compilebuffer(std::string Path, std::string Code) { if (v == nullptr) { SDL_Log("松鼠虚拟机未初始化!"); return false; } if (sq_compilebuffer(v, Code.c_str(), Code.length(), Path.c_str(), SQTrue) >= 0) { sq_pushroottable(v); sq_call(v, 1, SQFalse, SQTrue); sq_pop(v, 1); return true; } return false; } void SquirrelEx::Init() { v = sq_open(1024); // 栈大小1024 sqstd_seterrorhandlers(v); sq_pushroottable(v); sqstd_register_bloblib(v); sqstd_register_iolib(v); sqstd_register_systemlib(v); sqstd_register_mathlib(v); sqstd_register_stringlib(v); sq_setprintfunc(v, printfunc, errorfunc); // 加载脚本 LoadLocalScript(); } void SquirrelEx::RequestNetScript(std::string Ip, std::string Port) { // char *response = NULL; // size_t response_size = 0; // std::string url = "http://" + Ip + ":" + Port + "/get/getadvertisement?key=Files"; // 确保协议正确 // int result = http_get(url.c_str(), &response, &response_size); // if (result == 0 && response != NULL && response_size > 0) // { // std::string response_str(response, response_size); // free(response); // 释放内存 // nlohmann::json ex1 = nlohmann::json::parse(response_str); // for (const auto &[key, value] : ex1.items()) // { // std::string key_str = key; // std::string value_str = value; // bool Flag = Compilebuffer(key_str, value_str); // if (!Flag) // { // SDL_Log("Squirrel Compilebuffer Error! FileName: %s", key_str.c_str()); // } // } // } // else // { // if (response) // free(response); // } } void SquirrelEx::LoadLocalScript() { std::vector lines; std::ifstream file("sqr/SquirrelFileConfig.cfg"); if (file.is_open()) { std::string line; while (std::getline(file, line)) { lines.push_back(line); } file.close(); } else { SDL_LogError(0, "配置文件未找到,请检查项目目录 sqr/SquirrelFileConfig.cfg 文件是否存在"); } for (const auto &line : lines) { std::string clean_line = line; // 移除换行符和回车符 clean_line.erase(std::remove(clean_line.begin(), clean_line.end(), '\n'), clean_line.end()); clean_line.erase(std::remove(clean_line.begin(), clean_line.end(), '\r'), clean_line.end()); if (line.find(".nut") == std::string::npos) continue; std::string RegistPath = "sqr/" + clean_line; if (!SQ_SUCCEEDED(sqstd_dofile(v, (SQChar *)(RegistPath.c_str()), SQFalse, SQTrue))) { SDL_LogError(0, "脚本文件未找到,请检查项目目录 %s 文件是否存在", RegistPath.c_str()); } { // std::ifstream F; // F.open((RegistPath).c_str(), std::ios::in | std::ios::binary); // if (F.is_open()) // { // std::stringstream ContentStringStream; // ContentStringStream << F.rdbuf(); // std::string ContentString(ContentStringStream.str()); // std::string RealContentString = ContentString; // if (RealContentString.length() > 0) // { // if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(RealContentString.c_str()), RealContentString.length(), (SQChar *)(RegistPath.c_str()), true))) // { // sq_pushroottable(v); // sq_call(v, 1, 1, 1); // sq_pop(v, 1); // } // } // } // else // { // SDL_LogError(0, "脚本文件未找到,请检查项目目录 %s 文件是否存在", RegistPath.c_str()); // } // F.close(); } } } void SquirrelEx::Run() { // 载入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 } void SquirrelEx::Clean() { sq_close(v); v = nullptr; } HSQUIRRELVM SquirrelEx::GetSquirrelVM() { return v; }