Files
dps_lib/include/SqrReg_GameManager.hpp
2026-04-22 19:36:06 +08:00

163 lines
4.7 KiB
C++

#pragma once
#include "squirrel.h"
#include "sqstdaux.h"
#include "sqstdblob.h"
#include "sqstdio.h"
#include "sqstdmath.h"
#include "sqstdstring.h"
#include "sqstdsystem.h"
#include <iostream>
#include "frida-gum.h"
typedef void *(*__GetGameManagerVoid)();
static SQInteger GameManager_GameManager(HSQUIRRELVM v)
{
void *GameManager = ((__GetGameManagerVoid)0x080CC18E)();
sq_pushuserpointer(v, GameManager);
return 1;
}
typedef void *(*__GameManagerByThis)(void *GameManager);
static SQInteger GameManager_GetParty(HSQUIRRELVM v)
{
SQUserPointer P;
sq_getuserpointer(v, 2, &P);
void *CParty = ((__GameManagerByThis)0x08294E10)(P);
if (CParty)
sq_pushuserpointer(v, CParty);
else
sq_pushinteger(v, 0);
return 1;
}
typedef int (*cdeclCall2P)(int *a1, int a2);
static cdeclCall2P SkillSlot__get_skillslot_buf = (cdeclCall2P)0x086067DE;
static cdeclCall2P SkillSlot__gcheckComboSkillInsertQuickSlot = (cdeclCall2P)0x08608D58;
#define RDWORD(addr, offset) (*(DWORD *)((char *)(addr) + (offset)))
int __attribute__((cdecl)) hookCSkill__reform_ui_group_no(int *thisP, int *skillClassP, bool isTpSkill, int a4)
{
int p = (int)skillClassP;
if (RDWORD(skillClassP, -0x60) == 197)
{
// cout << " fix skill197 class to 4!" << endl;
*skillClassP = 4;
}
return 0;
}
int __attribute__((cdecl)) hookSkillSlot__get_skillslot_group(int *thisP, int slot)
{
// DWORD retAddr = (DWORD)gum_invocation_context_get_return_address(NULL);
// cout<< retAddr << " get_skillslot_group:" << slot << endl;
if (slot < 8 || slot >= 198)
return -1;
else if (slot >= 160)
return 4;
else if (slot >= 122)
return 3;
else if (slot >= 84)
return 2;
else if (slot >= 46)
return 1;
else
return 0;
}
int __attribute__((cdecl)) hookSkillSlot__get_skillslot_no(int *thisP, int skillId, int group, int slot, char is_active_skill)
{
if (!thisP || !*thisP)
return -1;
BYTE *buf = (BYTE *)SkillSlot__get_skillslot_buf(thisP, slot);
if (!buf)
return -1;
if (is_active_skill && SkillSlot__gcheckComboSkillInsertQuickSlot(thisP, skillId))
{
int end = skillId ? 7 : 5;
for (int i = 0; i <= end; ++i)
{
if (buf[2 * i] == skillId)
{
return i;
}
}
for (int i = 198; i <= 203; ++i)
{
if (buf[2 * i] == skillId)
{
return i;
}
}
}
int pos = 8 + group * 38;
for (int i = 0; i < 38; ++i)
{
if (buf[2 * (i + pos)] == skillId)
{
return i + pos;
}
}
return -1;
}
int __attribute__((cdecl)) hookSkillSlot__get_skillslot_no2(int *thisP, BYTE *buf, int skillId, int group, char is_active_skill)
{
if (!thisP || !*thisP || !buf)
return -1;
if (is_active_skill)
{
int end = skillId ? 7 : 5;
for (int i = 0; i <= end; ++i)
{
if (buf[2 * i] == skillId)
{
return i;
}
}
for (int i = 198; i <= 203; ++i)
{
if (buf[2 * i] == skillId)
{
return i;
}
}
}
int pos = 8 + group * 38;
for (int i = 0; i < 38; ++i)
{
if (buf[2 * (i + pos)] == skillId)
{
return i + pos;
}
}
return -1;
}
static SQInteger GameManager_FixA4Skill(HSQUIRRELVM vm)
{
GumInterceptor *v = gum_interceptor_obtain();
gum_interceptor_begin_transaction(v);
gum_interceptor_replace_fast(v, (gpointer)0x083507E8, (gpointer)hookCSkill__reform_ui_group_no, NULL);
gum_interceptor_replace_fast(v, (gpointer)0x086049FC, (gpointer)hookSkillSlot__get_skillslot_group, NULL);
gum_interceptor_replace_fast(v, (gpointer)0x08604A86, (gpointer)hookSkillSlot__get_skillslot_no, NULL);
gum_interceptor_replace_fast(v, (gpointer)0x08607DBA, (gpointer)hookSkillSlot__get_skillslot_no2, NULL);
gum_interceptor_end_transaction(v);
return 0;
}
static SQInteger register_GameManager_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 RegisterGameManager(HSQUIRRELVM v)
{
// 获得GameManager对象
register_GameManager_func(v, GameManager_GameManager, _SC("Sq_GameManager_GameManager"));
// 获得队伍对象
register_GameManager_func(v, GameManager_GetParty, _SC("Sq_GameManager_GetParty"));
// 修复A4技能
register_GameManager_func(v, GameManager_FixA4Skill, _SC("Sq_FixA4Skill"));
}