249 lines
7.5 KiB
C++
249 lines
7.5 KiB
C++
#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
|
||
}
|