111
This commit is contained in:
@@ -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"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user