#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 "l_socket.h" #include #include #include // 函数返回值类型枚举 enum RETTYPE { INT, FLOAT, BOOL, STRING, POINTER }; 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(); } 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; } // 指针转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_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); 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); SQInteger RetType; sq_getinteger(v, 3, &RetType); // 头部信息个数 int HeaderCount = 3; char *m = (char *)malloc((Count - HeaderCount) * 4); void *bm = m; for (int i = 0; i < (Count - HeaderCount); i++) { SQObjectType Type = sq_gettype(v, HeaderCount + 1 + i); switch (Type) { case OT_INTEGER: { SQInteger Buf; sq_getinteger(v, HeaderCount + 1 + i, &Buf); (*(int *)m) = Buf; m += sizeof(int); break; } case OT_FLOAT: { SQFloat Buf; sq_getfloat(v, HeaderCount + 1 + i, &Buf); (*(float *)m) = Buf; m += sizeof(float); break; } case OT_BOOL: { SQBool Buf; sq_getbool(v, HeaderCount + 1 + i, &Buf); (*(bool *)m) = Buf; m += sizeof(bool); break; } case OT_STRING: { const SQChar *Buf; sq_getstring(v, HeaderCount + 1 + i, &Buf); (*(char **)m) = (char *)Buf; m += sizeof(char *); break; } case OT_USERPOINTER: { SQUserPointer Buf; sq_getuserpointer(v, HeaderCount + 1 + i, &Buf); (*(void **)m) = Buf; m += sizeof(void *); break; } } } switch (RetType) { case POINTER: { void *B = CallGameT(FuncAddress, (va_list)bm); free(bm); sq_pushuserpointer(v, B); return 1; } } return 0; } 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 void RegisterGame(HSQUIRRELVM v) { getConfigPath(szGamePath, sizeof(szGamePath)); // int 和指针相互转换 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, 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")); // 读地址字符串 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")); register_World_func(v, L_CallFunc, _SC("Sq_CallFunc")); }