DP_S/src/df_main.cpp

784 lines
22 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.

#include "import.h"
#include "l_squirrel.h"
#include "l_socket.h"
#include "controller.h"
#include "CConnectPool.h"
extern HSQUIRRELVM v;
extern std::recursive_mutex SqMtx;
#define MY_VERSION ("BuildTime " __DATE__ " " __TIME__)
int n_sleep_time = 10000;
int bGMMode = 0, bFairPVP = 0, bPickupRout = 0;
// SUBHOOK_INIT(PacketGuard, 0x0858DD4C);
SUBHOOK_INIT(GetVectorUserCharacInfo, 0x081A0BB8);
SUBHOOK_INIT(doDispatch, 0x08594922);
SUBHOOK_INIT(addServerHackCnt, 0x080F8C7E);
SUBHOOK_INIT(put_header, 0x080CB8FC);
SUBHOOK_INIT(IsRoutingItem, 0x08150F18);
SUBHOOK_INIT(setCharacInfoDetail, 0x0864AC1A);
SUBHOOK_INIT(IsGameMasterMode, 0x0811EDEE);
SUBHOOK_INIT(isGMUser, 0x0814589C);
SUBHOOK_INIT(GetPvPTeamCount, 0x08568CE0);
SUBHOOK_INIT(isGM, 0x08109346);
SUBHOOK_INIT(isGM1, 0x0829948C);
SUBHOOK_INIT(set_add_info, 0x080CB884);
SUBHOOK_INIT(get_dispatcher, 0x085948E2);
SUBHOOK_INIT(dispatch_template, 0x081258B6);
SUBHOOK_INIT(isSocketAvatar, 0x082F9228);
SUBHOOK_INIT(reach_game_world, 0x086C4E50);
SUBHOOK_INIT(Inter_LoadEtc_dispatch_sig, 0x084C0264);
SUBHOOK_INIT(Inter_LoadGeolocation_dispatch_sig, 0x0816088A);
SUBHOOK_INIT(Leninsert_user, 0x086C25A6);
SUBHOOK_INIT(LenGameWorld_move_position, 0x086C5706);
SUBHOOK_INIT(LenGetTimerMess, 0x08630ECC);
SUBHOOK_INIT(Lengetareauseridlist, 0x086C305E);
SUBHOOK_INIT(ReqDBSendNewSystemMultiMail, 0x08556B68);
SUBHOOK_INIT(AddItem, 0x0867B6D4);
SUBHOOK_INIT(InterSelectMobileAuthReward, 0x0816132A);
SUBHOOK_INIT(CreateSkill, 0x084024E6);
SUBHOOK_INIT(CreateEquip, 0x084023AC);
SUBHOOK_INIT(History_Log, 0x854F990);
//_setCharacInfoDetail
int checkGame(const char *pName)
{
char path[256];
char *path_end;
memset(path, 0, sizeof(path));
if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)
return -1;
path_end = strrchr(path, '/');
if (!path_end || strlen(path_end) < 9)
return -1;
return strcmp(pName, ++path_end);
}
int open_main_module_file()
{
char path[256];
memset(path, 0, sizeof(path));
if (readlink("/proc/self/exe", path, sizeof(path)) <= 0)
return -1;
return open(path, O_RDONLY);
}
int GetProfileString(const char *profile, const char *section, const char *key, char **val)
{
int hFile = open(profile, O_RDONLY);
if (hFile == -1)
return -1;
struct stat st;
fstat(hFile, &st);
void *pFileData = mmap(0, st.st_size, PROT_READ, MAP_SHARED, hFile, 0);
if (!pFileData)
{
close(hFile);
return -1;
}
unsigned char readSection = 0, readKey = 1, readValue = 0, got = 0, notes = 0;
char *cur = (char *)pFileData, *end = (char *)pFileData + st.st_size;
char *sectionbuf = (char *)malloc(1024), *keybuf = (char *)malloc(1024), *valuebuf = (char *)malloc(1024);
memset(sectionbuf, 0, 1024);
memset(keybuf, 0, 1024);
memset(valuebuf, 0, 1024);
int i = 0;
do
{
if (notes && *cur != '\n')
continue;
switch (*cur)
{
case '#':
notes = 1;
break;
case ' ':
case '\t':
// jump space
break;
case '\n':
// new line
if (readValue)
{
valuebuf[i] = '\0';
if (!strcmp(section, sectionbuf) && !strcmp(key, keybuf))
{
*val = (char *)malloc(i + 1);
memset(*val, 0, i + 1);
strcpy(*val, valuebuf);
got = 1;
}
// printf("value:%s\n", valuebuf);
}
notes = 0, readSection = 0, readKey = 1, readValue = 0, i = 0;
break;
case '[':
// section begin
readSection = 1;
readKey = 0;
readValue = 0;
i = 0;
break;
case ']':
// section end
if (readSection)
{
sectionbuf[i] = '\0';
// printf("section:%s\n", sectionbuf);
readSection = 0;
}
break;
case '=':
if (readKey)
{
keybuf[i] = '\0';
// printf("key:%s\n", keybuf);
readSection = 0;
readKey = 0;
readValue = 1;
i = 0;
}
break;
default:
if (readSection)
{
sectionbuf[i++] = *cur;
}
else if (readKey)
{
keybuf[i++] = *cur;
}
else if (readValue)
{
valuebuf[i++] = *cur;
}
break;
}
} while (++cur != end && !got);
free(sectionbuf);
free(keybuf);
free(valuebuf);
munmap(pFileData, st.st_size);
return 0;
}
int GetProfileInt(const char *profile, const char *section, const char *key)
{
int ival = 0;
char *pValue = NULL;
if (GetProfileString(profile, section, key, &pValue) || !pValue)
return 0;
ival = atoi(pValue);
free(pValue);
return ival;
}
Elf32_Shdr *get_section_by_type(Elf32_Ehdr *pHeader, Elf32_Shdr *pSectionHeaderTable, Elf32_Word sh_type)
{
Elf32_Half i = 0;
do
{
if (pSectionHeaderTable[i].sh_type == sh_type)
{
return &pSectionHeaderTable[i];
}
} while (++i < pHeader->e_shnum);
return NULL;
}
Elf32_Shdr *get_section_by_index(Elf32_Ehdr *pHeader, Elf32_Shdr *pSectionHeaderTable, Elf32_Half i)
{
if (i < pHeader->e_shnum)
{
return &pSectionHeaderTable[i];
}
return NULL;
}
Elf32_Shdr *get_section_by_name(Elf32_Ehdr *pHeader, Elf32_Shdr *pSectionHeaderTable, const char *pSymStrTbl, const char *pName)
{
Elf32_Half i = 0;
do
{
if (!strcmp(pName, &pSymStrTbl[pSectionHeaderTable[i].sh_name]))
{
return &pSectionHeaderTable[i];
}
} while (++i < pHeader->e_shnum);
return NULL;
}
int get_symbol_index_by_name(Elf32_Sym *pSymbolTbl, int nSymbols, const char *pSymStrTbl, const char *pName)
{
int i = 0;
do
{
if (ELF32_ST_TYPE(pSymbolTbl[i].st_info) == STT_FUNC && !strcmp(pName, &pSymStrTbl[pSymbolTbl[i].st_name]))
{
return i;
}
} while (++i < nSymbols);
return 0;
}
void *replaceIAT(const char *pName, void *pAddr)
{
void *pOrgAddr = NULL;
int hFile = open_main_module_file();
if (hFile != -1)
{
struct stat st;
fstat(hFile, &st);
void *pFileData = mmap(0, st.st_size, PROT_READ, MAP_SHARED, hFile, 0);
if (pFileData)
{
Elf32_Ehdr *pHeader = (Elf32_Ehdr *)pFileData;
Elf32_Shdr *pSectionHeaderTable = (Elf32_Shdr *)((char *)pHeader + pHeader->e_shoff);
Elf32_Shdr *pSymSection = get_section_by_type(pHeader, pSectionHeaderTable, SHT_DYNSYM);
Elf32_Shdr *pSymStrSection = get_section_by_index(pHeader, pSectionHeaderTable, pSymSection->sh_link);
Elf32_Sym *pSymbolTbl = (Elf32_Sym *)((char *)pHeader + pSymSection->sh_offset);
const char *pSymStrTbl = (const char *)((char *)pHeader + pSymStrSection->sh_offset);
unsigned int iSymbol = get_symbol_index_by_name(pSymbolTbl, pSymSection->sh_size / sizeof(Elf32_Sym), pSymStrTbl, pName);
Elf32_Shdr *pStrSection = get_section_by_index(pHeader, pSectionHeaderTable, pHeader->e_shstrndx);
const char *pStrTbl = (const char *)((char *)pHeader + pStrSection->sh_offset);
Elf32_Shdr *pRelPltSection = get_section_by_name(pHeader, pSectionHeaderTable, pStrTbl, ".rel.plt");
Elf32_Shdr *pRelDynSection = get_section_by_name(pHeader, pSectionHeaderTable, pStrTbl, ".rel.dyn");
Elf32_Rel *pRelPlt = (Elf32_Rel *)(0x8047000 + pRelPltSection->sh_offset);
Elf32_Rel *pRelDyn = (Elf32_Rel *)(0x8047000 + pRelDynSection->sh_offset);
int nRelPlt = pRelPltSection->sh_size / sizeof(Elf32_Rel);
int nRelDyn = pRelDynSection->sh_size / sizeof(Elf32_Rel);
for (int i = 0; i < nRelPlt; i++)
{
if (ELF32_R_SYM(pRelPlt[i].r_info) == iSymbol && pRelPlt[i].r_offset)
{
pOrgAddr = *(void **)pRelPlt[i].r_offset;
*(void **)pRelPlt[i].r_offset = pAddr;
break;
}
}
if (!pOrgAddr)
{
for (int i = 0; i < nRelDyn; i++)
{
if (ELF32_R_SYM(pRelDyn[i].r_info) == iSymbol && pRelDyn[i].r_offset)
{
void **jmpAddr = (void **)pRelDyn[i].r_offset;
// printf("jmpaddr::::::::::::::::::::%X\n", pRelDyn[i].r_offset);
pOrgAddr = (void *)((char *)(*jmpAddr) + (int)jmpAddr + sizeof(void *));
CMem::WriteBytes(pOrgAddr, &pAddr, sizeof(pAddr));
break;
}
}
}
munmap(pFileData, st.st_size);
}
close(hFile);
}
return pOrgAddr;
}
int my_select(int __nfds, fd_set *__restrict __readfds,
fd_set *__restrict __writefds,
fd_set *__restrict __exceptfds,
struct timeval *__restrict __timeout)
{
if (!__nfds && !__readfds && !__writefds && !__exceptfds)
{
if (!__timeout->tv_sec && __timeout->tv_usec >= 0 && __timeout->tv_usec <= 1000)
{
__timeout->tv_usec = n_sleep_time;
}
}
return select(__nfds, __readfds, __writefds, __exceptfds, __timeout);
}
int my_usleep(__useconds_t __useconds)
{
if (__useconds >= 0 && __useconds <= 1000)
{
__useconds = n_sleep_time;
}
return usleep(__useconds);
}
/*void* my_malloc (size_t __size)
{
if (__size > 100 * 1024 * 1024)
{
char path[256];
memset(path, 0, sizeof(path));
readlink("/proc/self/exe", path, sizeof(path));
printf("**********************************[%s][malloc]: %.2f\n", path, (double)__size / 1024 / 1024);
print_backtrace(2);
}
return malloc(__size);
}*/
int _doDispatch(void *pPacketDispatcher, void *pUser, int a3, int a4, void *src, int a6, int a7, int a8) // 收包处理
{
void *pAction = *get_dispatcher(pPacketDispatcher, a4);
if (pAction)
{
// printf("Recv() cs:%d cmd:%d len:%d callback:%p\t%p\t%p\t%p\t%p\t%p\n", a3, a4, a6, *((void **)pAction), (void *)*((unsigned int *)pAction + 12), (void *)*((unsigned int *)pAction + 16), (void *)*((unsigned int *)pAction + 20), (void *)*((unsigned int *)pAction + 24), (void *)*((unsigned int *)pAction + 28));
}
else
{
// printf("Recv() cs:%d cmd:%d len:%d\n", a3, a4, a6);
}
return doDispatch(pPacketDispatcher, pUser, a3, a4, src, a6, a7, a8);
}
int _dispatch_template(void *pInst, void *pUser, void *pPacketBuf)
{
char *buf = (char *)(*((unsigned int *)pPacketBuf + 5));
// printf("Recv() cs:%d cmd:%d len:%d callback:%p|%p|%p|%p|%p\n"
// , buf[0]
// , *((unsigned short*)&buf[1])
// , *((unsigned int*)&buf[3])
// , *((void**)*((unsigned int*)pInst + 12))
// , *((void**)*((unsigned int*)pInst + 16))
// , *((void**)*((unsigned int*)pInst + 20))
// , *((void**)*((unsigned int*)pInst + 24))
// , *((void**)*((unsigned int*)pInst + 28))
//);
return dispatch_template(pInst, pUser, pPacketBuf);
}
int _addServerHackCnt(void *pCHackAnalyzer, void *pCUserCharacInfo, int HackType, int Cnt, int a5, int a6)
{
// printf("addServerHackCnt() HackType:%d \n", HackType);
// char pack_buf[0xC];
// PacketGuard(pack_buf);
return addServerHackCnt(pCHackAnalyzer, pCUserCharacInfo, HackType, Cnt, a5, a6);
}
int _put_header(void *pInterfacePacketBuf, int Type, int Cmd)
{
printf("Send() cmd:%d\n", Cmd);
return put_header(pInterfacePacketBuf, Type, Cmd);
}
int _IsRoutingItem(void *pItem)
{
// 拾取掷点
return bPickupRout && (*((unsigned int *)pItem + 14) == 4 || *((unsigned char *)pItem + 189));
}
int _setCharacInfoDetail(void *pUser, int a2, int a3, void *pCHARAC_DATA)
{
// 下线位置
unsigned char curArea = *((unsigned char *)pCHARAC_DATA + 34);
int ret = setCharacInfoDetail(pUser, a2, a3, pCHARAC_DATA);
if (curArea == 12 || curArea == 13)
{
*((char *)GetVectorUserCharacInfo((char *)pUser + 497384, a2) + 34) = 11;
}
return ret;
}
int _IsGameMasterMode(void *pUser)
{
// gm
return bGMMode || *((unsigned char *)pUser + 463320) != 0;
}
int _isGMUser(void *pUser)
{
// gm
// printf("%s\n", __FUNCTION__);
return bGMMode || (*((unsigned char *)pUser + 463320) != 0);
}
int _isGM(void *pGMAccounts, unsigned int a2)
{
// gm
// printf("%s\n", __FUNCTION__);
return bGMMode || isGM(pGMAccounts, a2);
}
int _isGM1(void *pGM_Manager)
{
// gm
// printf("%s\n", __FUNCTION__);
return bGMMode || isGM1(pGM_Manager);
}
int _GetPvPTeamCount(void *pDataManager)
{
if (bFairPVP)
return 10;
return *((unsigned int *)pDataManager + 11540);
}
// void *_set_add_info(void *pInven_Item, int a2)
// {
// if ((unsigned int)__builtin_return_address(0) == 0x0820156C)
// {
// char *_esp = NULL;
// __asm__ __volatile__("movl %%esp, %[a1];" : [a1] "=m"(_esp));
// if (_esp)
// {
// for (int i = 0; i < 200; i++)
// {
// if (897 == *((unsigned int *)&_esp[i]))
// {
// // printf("Get !!! %X\n", i);
// a2 = GetProfileInt(szGamePath, "", "val");
// }
// }
// }
// // printf("====================_set_add_info======================%d\n", a2);
// }
// return set_add_info(pInven_Item, a2);
// }
int _isSocketAvatar(void *pAvatarItemMgr1, void *pAvatarItemMgr2)
{
return 1;
}
int _reach_game_world(void *pThis, void *a2)
{
std::lock_guard<std::recursive_mutex> lock(SqMtx);
SQInteger top = sq_gettop(v); // saves the stack size before the call
sq_pushroottable(v); // pushes the global table
sq_pushstring(v, _SC("Cb_reach_game_world"), -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_pushuserpointer(v, a2);
sq_call(v, 2, SQFalse, SQTrue); // calls the function
}
sq_settop(v, top); // restores the original stack size
return reach_game_world(pThis, a2);
}
int _Inter_LoadEtc_dispatch_sig(void *pThis, void *pUser, char *a3)
{
int result = Inter_LoadEtc_dispatch_sig(pThis, pUser, a3);
LOG("_Inter_LoadEtc_dispatch_sig begin");
// typedef double(__cdecl* FN_sqrt)(_In_ double _X);
CUserCharacInfo_getCurCharacNo getCurCharacNo = (CUserCharacInfo_getCurCharacNo)(0x080CBC4E);
int CurCharacNo = getCurCharacNo(pUser);
LOG("CurCharacNo :%d", CurCharacNo);
CUserCharacInfo_getCurCharacName getCurCharacName = (CUserCharacInfo_getCurCharacName)0x8101028;
char *name = getCurCharacName(pUser);
LOG("CurCharacName :%s", name);
LOG("_Inter_LoadEtc_dispatch_sig end");
return result;
}
void _Leninsert_user(void *Area, void *CUser)
{
// *(int *)(Area + 0x68) = 1; // 让这个区域的所有玩家互相看不见123
// *(int *)(Area + 26) = 1;
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("Cb_insert_user"), -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_pushuserpointer(v, Area);
sq_pushuserpointer(v, CUser);
sq_call(v, 3, SQFalse, SQTrue); // calls the function
}
sq_settop(v, top); // restores the original stack size
Leninsert_user(Area, CUser);
}
void _LenGameWorld_move_position(void *GameWorld, void *CUser, int a3, int a4, int a5, short a6)
{
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("Cb_GameWorld_move_position"), -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_pushuserpointer(v, CUser);
sq_pushinteger(v, a3);
sq_pushinteger(v, a4);
sq_pushinteger(v, a5);
sq_pushinteger(v, a6);
sq_call(v, 6, SQFalse, SQTrue); // calls the function
}
sq_settop(v, top); // restores the original stack size
LenGameWorld_move_position(GameWorld, CUser, a3, a4, a5, a6);
}
int _LenGetTimerMess(void *TimerQueue, void *TimerEntry)
{
if (l_socket::getInstance().InitState)
l_socket::getInstance().Logic();
return LenGetTimerMess(TimerQueue, TimerEntry);
}
// void ReqScript()
// {
// asio::io_context io_context;
// asio::ip::tcp::resolver resolver(io_context);
// asio::ip::tcp::socket socket(io_context);
// // 解析主机名和端口号
// auto endpoints = resolver.resolve("110.42.251.214", "9007");
// // 连接到服务器
// asio::connect(socket, endpoints);
// // 发送 HTTP GET 请求
// asio::write(socket, asio::buffer("GET /user/getuser4 HTTP/1.1\r\nHost: 110.42.251.214\r\nConnection: close\r\n\r\n"));
// // 读取服务器的响应
// asio::streambuf response;
// asio::read_until(socket, response, "\r\n");
// // 输出响应
// std::istream response_stream(&response);
// std::string http_version;
// response_stream >> http_version;
// std::cout << "Response:\n";
// std::cout << &response;
// }
void PrintAuroraTag()
{
printf("\n");
LOG("**********************************************************");
LOG(" DNF_Server Plugin S%s ", MY_VERSION);
LOG(" By:Tanwan ");
LOG("**********************************************************");
LOG("插件已加载*********************************************贪玩");
LOG("插件已加载*********************************************贪玩");
LOG("插件已加载*********************************************贪玩");
LOG("插件已加载*********************************************贪玩");
LOG("插件已加载*********************************************贪玩");
LOG("插件已加载*********************************************贪玩");
}
int _Inter_LoadGeolocation_dispatch_sig(void *pThis, void *pUser, char *a3)
{
int Ret = Inter_LoadGeolocation_dispatch_sig(pThis, pUser, a3);
PrintAuroraTag();
// 请求脚本
// ReqScript();
// 初始化松鼠
InitSquirrel();
return Ret;
}
int _ReqDBSendNewSystemMultiMail(char *src, int a2, unsigned int a3, int a4, int a5, char *a6, int a7, int a8, int a9, char a10)
{
int Ret = ReqDBSendNewSystemMultiMail(src, a2, a3, a4, a5, a6, a7, a8, a9, a10);
std::cout << 111 << std::endl;
return Ret;
}
int _AddItem(void *CUser, int a2, int a3, int a4, int *a5, int a6)
{
int Ret = AddItem(CUser, a2, a3, a4, a5, a6);
std::cout << 111 << std::endl;
return Ret;
}
int _InterSelectMobileAuthReward(void *InterSelect, void *CUser, char *a3)
{
int Ret = InterSelectMobileAuthReward(InterSelect, CUser, a3);
std::cout << 111 << std::endl;
return Ret;
}
bool _CreateSkill(int a1, int a2)
{
char *Str = (char *)(a2 + 121);
char *Str1 = (char *)(a2 + 529);
// Str[6] = 8;
// Str[7] = 1;
// Str1[6] = 8;
// Str1[7] = 1;
// Str[8] = 36;
// Str[9] = 1;
// Str1[8] = 36;
// Str1[9] = 1;
std::cout << "Str: " << Str << std::endl;
std::cout << "Str1: " << Str1 << std::endl;
bool Ret = CreateSkill(a1, a2);
return Ret;
}
// 贪玩需求
bool _CreateEquip(void *a1, unsigned int a2, void *a3)
{
char *Str = (char *)(a3);
for (int i = 0; i < (30 * 11); i++)
{
Str[i] = 0x0;
}
bool Ret = CreateEquip(a1, a2, a3);
return Ret;
}
int _History_Log(int a1, char *format, ...)
{
char Buffer[256];
va_list args;
va_start(args, format);
vsprintf(Buffer, format, args);
va_end(args);
std::vector<std::string> Data;
Tool::Split(Buffer, Data, ",");
// std::cout << Buffer << std::endl;
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("Cb_History_Log"), -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_newarray(v, 0);
for (std::string Str : Data)
{
sq_pushstring(v, Str.c_str(), -1);
sq_arrayappend(v, -2);
}
sq_call(v, 2, SQFalse, SQTrue); // calls the function
}
sq_settop(v, top); // restores the original stack size
// 调用原始函数
va_start(args, format);
int result = History_Log(a1, format, args);
va_end(args);
return result;
}
void Lenheart()
{
if (!checkGame("df_game_r"))
{
int a = 1;
void *buf = malloc(4);
CMem::WriteBytes(buf, &a, 4);
unsigned int nMaxGrade = 85;
bGMMode = 1;
// max_level = nMaxGrade;
// ServerParameterScript::setDungeonOpen
// CodeHook::WriteUChar(MAIN_OFFSET(0x22069B), 0x01);
// ServerParameterScript::isDungeonOpen
CMem::WriteUChar(MAIN_OFFSET(0x220894), 0x01);
// Init DataManager
CMem::WriteUChar(MAIN_OFFSET(0x258E80), 0xEB);
// Init Level Exp
CMem::WriteUChar(MAIN_OFFSET(0x314ECB), 0xEB);
// Init Mob Reward
CMem::WriteUChar(MAIN_OFFSET(0x314FCB), 0xEB);
// CDataManager::GetSpAtLevelUp
CMem::WriteUChar(MAIN_OFFSET(0x318CC8), 0xE6);
// fixbug
CMem::WriteUChar(MAIN_OFFSET(0x31C128), 0x7E);
CMem::WriteUChar(MAIN_OFFSET(0x31C129), 0x06);
CMem::WriteUChar(MAIN_OFFSET(0x547005), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x61AF55), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x61B0F3), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x61DD28), nMaxGrade - 1);
CMem::WriteUChar(MAIN_OFFSET(0x61E86A), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x61EE9C), nMaxGrade - 1);
CMem::WriteUChar(MAIN_OFFSET(0x6224A8), nMaxGrade - 1);
CMem::WriteUChar(MAIN_OFFSET(0x622929), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x641D4B), nMaxGrade - 1);
CMem::WriteUChar(MAIN_OFFSET(0x647ECE), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x647EDA), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x647F82), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x647F88), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x66521D), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x665223), nMaxGrade);
// SUBHOOK_SETUP(addServerHackCnt);
// SUBHOOK_SETUP(put_header);
// SUBHOOK_SETUP(IsCurCharacVisible);
// SUBHOOK_SETUP(IsRoutingItem);
// SUBHOOK_SETUP(setCharacInfoDetail);
// SUBHOOK_SETUP(IsGameMasterMode);
// SUBHOOK_SETUP(isGMUser);
// SUBHOOK_SETUP(isGM);
// SUBHOOK_SETUP(isGM1);
// SUBHOOK_SETUP(GetPvPTeamCount);
// SUBHOOK_SETUP(set_add_info);
SUBHOOK_SETUP(reach_game_world);
SUBHOOK_SETUP(Leninsert_user);
SUBHOOK_SETUP(LenGetTimerMess);
SUBHOOK_SETUP(LenGameWorld_move_position);
// SUBHOOK_SETUP(Lengetareauseridlist);
// SUBHOOK_SETUP(Inter_LoadEtc_dispatch_sig);
// SUBHOOK_SETUP(send_area_users);
SUBHOOK_SETUP(Inter_LoadGeolocation_dispatch_sig);
SUBHOOK_SETUP(History_Log);
// 发送邮件HOOK
// SUBHOOK_SETUP(ReqDBSendNewSystemMultiMail);
// 发送道具
// SUBHOOK_SETUP(AddItem);
// 账号首角色送成长契约
// SUBHOOK_SETUP(InterSelectMobileAuthReward);
// 创建角色创建技能
// SUBHOOK_SETUP(CreateSkill);
// 创建角色创建装备
SUBHOOK_SETUP(CreateEquip);
// SUBHOOK_SETUP(doDispatch); // 收包注册
// CMem::HookJmp(0x86c2994, (int)insert_user_send_to_all);
Controller::Get()
->init();
// SUBHOOK_SETUP(isSocketAvatar);
if (nMaxGrade > 70)
{
// 以下需要扩充类大小, 修改偏移
CMem::WriteUInt(MAIN_OFFSET(0x87162 + 3), 0xB678 + nMaxGrade * 4 + nMaxGrade * 12);
// CDataManager::set_reward_sp
CMem::WriteUInt(MAIN_OFFSET(0x318C26 + 2), 10836 + 840);
CMem::WriteUChar(MAIN_OFFSET(0x318C3B), nMaxGrade);
CMem::WriteUInt(MAIN_OFFSET(0x318C68 + 2), 10836 + 840);
CMem::WriteUChar(MAIN_OFFSET(0x318C79), nMaxGrade);
// CDataManager::GetSpAtLevelUp
CMem::WriteUChar(MAIN_OFFSET(0x318CC4), nMaxGrade);
CMem::WriteUInt(MAIN_OFFSET(0x318CD4 + 2), 10836 + 840);
}
CMem::WriteUChar(MAIN_OFFSET(0x61B8F6), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x622659), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade);
CMem::WriteUChar(MAIN_OFFSET(0x622941), nMaxGrade);
}
}
void __attribute__((constructor)) lenheart_init(void)
{
Lenheart();
}