DP_S/include/SqrReg_Game.hpp

1126 lines
30 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 "croncpp.h"
#include "l_socket.h"
#include <openssl/md5.h>
#include <opencc/opencc.h>
#include <iostream>
#include <functional>
#include <list>
#include <ffi.h>
#include <iconv.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;
}
const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string base64_encode(const std::string &in)
{
std::string out;
int val = 0;
int valb = -6;
for (unsigned char c : in)
{
val = (val << 8) + c;
valb += 8;
while (valb >= 0)
{
out.push_back(base64_chars[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6)
{
out.push_back(base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
}
while (out.size() % 4)
{
out.push_back('=');
}
return out;
}
std::string calculateMD5(const std::string &filePath)
{
std::ifstream file(filePath, std::ios::binary | std::ios::ate);
if (!file)
{
return "";
}
std::streampos size = file.tellg();
file.seekg(0, std::ios::beg);
unsigned char buffer[16];
MD5_CTX md5Context;
MD5_Init(&md5Context);
while (file.read(reinterpret_cast<char *>(buffer), sizeof(buffer)))
{
MD5_Update(&md5Context, buffer, file.gcount());
}
MD5_Final(buffer, &md5Context);
file.close();
return base64_encode((char *)buffer);
}
void processDirectory(const std::string &directoryPath, std::unordered_map<std::string, std::string> &fileMD5Map)
{
DIR *dir;
struct dirent *entry;
if ((dir = opendir(directoryPath.c_str())) != nullptr)
{
while ((entry = readdir(dir)) != nullptr)
{
if (entry->d_type == DT_REG)
{
std::string filePath = directoryPath + "/" + entry->d_name;
std::string currentMD5 = calculateMD5(filePath);
if (fileMD5Map.find(filePath) != fileMD5Map.end())
{
if (fileMD5Map[filePath] != currentMD5)
{
fileMD5Map[filePath] = currentMD5;
std::lock_guard<std::recursive_mutex> lock(SqMtx);
// 执行虚拟机Main函数
SQInteger top = sq_gettop(v); // saves the stack size before the call
sq_pushroottable(v); // pushes the global table
sq_pushstring(v, _SC("_Reload_List_Write_"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2)))
{ // gets the field 'foo' from the global table
sq_pushroottable(v); // push the 'this' (in this case is the global table)
sq_pushstring(v, filePath.c_str(), -1);
sq_call(v, 2, SQFalse, SQTrue); // calls the function
}
sq_settop(v, top); // restores the original stack size
}
}
else
{
fileMD5Map[filePath] = currentMD5;
}
}
else if (entry->d_type == DT_DIR && std::string(entry->d_name) != "." && std::string(entry->d_name) != "..")
{
processDirectory(directoryPath + "/" + entry->d_name, fileMD5Map);
}
}
closedir(dir);
}
else
{
std::cerr << "无法打开目录:" << directoryPath << std::endl;
}
}
struct AutoReloadSt
{
std::string Path;
};
static void *continuousMonitoring(void *arg)
{
AutoReloadSt *Info = (AutoReloadSt *)arg;
std::unordered_map<std::string, std::string> fileMD5Map;
while (true)
{
processDirectory(Info->Path, fileMD5Map);
usleep(1000); // 每隔 1 秒检查一次
}
}
static SQInteger AutoReload(HSQUIRRELVM v)
{
const SQChar *Str;
sq_getstring(v, 2, &Str);
AutoReloadSt *Info = new AutoReloadSt();
Info->Path = std::string(Str);
// 开启DP-S 自动热重载
// std::string targetDirectory = (char *)Str;
// std::thread monitorThread(continuousMonitoring, targetDirectory);
// monitorThread.join();
pthread_t MonitoringThread;
// 创建线程1
if (pthread_create(&MonitoringThread, NULL, continuousMonitoring, Info) != 0)
{
std::cerr << "Error creating thread 1" << std::endl;
}
return 0;
}
static SQInteger L_Sq_Cron_Next(HSQUIRRELVM v)
{
const SQChar *Str;
sq_getstring(v, 2, &Str);
SQInteger Date;
sq_getinteger(v, 3, &Date);
auto cron = cron::make_cron(Str);
std::time_t next = cron::cron_next(cron, Date);
sq_pushinteger(v, next);
return 1;
}
static SQInteger _stream_myreadstring(HSQUIRRELVM v)
{
SQStream *self = NULL;
if (SQ_FAILED(sq_getinstanceup(v, 1, (SQUserPointer *)&self, (SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG), SQFalse)))
return sq_throwerror(v, _SC("invalid type tag"));
if (!self || !self->IsValid())
return sq_throwerror(v, _SC("the stream is invalid"));
SQInteger Count;
sq_getinteger(v, 2, &Count);
char *Str = new char[Count + 1];
self->Read(Str, Count);
std::string Sstr(Str, Count);
delete[] Str;
sq_pushstring(v, Sstr.c_str(), -1);
return 1;
}
static SQInteger _CrcDecode(HSQUIRRELVM v)
{
SQInteger Buffer[4];
sq_pushnull(v); // null iterator
int Idx = 0;
while (SQ_SUCCEEDED(sq_next(v, -2)))
{
sq_getinteger(v, -1, &Buffer[Idx]);
Idx++;
sq_pop(v, 2);
}
sq_pop(v, 1);
SQInteger crc32;
sq_getinteger(v, 3, &crc32);
int64 num = 2175242257;
int64 anInt = ((Buffer[0]) << 0) | ((Buffer[1]) << 8) | ((Buffer[2]) << 16) | ((Buffer[3]) << 24);
int64 val = (anInt ^ num ^ crc32);
int64 jiemi = (val >> 6) | ((val << (32 - 6)) & 0xFFFFFFFF);
sq_newarray(v, 0);
for (size_t i = 0; i < 4; i++)
{
sq_pushinteger(v, (jiemi >> (i * 8)) & 0xFF);
sq_arrayappend(v, -2);
}
return 1;
}
static SQInteger L_Conversion(HSQUIRRELVM v)
{
const SQChar *Str;
sq_getstring(v, 2, &Str);
SQInteger Type;
sq_getinteger(v, 3, &Type);
std::string traditionalStr = std::string(Str);
// sq_pushnull(v);
opencc_t ot;
if (Type == 0)
ot = opencc_open(OPENCC_DEFAULT_CONFIG_TRAD_TO_SIMP);
else if (Type == 1)
ot = opencc_open(OPENCC_DEFAULT_CONFIG_SIMP_TO_TRAD);
char *NewStr = opencc_convert_utf8(ot, traditionalStr.c_str(), traditionalStr.length());
std::string RetStr(NewStr);
sq_pushstring(v, RetStr.c_str(), -1);
opencc_convert_utf8_free(NewStr);
opencc_close(ot);
return 1;
}
static SQInteger L_GetTimestampString(HSQUIRRELVM v)
{
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto value = now_ms.time_since_epoch();
long long milliseconds = value.count();
std::ostringstream oss;
oss << milliseconds;
sq_pushstring(v, oss.str().c_str(), -1);
return 1;
}
#define NSUBHOOK_INIT(func, addr) \
fn##func func = (fn##func)addr; \
FuncHook h##func
#define NSUBHOOK_SETUP(func) h##func.Hook((void **)&func, (void *)_##func)
typedef int (*fnInven_Item_reset)(void *a1);
typedef void *(*fnInven_Item_setcopy)(void *a1, void *a2);
NSUBHOOK_INIT(Inven_Item_reset, 0x080CB7D8);
int _Inven_Item_reset(void *item)
{
int ret = Inven_Item_reset(item);
memset(item, 0, 61);
return ret;
}
NSUBHOOK_INIT(Inven_Item_setcopy, 0x0814A62E);
void *_Inven_Item_setcopy(void *item, void *item2)
{
Inven_Item_setcopy(item, item2);
memcpy(item, item2, 61);
return item2;
}
static SQInteger L_HookEquimentUseJewel(HSQUIRRELVM v)
{
NSUBHOOK_SETUP(Inven_Item_setcopy);
NSUBHOOK_SETUP(Inven_Item_reset);
return 0;
}
static SQInteger LongLongOperation(HSQUIRRELVM v)
{
const SQChar *valuebuf1;
sq_getstring(v, 2, &valuebuf1);
long long value1 = std::atoll(valuebuf1);
const SQChar *valuebuf2;
sq_getstring(v, 3, &valuebuf2);
long long value2 = std::atoll(valuebuf2);
const SQChar *TypeBuf;
sq_getstring(v, 4, &TypeBuf);
std::string Type(TypeBuf);
std::string RetString = "";
if (Type == "+")
{
RetString = std::to_string(value1 + value2);
}
else if (Type == "-")
{
RetString = std::to_string(value1 - value2);
}
else if (Type == "*")
{
RetString = std::to_string((static_cast<double>(value1) * static_cast<double>(value2)));
}
else if (Type == "/")
{
RetString = std::to_string((static_cast<double>(value1) / static_cast<double>(value2)));
}
else if (Type == "%")
{
RetString = std::to_string(value1 % value2);
}
else if (Type == "format")
{
if (value1 < 1000)
{
RetString = std::to_string(value1);
}
else if (value1 < 1000000)
{
RetString = std::to_string(value1 / 1000.0) + "k";
}
else if (value1 < 1000000000)
{
RetString = std::to_string(value1 / 1000000.0) + "M";
}
else if (value1 < 1000000000000LL)
{
RetString = std::to_string(value1 / 1000000000.0) + "G";
}
else
{
RetString = std::to_string(value1 / 1000000000000.0) + "T";
}
}
sq_pushstring(v, RetString.c_str(), -1);
return 1;
}
static void RegisterGame(HSQUIRRELVM v)
{
getConfigPath(szGamePath, sizeof(szGamePath));
// 获取字符串时间戳
register_World_func(v, L_GetTimestampString, _SC("Sq_GetTimestampString"));
// 简繁转换
register_World_func(v, L_Conversion, _SC("Sq_Conversion"));
// 获取下一个cron
register_World_func(v, L_Sq_Cron_Next, _SC("Sq_Cron_Next"));
// 自身封装读取流
register_World_func(v, _stream_myreadstring, _SC("stream_myreadstring"));
register_World_func(v, _CrcDecode, _SC("Sq_CrcDecode"));
// 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"));
// 开启自动热重载
register_World_func(v, AutoReload, _SC("Sq_AutoReload"));
// Hook装备镶嵌
register_World_func(v, L_HookEquimentUseJewel, _SC("L_HookEquimentUseJewel"));
//大数字计算
register_World_func(v, LongLongOperation, _SC("Sq_LongLongOperation"));
}