Commit message
This commit is contained in:
@@ -11,16 +11,9 @@
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <ffi.h>
|
||||
|
||||
// 函数返回值类型枚举
|
||||
enum RETTYPE
|
||||
{
|
||||
INT,
|
||||
FLOAT,
|
||||
BOOL,
|
||||
STRING,
|
||||
POINTER
|
||||
};
|
||||
#define CONTAINS_STRING(str, substr) (str == substr)
|
||||
|
||||
template <typename R, typename A, typename... ARG>
|
||||
R CallGameT(A call_addr, const ARG... arguments)
|
||||
@@ -39,6 +32,41 @@ R CallGameT(A call_addr, const ARG... arguments)
|
||||
}
|
||||
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)
|
||||
@@ -394,78 +422,161 @@ static void Aprintfunc(const SQChar *s, ...)
|
||||
// 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);
|
||||
// 得到返回值类型
|
||||
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 = 3;
|
||||
int HeaderCount = 4;
|
||||
|
||||
char *m = (char *)malloc((Count - 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;
|
||||
for (int i = 0; i < (Count - HeaderCount); i++)
|
||||
// 定义函数签名
|
||||
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++)
|
||||
{
|
||||
SQObjectType Type = sq_gettype(v, HeaderCount + 1 + i);
|
||||
switch (Type)
|
||||
if (CONTAINS_STRING(ParameterType[0], "int"))
|
||||
{
|
||||
case OT_INTEGER:
|
||||
{
|
||||
SQInteger Buf;
|
||||
sq_getinteger(v, HeaderCount + 1 + i, &Buf);
|
||||
(*(int *)m) = Buf;
|
||||
sq_getinteger(v, i, (SQInteger *)m);
|
||||
args[CFlag] = &ffi_type_sint;
|
||||
values[CFlag] = m;
|
||||
m += sizeof(int);
|
||||
break;
|
||||
}
|
||||
case OT_FLOAT:
|
||||
else if (CONTAINS_STRING(ParameterType[0], "float"))
|
||||
{
|
||||
SQFloat Buf;
|
||||
sq_getfloat(v, HeaderCount + 1 + i, &Buf);
|
||||
(*(float *)m) = Buf;
|
||||
sq_getfloat(v, i, (SQFloat *)m);
|
||||
args[CFlag] = &ffi_type_float;
|
||||
values[CFlag] = m;
|
||||
m += sizeof(float);
|
||||
break;
|
||||
}
|
||||
case OT_BOOL:
|
||||
else if (CONTAINS_STRING(ParameterType[0], "bool"))
|
||||
{
|
||||
SQBool Buf;
|
||||
sq_getbool(v, HeaderCount + 1 + i, &Buf);
|
||||
(*(bool *)m) = Buf;
|
||||
sq_getbool(v, i, (SQBool *)m);
|
||||
args[CFlag] = &ffi_type_sint8;
|
||||
values[CFlag] = m;
|
||||
m += sizeof(bool);
|
||||
break;
|
||||
}
|
||||
case OT_STRING:
|
||||
else if (CONTAINS_STRING(ParameterType[0], "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;
|
||||
|
||||
sq_getstring(v, i, (const SQChar **)m);
|
||||
args[CFlag] = &ffi_type_pointer;
|
||||
values[CFlag] = m;
|
||||
m += sizeof(void *);
|
||||
break;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
|
||||
switch (RetType)
|
||||
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)
|
||||
{
|
||||
case POINTER:
|
||||
{
|
||||
void *B = CallGameT<void *>(FuncAddress, (va_list)bm);
|
||||
free(bm);
|
||||
sq_pushuserpointer(v, B);
|
||||
return 1;
|
||||
}
|
||||
// 动态调用函数
|
||||
ffi_call(&cif, FFI_FN(FuncAddress), &result, values);
|
||||
}
|
||||
|
||||
return 0;
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -289,6 +289,7 @@ static SQInteger CUser_SendItemSpace(HSQUIRRELVM v)
|
||||
SQInteger itemSpace;
|
||||
sq_getinteger(v, 3, &itemSpace);
|
||||
|
||||
std::cout << *(int *)P << std::endl;
|
||||
CallUser<int>(0x865DB6C, P, itemSpace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ public:
|
||||
socket(io_context)
|
||||
{
|
||||
endpoint = resolver.resolve(Ip, Port);
|
||||
this->Ip = Ip;
|
||||
this->Port = Port;
|
||||
PackData.fill(0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user