DP_S/src/l_squirrel.cpp

198 lines
5.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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
}