325 lines
7.8 KiB
C++
325 lines
7.8 KiB
C++
#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 <iostream>
|
||
|
||
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();
|
||
}
|
||
|
||
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_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<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;
|
||
}
|
||
// 创建数据库连接池
|
||
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;
|
||
}
|
||
|
||
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 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, 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"));
|
||
// 读取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"));
|
||
// 创建数据库连接池
|
||
register_World_func(v, L_CreatCConnectPool, _SC("Sq_CreatCConnectPool"));
|
||
// 阻塞线程的数据库操作 无返回值
|
||
register_World_func(v, L_MysqlExecNoRet, _SC("Sq_MysqlExecNoRet"));
|
||
} |