DP_S/src/l_squirrel.cpp

249 lines
7.5 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>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <iostream>
#include <ctime>
#include <sstream>
#include <chrono>
#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<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::info);
console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v");
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(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<spdlog::logger>("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<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)
{
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<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);
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
}