DP_S/include/SqrReg_Game.hpp

772 lines
20 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 "l_socket.h"
#include <iostream>
#include <functional>
#include <list>
#include <ffi.h>
#include "nlohmann/json.hpp"
#define CONTAINS_STRING(str, substr) (str == substr)
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();
}
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();
}
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<int *>(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<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;
}
// 通过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;
}
// 创建数据库连接池
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<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);
// 头部信息个数
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<void *>(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;
}
static void RegisterGame(HSQUIRRELVM v)
{
getConfigPath(szGamePath, sizeof(szGamePath));
// 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"));
}