1.0
This commit is contained in:
163
include/SqrReg_GameManager.hpp
Normal file
163
include/SqrReg_GameManager.hpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#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"));
|
||||
}
|
||||
Reference in New Issue
Block a user