DP_S/include/SqrReg_Game.hpp

325 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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"));
}