198 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
| #include "l_squirrel.h"
 | ||
| #include "l_squirrel_register.hpp"
 | ||
| #include "spdlog/spdlog.h"
 | ||
| 
 | ||
| // 虚拟机对象
 | ||
| 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 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, ...)
 | ||
| // {
 | ||
| //     fflush(stderr);
 | ||
| //     va_list vl;
 | ||
| //     va_start(vl, s);
 | ||
| //     scvprintf(stderr, s, vl);
 | ||
| //     va_end(vl);
 | ||
| //     printf("\n");
 | ||
| //     fflush(stderr);
 | ||
| // }
 | ||
| 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<std::string> vec = Tool::GetListFilesR(FilePath);
 | ||
|     std::map<std::string, std::string> 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<std::string, std::string> 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<std::string, std::string> 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<std::recursive_mutex> 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);
 | ||
| 
 | ||
|     // 设置日志格式
 | ||
|     spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %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
 | ||
| }
 |