#pragma once #include "squirrel.h" #include "sqstdaux.h" #include "sqstdblob.h" #include "sqstdio.h" #include "sqstdmath.h" #include "sqstdstring.h" #include "sqstdsystem.h" #include "CConnectPool.h" #include "croncpp.h" #include "l_socket.h" #include #include #include #include #include #include #include #include "nlohmann/json.hpp" #define CONTAINS_STRING(str, substr) (str == substr) template R CallGameT(A call_addr, const ARG... arguments) { if (!call_addr) { return R(); } const auto control = reinterpret_cast(call_addr); try { return control(arguments...); } catch (...) { } return R(); } template R CallGameRT(void *call_addr, va_list arguments, std::vector Type) { if (!call_addr) { return R(); } try { // 使用汇编语言将va_list中的值一个一个push进去 R result; va_list args; va_copy(args, arguments); asm volatile( "pushl %0" : : "g"(va_arg(args, int)) : "memory"); va_end(args); asm volatile( "call *%1" : "=a"(result) : "r"(call_addr) : "memory"); return result; } catch (...) { } return R(); } static char szGamePath[256]; static int getargs(char ***argv) { size_t buflen = 1024, readlen = 0, maxlen = buflen; int fd = open("/proc/self/cmdline", O_RDONLY); if (fd == -1) return 0; char *buf = (char *)malloc(buflen); while (1) { ssize_t n = read(fd, buf + readlen, buflen - readlen); if (n == -1) { free(buf); close(fd); return 0; } readlen += n; if (!n || readlen < buflen) break; maxlen += buflen; buf = (char *)realloc(buf, maxlen); } close(fd); int argc = 0; char *cp = buf; do { while (*cp != '\0') cp++; argc++; } while (++cp < buf + readlen); *argv = (char **)malloc(argc * sizeof(char *)); argc = 0; cp = buf; do { (*argv)[argc] = (char *)malloc(strlen(cp) + 1); strcpy((*argv)[argc], cp); argc++; while (*cp != '\0') cp++; } while (++cp < buf + readlen); free(buf); return argc; } static int getConfigPath(char *pPath, size_t nSize) { if (readlink("/proc/self/exe", pPath, nSize) <= 0) return -1; char **argv = NULL; int argc = getargs(&argv); if (!argv || argc < 2) { if (argv) { for (int i = 0; i < argc; i++) { if (argv[i]) free(argv[i]); } free(argv); } return -1; } *strrchr(pPath, '/') = '\0'; sprintf(pPath, "%s/cfg/%s.cfg", pPath, argv[1]); for (int i = 0; i < argc; i++) { if (argv[i]) free(argv[i]); } free(argv); return 0; } static SQInteger Game_GetConfig(HSQUIRRELVM v) { sq_pushstring(v, szGamePath, -1); return 1; } // 加密函数 static std::string Buf_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 Buf_IsencryptDecrypt(const std::string &input, const std::string &FileName) { if (FileName.find(".nut") != std::string::npos) return input; else return Buf_encryptDecrypt(input, "Lenheart-asdhfjiaednkljanslk"); } // 执行脚本 static SQInteger RunScript(HSQUIRRELVM v) { const SQChar *Path; sq_getstring(v, 2, &Path); std::string RealPath(Path); RealPath = "/dp_s/" + RealPath; std::fstream F; F.open(RealPath, std::ios::in); std::stringstream ContentStringStream; ContentStringStream << F.rdbuf(); std::string ContentString(ContentStringStream.str()); F.close(); std::string RealContentString = Buf_IsencryptDecrypt(ContentString, RealPath); if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(RealContentString.c_str()), RealContentString.length(), (SQChar *)(RealPath.c_str()), true))) { sq_pushroottable(v); sq_call(v, 1, 1, 1); sq_pop(v, 1); } return 0; } // 指针转int static SQInteger L_Ptr2Int(HSQUIRRELVM v) { SQUserPointer P; sq_getuserpointer(v, 2, &P); sq_pushinteger(v, (int)P); return 1; } // int转指针 static SQInteger L_Int2Ptr(HSQUIRRELVM v) { SQInteger Address; sq_getinteger(v, 2, &Address); sq_pushuserpointer(v, (void *)Address); return 1; } // 写内存 static SQInteger L_WriteAddress(HSQUIRRELVM v) { // 内存地址 int型 SQUserPointer Address; // 内存偏移 int型 SQInteger Offset; // 获取参数个数 int ParameterNum = sq_gettop(v); // 2个参数时 if (ParameterNum == 4) { // 获取地址 sq_getuserpointer(v, 2, &Address); // 获取偏移 sq_getinteger(v, 3, &Offset); // 获取修改的值 SQInteger WriteValue; sq_getinteger(v, 4, &WriteValue); *(int *)((void *)Address + Offset) = WriteValue; sq_pushbool(v, true); return 1; } if (ParameterNum == 5) { } else { sq_pushbool(v, false); return 1; } return 0; } // 读内存 static SQInteger L_ReadAddress(HSQUIRRELVM v) { // 内存地址 int型 SQUserPointer Address; // 获取地址 sq_getuserpointer(v, 2, &Address); sq_pushinteger(v, *(int *)Address); return 1; } // 读内存 static SQInteger L_ReadPoint(HSQUIRRELVM v) { // 内存地址 int型 SQUserPointer Address; // 获取地址 sq_getuserpointer(v, 2, &Address); int *ptr = reinterpret_cast(Address); int value = *ptr; sq_pushuserpointer(v, (void *)(value)); return 1; } // 读内存字符串 static SQInteger L_ReadAddressString(HSQUIRRELVM v) { // 内存地址 int型 SQUserPointer Address; // 获取地址 sq_getuserpointer(v, 2, &Address); if (sq_gettop(v) == 3) { SQInteger Length; sq_getinteger(v, 3, &Length); sq_pushstring(v, (char *)(Address), Length); } else { sq_pushstring(v, (char *)(Address), -1); } return 1; } // 读取字节数组 static SQInteger L_ReadByteArr(HSQUIRRELVM v) { SQUserPointer P; sq_getuserpointer(v, 2, &P); SQInteger Count; sq_getinteger(v, 3, &Count); char *Address = (char *)P; sq_newarray(v, 0); for (size_t i = 0; i < Count; i++) { sq_pushinteger(v, (int)(Address[i])); sq_arrayappend(v, -2); } return 1; } // 指针转Blob static SQInteger L_Point2Blob(HSQUIRRELVM v) { SQUserPointer P; sq_getuserpointer(v, 2, &P); SQInteger Count; sq_getinteger(v, 3, &Count); char *Address = (char *)P; SQUserPointer Blobobj = sqstd_createblob(v, Count); memcpy(Blobobj, P, Count); return 1; } // 写字节数组 static SQInteger L_WriteByteArr(HSQUIRRELVM v) { SQUserPointer P; sq_getuserpointer(v, 2, &P); char *Address = (char *)P; size_t Idx = 0; sq_pushnull(v); // null iterator while (SQ_SUCCEEDED(sq_next(v, 3))) { SQInteger Buf; sq_getinteger(v, -1, &Buf); CMem::WriteUChar((Address + Idx), Buf); // 这里-1是值,-2是键 sq_pop(v, 2); // 在下一次迭代之前弹出键和值 Idx++; } sq_pop(v, 1); return 0; } // 写Blob到指定地址 static SQInteger L_WriteBlobToAddress(HSQUIRRELVM v) { SQUserPointer P; sq_getuserpointer(v, 2, &P); SQUserPointer Blobobj; // sq_getuserpointer(v, 3, &P); sqstd_getblob(v, 3, &Blobobj); int Size = sqstd_getblobsize(v, 3); memcpy(P, Blobobj, Size); return 0; } // 通过ID从Pvf中查询名称 static SQInteger L_GetNameByIdFromPvf(HSQUIRRELVM v) { SQInteger Idx; sq_getinteger(v, 2, &Idx); void *Ret = CallGameT(0x835FA32, CallGameT(0x80CC19B), (unsigned int)Idx); if (Ret) { const char *Name = CallGameT(0x811ed82, Ret); sq_pushstring(v, Name, -1); } else { sq_pushnull(v); } return 1; } // 通过ID从Pvf中查询Data static SQInteger L_GetDataByIdFromPvf(HSQUIRRELVM v) { SQInteger Idx; sq_getinteger(v, 2, &Idx); void *Ret = CallGameT(0x835FA32, CallGameT(0x80CC19B), (unsigned int)Idx); if (Ret) { sq_pushuserpointer(v, Ret); } else { sq_pushnull(v); } return 1; } // 创建数据库连接池 static SQInteger L_CreatCConnectPool(HSQUIRRELVM v) { SQInteger MinConnectCount, MaxConnectCount, Port; const SQChar *Host; const SQChar *Account; const SQChar *Passwd; sq_getinteger(v, 2, &MinConnectCount); sq_getinteger(v, 3, &MaxConnectCount); sq_getstring(v, 4, &Host); sq_getinteger(v, 5, &Port); sq_getstring(v, 6, &Account); sq_getstring(v, 7, &Passwd); // 初始化数据库 CConnectPool::CreatePool(MinConnectCount, MaxConnectCount, Host, Port, Account, Passwd); return 0; } // 阻塞线程的数据库操作 无返回值 static SQInteger L_MysqlExecNoRet(HSQUIRRELVM v) { const SQChar *Sql; sq_getstring(v, 2, &Sql); MYSQL *MysqlObject = CConnectPool::GetConnect(); mysql_query(MysqlObject, Sql); CConnectPool::PutConnect(MysqlObject); return 0; } struct CreateSocketInfo { std::string Ip; std::string Port; }; static void *SocketThread_function(void *arg) { CreateSocketInfo *Info = (CreateSocketInfo *)arg; l_socket::getInstance().Init(Info->Ip, Info->Port); delete Info; // 在这里编写线程的具体操作 pthread_exit(NULL); } // 创建Socket连接 static SQInteger L_CreatSocketConnect(HSQUIRRELVM v) { const SQChar *Host; const SQChar *Port; sq_getstring(v, 2, &Host); sq_getstring(v, 3, &Port); CreateSocketInfo *Info = new CreateSocketInfo(); Info->Ip = Host; Info->Port = Port; pthread_t SocketThread; // 创建线程1 if (pthread_create(&SocketThread, NULL, SocketThread_function, Info) != 0) { std::cerr << "Error creating thread 1" << std::endl; } return 0; } static SQInteger register_Game_func(HSQUIRRELVM v, SQFUNCTION f, const char *fname) { sq_pushroottable(v); sq_pushstring(v, fname, -1); sq_newclosure(v, f, 0); // create a new function sq_newslot(v, -3, SQFalse); sq_pop(v, 1); // pops the root table } static void Aprintfunc(const SQChar *s, ...) { fflush(stdout); va_list vl; va_start(vl, s); scvprintf(stdout, s, vl); va_end(vl); printf("\n"); fflush(stdout); } // CallFunc static SQInteger L_CallFunc(HSQUIRRELVM v) { // 得到参数个数 SQInteger Count = sq_gettop(v); // 得到函数地址 SQUserPointer FuncAddress; sq_getuserpointer(v, 2, &FuncAddress); // 得到返回值类型 const SQChar *RetType; sq_getstring(v, 3, &RetType); std::vector ParameterType; // 遍历参数类型数组 sq_pushnull(v); // null iterator while (SQ_SUCCEEDED(sq_next(v, 4))) { const SQChar *path; sq_getstring(v, -1, &path); ParameterType.push_back(path); sq_pop(v, 2); } sq_pop(v, 1); // 头部信息个数 int HeaderCount = 4; // 计算valist内存 int AdrSize = 0; for (std::string Type : ParameterType) { if (CONTAINS_STRING(Type, "int")) AdrSize += sizeof(int); else if (CONTAINS_STRING(Type, "bool")) AdrSize += sizeof(bool); else if (CONTAINS_STRING(Type, "string")) AdrSize += sizeof(char *); else if (CONTAINS_STRING(Type, "float")) AdrSize += sizeof(float); else if (CONTAINS_STRING(Type, "pointer")) AdrSize += sizeof(void *); else if (CONTAINS_STRING(Type, "short")) AdrSize += sizeof(short); else if (CONTAINS_STRING(Type, "char")) AdrSize += sizeof(char); } char *m = (char *)malloc(AdrSize); void *bm = m; // 定义函数签名 ffi_cif cif; ffi_type **args = (ffi_type **)malloc(ParameterType.size() * sizeof(ffi_type *)); // 动态分配参数类型数组 void **values = (void **)malloc(ParameterType.size() * sizeof(void *)); // 动态分配参数值数组 ffi_arg result; int CFlag = 0; for (int i = (HeaderCount + 1); i < (Count + 1); i++) { if (CONTAINS_STRING(ParameterType[0], "int")) { sq_getinteger(v, i, (SQInteger *)m); args[CFlag] = &ffi_type_sint; values[CFlag] = m; m += sizeof(int); } else if (CONTAINS_STRING(ParameterType[0], "float")) { sq_getfloat(v, i, (SQFloat *)m); args[CFlag] = &ffi_type_float; values[CFlag] = m; m += sizeof(float); } else if (CONTAINS_STRING(ParameterType[0], "bool")) { sq_getbool(v, i, (SQBool *)m); args[CFlag] = &ffi_type_sint8; values[CFlag] = m; m += sizeof(bool); } else if (CONTAINS_STRING(ParameterType[0], "string")) { sq_getstring(v, i, (const SQChar **)m); args[CFlag] = &ffi_type_pointer; values[CFlag] = m; m += sizeof(void *); } else if (CONTAINS_STRING(ParameterType[0], "pointer")) { sq_getuserpointer(v, i, (SQUserPointer *)m); args[CFlag] = &ffi_type_pointer; values[CFlag] = m; m += sizeof(void *); } else if (CONTAINS_STRING(ParameterType[0], "short")) { sq_getinteger(v, i, (SQInteger *)m); args[CFlag] = &ffi_type_sint16; values[CFlag] = m; m += sizeof(short); } else if (CONTAINS_STRING(ParameterType[0], "char")) { sq_getinteger(v, i, (SQInteger *)m); args[CFlag] = &ffi_type_schar; values[CFlag] = m; m += sizeof(char); } ParameterType.erase(ParameterType.begin()); CFlag++; } ffi_type *RetTypeFlag = &ffi_type_void; std::string RetTypeString = RetType; if (CONTAINS_STRING(RetTypeString, "int")) RetTypeFlag = &ffi_type_sint; else if (CONTAINS_STRING(RetTypeString, "float")) RetTypeFlag = &ffi_type_float; else if (CONTAINS_STRING(RetTypeString, "bool")) RetTypeFlag = &ffi_type_sint8; else if (CONTAINS_STRING(RetTypeString, "string")) RetTypeFlag = &ffi_type_pointer; else if (CONTAINS_STRING(RetTypeString, "pointer")) RetTypeFlag = &ffi_type_pointer; else if (CONTAINS_STRING(RetTypeString, "short")) RetTypeFlag = &ffi_type_sint16; else if (CONTAINS_STRING(RetTypeString, "char")) RetTypeFlag = &ffi_type_schar; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, CFlag, RetTypeFlag, args) == FFI_OK) { // 动态调用函数 ffi_call(&cif, FFI_FN(FuncAddress), &result, values); } free(args); free(values); free(bm); if (CONTAINS_STRING(RetTypeString, "int")) sq_pushinteger(v, (int)result); else if (CONTAINS_STRING(RetTypeString, "float")) sq_pushfloat(v, (float)result); else if (CONTAINS_STRING(RetTypeString, "bool")) sq_pushbool(v, (bool)result); else if (CONTAINS_STRING(RetTypeString, "string")) sq_pushstring(v, (char *)result, -1); else if (CONTAINS_STRING(RetTypeString, "pointer")) sq_pushuserpointer(v, (void *)result); else if (CONTAINS_STRING(RetTypeString, "short")) sq_pushinteger(v, (int)result); else if (CONTAINS_STRING(RetTypeString, "char")) sq_pushinteger(v, (int)result); else return 0; return 1; } static SQInteger L_S_Ptr(HSQUIRRELVM v) { const SQChar *str; sq_getstring(v, 2, &str); unsigned long long addr = std::stoull(str, 0, 16); void *ptr = reinterpret_cast(addr); sq_pushuserpointer(v, ptr); return 1; } static SQInteger L_Str_Ptr(HSQUIRRELVM v) { const SQChar *str; sq_getstring(v, 2, &str); sq_pushuserpointer(v, (void *)str); return 1; } static SQInteger L_Ptr_Operation_A2S(HSQUIRRELVM v) { // 内存地址 int型 SQUserPointer Address; // 获取地址 sq_getuserpointer(v, 2, &Address); SQInteger Offset; sq_getinteger(v, 3, &Offset); sq_pushuserpointer(v, (void *)(Address + Offset)); return 1; } static SQInteger New_Point(HSQUIRRELVM v) { SQInteger Len; sq_getinteger(v, 2, &Len); void *P = malloc(Len); sq_pushuserpointer(v, P); return 1; } static SQInteger Delete_Point(HSQUIRRELVM v) { SQUserPointer P; sq_getuserpointer(v, 2, &P); free(P); return 0; } static SQInteger Sq_getExportByName(HSQUIRRELVM v) { const SQChar *MoudleName; const SQChar *FuncName; sq_getstring(v, 2, &MoudleName); sq_getstring(v, 3, &FuncName); void *handle = dlopen(nullptr, RTLD_LAZY); if (!handle) return 0; void *targetFunctionPtr = dlsym(handle, FuncName); if (!targetFunctionPtr) return 0; sq_pushuserpointer(v, targetFunctionPtr); return 1; } static SQInteger OutPutTable(HSQUIRRELVM v) { const SQChar *Str; sq_getstring(v, 2, &Str); nlohmann::json ex1 = nlohmann::json::parse(Str); std::cout << std::setw(4) << ex1 << std::endl; 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(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 &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 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 } } 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 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 SQInteger L_Sq_Cron_Next(HSQUIRRELVM v) { const SQChar *Str; sq_getstring(v, 2, &Str); SQInteger Date; sq_getinteger(v, 3, &Date); auto cron = cron::make_cron(Str); std::time_t next = cron::cron_next(cron, Date); sq_pushinteger(v, next); return 1; } static SQInteger _stream_myreadstring(HSQUIRRELVM v) { SQStream *self = NULL; if (SQ_FAILED(sq_getinstanceup(v, 1, (SQUserPointer *)&self, (SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG), SQFalse))) return sq_throwerror(v, _SC("invalid type tag")); if (!self || !self->IsValid()) return sq_throwerror(v, _SC("the stream is invalid")); SQInteger Count; sq_getinteger(v, 2, &Count); char *Str = new char[Count + 1]; self->Read(Str, Count); std::string Sstr(Str, Count); delete[] Str; sq_pushstring(v, Sstr.c_str(), -1); return 1; } static SQInteger _CrcDecode(HSQUIRRELVM v) { SQInteger Buffer[4]; sq_pushnull(v); // null iterator int Idx = 0; while (SQ_SUCCEEDED(sq_next(v, -2))) { sq_getinteger(v, -1, &Buffer[Idx]); Idx++; sq_pop(v, 2); } sq_pop(v, 1); SQInteger crc32; sq_getinteger(v, 3, &crc32); int64 num = 2175242257; int64 anInt = ((Buffer[0]) << 0) | ((Buffer[1]) << 8) | ((Buffer[2]) << 16) | ((Buffer[3]) << 24); int64 val = (anInt ^ num ^ crc32); int64 jiemi = (val >> 6) | ((val << (32 - 6)) & 0xFFFFFFFF); sq_newarray(v, 0); for (size_t i = 0; i < 4; i++) { sq_pushinteger(v, (jiemi >> (i * 8)) & 0xFF); sq_arrayappend(v, -2); } return 1; } static SQInteger L_Conversion(HSQUIRRELVM v) { const SQChar *Str; sq_getstring(v, 2, &Str); SQInteger Type; sq_getinteger(v, 3, &Type); std::string traditionalStr = std::string(Str); // sq_pushnull(v); opencc_t ot; if (Type == 0) ot = opencc_open(OPENCC_DEFAULT_CONFIG_TRAD_TO_SIMP); else if (Type == 1) ot = opencc_open(OPENCC_DEFAULT_CONFIG_SIMP_TO_TRAD); char *NewStr = opencc_convert_utf8(ot, traditionalStr.c_str(), traditionalStr.length()); std::string RetStr(NewStr); sq_pushstring(v, RetStr.c_str(), -1); opencc_convert_utf8_free(NewStr); opencc_close(ot); return 1; } static SQInteger L_GetTimestampString(HSQUIRRELVM v) { auto now = std::chrono::system_clock::now(); auto now_ms = std::chrono::time_point_cast(now); auto value = now_ms.time_since_epoch(); long long milliseconds = value.count(); std::ostringstream oss; oss << milliseconds; sq_pushstring(v, oss.str().c_str(), -1); return 1; } #define NSUBHOOK_INIT(func, addr) \ fn##func func = (fn##func)addr; \ FuncHook h##func #define NSUBHOOK_SETUP(func) h##func.Hook((void **)&func, (void *)_##func) typedef int (*fnInven_Item_reset)(void *a1); typedef void *(*fnInven_Item_setcopy)(void *a1, void *a2); NSUBHOOK_INIT(Inven_Item_reset, 0x080CB7D8); int _Inven_Item_reset(void *item) { int ret = Inven_Item_reset(item); memset(item, 0, 61); return ret; } NSUBHOOK_INIT(Inven_Item_setcopy, 0x0814A62E); void *_Inven_Item_setcopy(void *item, void *item2) { Inven_Item_setcopy(item, item2); memcpy(item, item2, 61); return item2; } static SQInteger L_HookEquimentUseJewel(HSQUIRRELVM v) { NSUBHOOK_SETUP(Inven_Item_setcopy); NSUBHOOK_SETUP(Inven_Item_reset); return 0; } static SQInteger LongLongOperation(HSQUIRRELVM v) { const SQChar *valuebuf1; sq_getstring(v, 2, &valuebuf1); long long value1 = std::atoll(valuebuf1); const SQChar *valuebuf2; sq_getstring(v, 3, &valuebuf2); long long value2 = std::atoll(valuebuf2); const SQChar *TypeBuf; sq_getstring(v, 4, &TypeBuf); std::string Type(TypeBuf); std::string RetString = ""; if (Type == "+") { RetString = std::to_string(value1 + value2); } else if (Type == "-") { RetString = std::to_string(value1 - value2); } else if (Type == "*") { RetString = std::to_string((static_cast(value1) * static_cast(value2))); } else if (Type == "/") { RetString = std::to_string((static_cast(value1) / static_cast(value2))); } else if (Type == "%") { RetString = std::to_string(value1 % value2); } else if (Type == "format") { if (value1 < 1000) { RetString = std::to_string(value1); } else if (value1 < 1000000) { RetString = std::to_string(value1 / 1000.0) + "k"; } else if (value1 < 1000000000) { RetString = std::to_string(value1 / 1000000.0) + "M"; } else if (value1 < 1000000000000LL) { RetString = std::to_string(value1 / 1000000000.0) + "G"; } else { RetString = std::to_string(value1 / 1000000000000.0) + "T"; } } sq_pushstring(v, RetString.c_str(), -1); return 1; } static void RegisterGame(HSQUIRRELVM v) { getConfigPath(szGamePath, sizeof(szGamePath)); // 获取字符串时间戳 register_World_func(v, L_GetTimestampString, _SC("Sq_GetTimestampString")); // 简繁转换 register_World_func(v, L_Conversion, _SC("Sq_Conversion")); // 获取下一个cron register_World_func(v, L_Sq_Cron_Next, _SC("Sq_Cron_Next")); // 自身封装读取流 register_World_func(v, _stream_myreadstring, _SC("stream_myreadstring")); register_World_func(v, _CrcDecode, _SC("Sq_CrcDecode")); // int 和指针相互转换 register_World_func(v, RunScript, _SC("sq_RunScript")); register_World_func(v, L_Ptr2Int, _SC("Sq_Ptr2Int")); register_World_func(v, L_Int2Ptr, _SC("Sq_Int2Ptr")); register_World_func(v, L_S_Ptr, _SC("S_Ptr")); register_World_func(v, L_Str_Ptr, _SC("Str_Ptr")); // 指针运算 register_World_func(v, L_Ptr_Operation_A2S, _SC("Ptr_Operation_A2S")); // new一个指针 register_World_func(v, New_Point, _SC("Sq_New_Point")); // 销毁一个指针 register_World_func(v, Delete_Point, _SC("Sq_Delete_Point")); // 获取频道配置 register_World_func(v, Game_GetConfig, _SC("Sq_Game_GetConfig")); // 写地址int register_World_func(v, L_WriteAddress, _SC("Sq_WriteAddress")); // 读地址int register_World_func(v, L_ReadAddress, _SC("Sq_ReadAddress")); // 读地址Point register_World_func(v, L_ReadPoint, _SC("Sq_ReadPoint")); // 读地址字符串 register_World_func(v, L_ReadAddressString, _SC("Sq_ReadAddressString")); // 读取Byte register_World_func(v, L_ReadByteArr, _SC("Sq_ReadByteArr")); // 写入Byte register_World_func(v, L_WriteByteArr, _SC("Sq_WriteByteArr")); // 通过指针转Blob register_World_func(v, L_Point2Blob, _SC("Sq_Point2Blob")); // 写Blob到指定地址 register_World_func(v, L_WriteBlobToAddress, _SC("Sq_WriteBlobToAddress")); // 通过ID从Pvf中查询名称 register_World_func(v, L_GetNameByIdFromPvf, _SC("Sq_GetNameByIdFromPvf")); // 通过ID从Pvf中查询Data register_World_func(v, L_GetDataByIdFromPvf, _SC("Sq_GetDataByIdFromPvf")); // 创建数据库连接池 register_World_func(v, L_CreatCConnectPool, _SC("Sq_CreatCConnectPool")); // 阻塞线程的数据库操作 无返回值 register_World_func(v, L_MysqlExecNoRet, _SC("Sq_MysqlExecNoRet")); // 创建Socket连接 register_World_func(v, L_CreatSocketConnect, _SC("Sq_CreatSocketConnect")); // 动态调用Call register_World_func(v, L_CallFunc, _SC("Sq_CallFunc")); // 获取模块函数地址 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")); // Hook装备镶嵌 register_World_func(v, L_HookEquimentUseJewel, _SC("L_HookEquimentUseJewel")); //大数字计算 register_World_func(v, LongLongOperation, _SC("Sq_LongLongOperation")); }