This commit is contained in:
lenheart
2024-10-02 15:04:35 +08:00
parent a5b0345d2b
commit 52ec40aece
12 changed files with 425 additions and 269 deletions

View File

@@ -8,6 +8,7 @@
#include "sqstdsystem.h"
#include "CConnectPool.h"
#include "l_socket.h"
#include <openssl/md5.h>
#include <iostream>
#include <functional>
#include <list>
@@ -713,6 +714,160 @@ static SQInteger OutPutTable(HSQUIRRELVM v)
return 0;
}
const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string base64_encode(const std::string &in)
{
std::string out;
int val = 0;
int valb = -6;
for (unsigned char c : in)
{
val = (val << 8) + c;
valb += 8;
while (valb >= 0)
{
out.push_back(base64_chars[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6)
{
out.push_back(base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
}
while (out.size() % 4)
{
out.push_back('=');
}
return out;
}
std::string calculateMD5(const std::string &filePath)
{
std::ifstream file(filePath, std::ios::binary | std::ios::ate);
if (!file)
{
return "";
}
std::streampos size = file.tellg();
file.seekg(0, std::ios::beg);
unsigned char buffer[16];
MD5_CTX md5Context;
MD5_Init(&md5Context);
while (file.read(reinterpret_cast<char *>(buffer), sizeof(buffer)))
{
MD5_Update(&md5Context, buffer, file.gcount());
}
MD5_Final(buffer, &md5Context);
file.close();
return base64_encode((char *)buffer);
}
void processDirectory(const std::string &directoryPath, std::unordered_map<std::string, std::string> &fileMD5Map)
{
DIR *dir;
struct dirent *entry;
if ((dir = opendir(directoryPath.c_str())) != nullptr)
{
while ((entry = readdir(dir)) != nullptr)
{
if (entry->d_type == DT_REG)
{
std::string filePath = directoryPath + "/" + entry->d_name;
std::string currentMD5 = calculateMD5(filePath);
if (fileMD5Map.find(filePath) != fileMD5Map.end())
{
if (fileMD5Map[filePath] != currentMD5)
{
fileMD5Map[filePath] = currentMD5;
std::lock_guard<std::recursive_mutex> lock(SqMtx);
// 执行虚拟机Main函数
SQInteger top = sq_gettop(v); // saves the stack size before the call
sq_pushroottable(v); // pushes the global table
sq_pushstring(v, _SC("_Reload_List_Write_"), -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_pushstring(v, filePath.c_str(), -1);
sq_call(v, 2, SQFalse, SQTrue); // calls the function
}
sq_settop(v, top); // restores the original stack size
// // 文件有变动,写入文件路径
// std::ofstream outputFile("/dp_s/auto_reload.dat", std::ios_base::app);
// if (outputFile.is_open())
// {
// std::string ins = "dofile(\"" + filePath + "\");";
// outputFile << ins << std::endl;
// outputFile.close();
// }
// else
// {
// std::cerr << "无法创建输出文件。" << std::endl;
// }
}
}
else
{
fileMD5Map[filePath] = currentMD5;
}
}
else if (entry->d_type == DT_DIR && std::string(entry->d_name) != "." && std::string(entry->d_name) != "..")
{
processDirectory(directoryPath + "/" + entry->d_name, fileMD5Map);
}
}
closedir(dir);
}
else
{
std::cerr << "无法打开目录:" << directoryPath << std::endl;
}
}
struct AutoReloadSt
{
std::string Path;
};
static void *continuousMonitoring(void *arg)
{
AutoReloadSt *Info = (AutoReloadSt *)arg;
std::unordered_map<std::string, std::string> fileMD5Map;
while (true)
{
processDirectory(Info->Path, fileMD5Map);
usleep(1000); // 每隔 1 秒检查一次
}
}
static SQInteger AutoReload(HSQUIRRELVM v)
{
const SQChar *Str;
sq_getstring(v, 2, &Str);
AutoReloadSt *Info = new AutoReloadSt();
Info->Path = std::string(Str);
// 开启DP-S 自动热重载
// std::string targetDirectory = (char *)Str;
// std::thread monitorThread(continuousMonitoring, targetDirectory);
// monitorThread.join();
pthread_t MonitoringThread;
// 创建线程1
if (pthread_create(&MonitoringThread, NULL, continuousMonitoring, Info) != 0)
{
std::cerr << "Error creating thread 1" << std::endl;
}
return 0;
}
static void RegisterGame(HSQUIRRELVM v)
{
getConfigPath(szGamePath, sizeof(szGamePath));
@@ -767,4 +922,6 @@ static void RegisterGame(HSQUIRRELVM v)
register_World_func(v, Sq_getExportByName, _SC("Sq_getExportByName"));
// 打印表
register_World_func(v, OutPutTable, _SC("Sq_OutPutTable"));
// 开启自动热重载
register_World_func(v, AutoReload, _SC("Sq_AutoReload"));
}