| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | #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"
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | #include "l_socket.h"
 | 
					
						
							| 
									
										
										
										
											2024-10-02 15:04:35 +08:00
										 |  |  |  | #include <openssl/md5.h>
 | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | #include <iostream>
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | #include <functional>
 | 
					
						
							|  |  |  |  | #include <list>
 | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  | #include <ffi.h>
 | 
					
						
							| 
									
										
										
										
											2024-09-20 00:17:48 +08:00
										 |  |  |  | #include "nlohmann/json.hpp"
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  | #define CONTAINS_STRING(str, substr) (str == substr)
 | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | template <typename R, typename A, typename... ARG> | 
					
						
							|  |  |  |  | R CallGameT(A call_addr, const ARG... arguments) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     if (!call_addr) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         return R(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     const auto control = reinterpret_cast<R (*)(ARG...)>(call_addr); | 
					
						
							|  |  |  |  |     try | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         return control(arguments...); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     catch (...) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return R(); | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  | template <typename R> | 
					
						
							|  |  |  |  | R CallGameRT(void *call_addr, va_list arguments, std::vector<std::string> 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(); | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 11:35:30 +08:00
										 |  |  |  | // 加密函数
 | 
					
						
							|  |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | // 指针转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; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-09-17 11:41:25 +08:00
										 |  |  |  | // 读内存
 | 
					
						
							|  |  |  |  | static SQInteger L_ReadPoint(HSQUIRRELVM v) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // 内存地址 int型
 | 
					
						
							|  |  |  |  |     SQUserPointer Address; | 
					
						
							|  |  |  |  |     // 获取地址
 | 
					
						
							|  |  |  |  |     sq_getuserpointer(v, 2, &Address); | 
					
						
							|  |  |  |  |     int *ptr = reinterpret_cast<int *>(Address); | 
					
						
							|  |  |  |  |     int value = *ptr; | 
					
						
							|  |  |  |  |     sq_pushuserpointer(v, (void *)(value)); | 
					
						
							|  |  |  |  |     return 1; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | // 读内存字符串
 | 
					
						
							|  |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // 读取字节数组
 | 
					
						
							|  |  |  |  | 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); | 
					
						
							| 
									
										
										
										
											2024-09-15 13:08:42 +08:00
										 |  |  |  |         CMem::WriteUChar((Address + Idx), Buf); | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  |         // 这里-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<void *>(0x835FA32, CallGameT<void *>(0x80CC19B), (unsigned int)Idx); | 
					
						
							|  |  |  |  |     if (Ret) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         const char *Name = CallGameT<const char *>(0x811ed82, Ret); | 
					
						
							|  |  |  |  |         sq_pushstring(v, Name, -1); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     else | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         sq_pushnull(v); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return 1; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | // 通过ID从Pvf中查询Data
 | 
					
						
							|  |  |  |  | static SQInteger L_GetDataByIdFromPvf(HSQUIRRELVM v) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     SQInteger Idx; | 
					
						
							|  |  |  |  |     sq_getinteger(v, 2, &Idx); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     void *Ret = CallGameT<void *>(0x835FA32, CallGameT<void *>(0x80CC19B), (unsigned int)Idx); | 
					
						
							|  |  |  |  |     if (Ret) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         sq_pushuserpointer(v, Ret); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     else | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         sq_pushnull(v); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return 1; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | // 创建数据库连接池
 | 
					
						
							|  |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | 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
 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 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) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     // 得到参数个数
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     SQInteger Count = sq_gettop(v); | 
					
						
							|  |  |  |  |     // 得到函数地址
 | 
					
						
							|  |  |  |  |     SQUserPointer FuncAddress; | 
					
						
							|  |  |  |  |     sq_getuserpointer(v, 2, &FuncAddress); | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     // 得到返回值类型
 | 
					
						
							|  |  |  |  |     const SQChar *RetType; | 
					
						
							|  |  |  |  |     sq_getstring(v, 3, &RetType); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     std::vector<std::string> 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); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 头部信息个数
 | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     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); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     char *m = (char *)malloc(AdrSize); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     void *bm = m; | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     // 定义函数签名
 | 
					
						
							|  |  |  |  |     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++) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         if (CONTAINS_STRING(ParameterType[0], "int")) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |             sq_getinteger(v, i, (SQInteger *)m); | 
					
						
							|  |  |  |  |             args[CFlag] = &ffi_type_sint; | 
					
						
							|  |  |  |  |             values[CFlag] = m; | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |             m += sizeof(int); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         else if (CONTAINS_STRING(ParameterType[0], "float")) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |             sq_getfloat(v, i, (SQFloat *)m); | 
					
						
							|  |  |  |  |             args[CFlag] = &ffi_type_float; | 
					
						
							|  |  |  |  |             values[CFlag] = m; | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |             m += sizeof(float); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         else if (CONTAINS_STRING(ParameterType[0], "bool")) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |             sq_getbool(v, i, (SQBool *)m); | 
					
						
							|  |  |  |  |             args[CFlag] = &ffi_type_sint8; | 
					
						
							|  |  |  |  |             values[CFlag] = m; | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |             m += sizeof(bool); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         else if (CONTAINS_STRING(ParameterType[0], "string")) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             sq_getstring(v, i, (const SQChar **)m); | 
					
						
							|  |  |  |  |             args[CFlag] = &ffi_type_pointer; | 
					
						
							|  |  |  |  |             values[CFlag] = m; | 
					
						
							|  |  |  |  |             m += sizeof(void *); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         else if (CONTAINS_STRING(ParameterType[0], "pointer")) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |             sq_getuserpointer(v, i, (SQUserPointer *)m); | 
					
						
							|  |  |  |  |             args[CFlag] = &ffi_type_pointer; | 
					
						
							|  |  |  |  |             values[CFlag] = m; | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |             m += sizeof(void *); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         else if (CONTAINS_STRING(ParameterType[0], "short")) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             sq_getinteger(v, i, (SQInteger *)m); | 
					
						
							|  |  |  |  |             args[CFlag] = &ffi_type_sint16; | 
					
						
							|  |  |  |  |             values[CFlag] = m; | 
					
						
							|  |  |  |  |             m += sizeof(short); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         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++; | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     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) | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |         // 动态调用函数
 | 
					
						
							|  |  |  |  |         ffi_call(&cif, FFI_FN(FuncAddress), &result, values); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 09:07:41 +08:00
										 |  |  |  |     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; | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-09-22 21:36:40 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 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<void *>(addr); | 
					
						
							|  |  |  |  |     sq_pushuserpointer(v, ptr); | 
					
						
							|  |  |  |  |     return 1; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-07-22 19:26:56 +08:00
										 |  |  |  | static SQInteger L_Str_Ptr(HSQUIRRELVM v) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     const SQChar *str; | 
					
						
							|  |  |  |  |     sq_getstring(v, 2, &str); | 
					
						
							|  |  |  |  |     sq_pushuserpointer(v, (void *)str); | 
					
						
							|  |  |  |  |     return 1; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-09-17 11:41:25 +08:00
										 |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-07-22 19:26:56 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-17 11:41:25 +08:00
										 |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-09-16 17:07:36 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-20 00:17:48 +08:00
										 |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 15:04:35 +08:00
										 |  |  |  | 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; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | static void RegisterGame(HSQUIRRELVM v) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     getConfigPath(szGamePath, sizeof(szGamePath)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // int 和指针相互转换
 | 
					
						
							| 
									
										
										
										
											2024-09-18 11:35:30 +08:00
										 |  |  |  |     register_World_func(v, RunScript, _SC("sq_RunScript")); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  |     register_World_func(v, L_Ptr2Int, _SC("Sq_Ptr2Int")); | 
					
						
							|  |  |  |  |     register_World_func(v, L_Int2Ptr, _SC("Sq_Int2Ptr")); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     register_World_func(v, L_S_Ptr, _SC("S_Ptr")); | 
					
						
							| 
									
										
										
										
											2024-07-22 19:26:56 +08:00
										 |  |  |  |     register_World_func(v, L_Str_Ptr, _SC("Str_Ptr")); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-20 00:17:48 +08:00
										 |  |  |  |     // 指针运算
 | 
					
						
							| 
									
										
										
										
											2024-09-17 11:41:25 +08:00
										 |  |  |  |     register_World_func(v, L_Ptr_Operation_A2S, _SC("Ptr_Operation_A2S")); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 19:26:56 +08:00
										 |  |  |  |     // new一个指针
 | 
					
						
							|  |  |  |  |     register_World_func(v, New_Point, _SC("Sq_New_Point")); | 
					
						
							|  |  |  |  |     // 销毁一个指针
 | 
					
						
							|  |  |  |  |     register_World_func(v, Delete_Point, _SC("Sq_Delete_Point")); | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 获取频道配置
 | 
					
						
							|  |  |  |  |     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")); | 
					
						
							| 
									
										
										
										
											2024-09-17 11:41:25 +08:00
										 |  |  |  |     // 读地址Point
 | 
					
						
							|  |  |  |  |     register_World_func(v, L_ReadPoint, _SC("Sq_ReadPoint")); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     // 读地址字符串
 | 
					
						
							|  |  |  |  |     register_World_func(v, L_ReadAddressString, _SC("Sq_ReadAddressString")); | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  |     // 读取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")); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     // 通过ID从Pvf中查询Data
 | 
					
						
							|  |  |  |  |     register_World_func(v, L_GetDataByIdFromPvf, _SC("Sq_GetDataByIdFromPvf")); | 
					
						
							| 
									
										
										
										
											2024-04-24 10:25:44 +08:00
										 |  |  |  |     // 创建数据库连接池
 | 
					
						
							|  |  |  |  |     register_World_func(v, L_CreatCConnectPool, _SC("Sq_CreatCConnectPool")); | 
					
						
							|  |  |  |  |     // 阻塞线程的数据库操作 无返回值
 | 
					
						
							|  |  |  |  |     register_World_func(v, L_MysqlExecNoRet, _SC("Sq_MysqlExecNoRet")); | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     // 创建Socket连接
 | 
					
						
							|  |  |  |  |     register_World_func(v, L_CreatSocketConnect, _SC("Sq_CreatSocketConnect")); | 
					
						
							| 
									
										
										
										
											2024-09-20 00:17:48 +08:00
										 |  |  |  |     // 动态调用Call
 | 
					
						
							| 
									
										
										
										
											2024-04-30 03:01:48 +08:00
										 |  |  |  |     register_World_func(v, L_CallFunc, _SC("Sq_CallFunc")); | 
					
						
							| 
									
										
										
										
											2024-09-20 00:17:48 +08:00
										 |  |  |  |     // 获取模块函数地址
 | 
					
						
							| 
									
										
										
										
											2024-09-17 11:41:25 +08:00
										 |  |  |  |     register_World_func(v, Sq_getExportByName, _SC("Sq_getExportByName")); | 
					
						
							| 
									
										
										
										
											2024-09-20 00:17:48 +08:00
										 |  |  |  |     // 打印表
 | 
					
						
							|  |  |  |  |     register_World_func(v, OutPutTable, _SC("Sq_OutPutTable")); | 
					
						
							| 
									
										
										
										
											2024-10-02 15:04:35 +08:00
										 |  |  |  |     // 开启自动热重载
 | 
					
						
							|  |  |  |  |     register_World_func(v, AutoReload, _SC("Sq_AutoReload")); | 
					
						
							| 
									
										
										
										
											2024-09-16 17:07:36 +08:00
										 |  |  |  | } |