Skip to content

Commit

Permalink
Merge pull request #59 from hzqst/master
Browse files Browse the repository at this point in the history
fix cl_time, cl_oldtime, cl_waterlevel, cl_parsecount, and cl_serverc…
  • Loading branch information
LAGonauta authored Nov 28, 2023
2 parents afadf07 + e30fbd1 commit 014ee07
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 16 deletions.
36 changes: 29 additions & 7 deletions src/metaaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ ICommandLine *CommandLine()
return g_pInterface->CommandLine;
}

void IPlugins::Init(metahook_api_t *pAPI, mh_interface_t *pInterface, mh_enginesave_t *pSave)
void IPluginsV4::Init(metahook_api_t *pAPI, mh_interface_t *pInterface, mh_enginesave_t *pSave)
{
g_pInterface = pInterface;
g_pMetaHookAPI = pAPI;
Expand All @@ -66,7 +66,7 @@ void IPlugins::Init(metahook_api_t *pAPI, mh_interface_t *pInterface, mh_engines
audio_engine = std::make_unique<MetaAudio::AudioEngine>(audio_cache, sound_loader);
}

void IPlugins::Shutdown()
void IPluginsV4::Shutdown()
{
sound_loader.reset();
audio_engine.reset();
Expand All @@ -77,7 +77,7 @@ void IPlugins::Shutdown()
}
}

void IPlugins::LoadEngine()
void IPluginsV4::LoadEngine(cl_enginefunc_t* pEngfuncs)
{
g_pFileSystem = g_pInterface->FileSystem;
if (!g_pFileSystem)//backward compatibility
Expand All @@ -92,25 +92,47 @@ void IPlugins::LoadEngine()
g_dwEngineDataBase = g_pMetaHookAPI->GetSectionByName(g_dwEngineBase, ".data\x0\x0\x0", &g_dwEngineDataSize);
g_dwEngineRdataBase = g_pMetaHookAPI->GetSectionByName(g_dwEngineBase, ".rdata\x0\x0", &g_dwEngineRdataSize);

memcpy(&gEngfuncs, pEngfuncs, sizeof(gEngfuncs));

S_FillAddress();
S_InstallHook(audio_engine.get(), sound_loader.get());
}

void IPlugins::LoadClient(cl_exportfuncs_t *pExportFunc)
void IPluginsV4::LoadClient(cl_exportfuncs_t *pExportFunc)
{
memcpy(&gExportfuncs, pExportFunc, sizeof(gExportfuncs));
memcpy(&gEngfuncs, g_pMetaSave->pEngineFuncs, sizeof(gEngfuncs));

gEngfuncs.pfnAddCommand("al_version", AL_Version);
gEngfuncs.pfnAddCommand("al_reset_efx", AL_ResetEFX);
gEngfuncs.pfnAddCommand("al_show_basic_devices", AL_BasicDevices);
gEngfuncs.pfnAddCommand("al_show_full_devices", AL_FullDevices);
}

void IPlugins::ExitGame(int iResult)
void IPluginsV4::ExitGame(int iResult)
{
S_UninstallHook();
Shutdown();
}

EXPOSE_SINGLE_INTERFACE(IPlugins, IPlugins, METAHOOK_PLUGIN_API_VERSION);
const char completeVersion[] =
{
BUILD_YEAR_CH0, BUILD_YEAR_CH1, BUILD_YEAR_CH2, BUILD_YEAR_CH3,
'-',
BUILD_MONTH_CH0, BUILD_MONTH_CH1,
'-',
BUILD_DAY_CH0, BUILD_DAY_CH1,
'T',
BUILD_HOUR_CH0, BUILD_HOUR_CH1,
':',
BUILD_MIN_CH0, BUILD_MIN_CH1,
':',
BUILD_SEC_CH0, BUILD_SEC_CH1,
'\0'
};

const char* IPluginsV4::GetVersion(void)
{
return completeVersion;
}

EXPOSE_SINGLE_INTERFACE(IPluginsV4, IPluginsV4, METAHOOK_PLUGIN_API_VERSION_V4);
142 changes: 133 additions & 9 deletions src/snd_hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,10 @@ void S_FillAddress()
{
typedef struct
{
int unused;
int cmp_instCount;
void* branch_succ;
int mov2BC_instCount;
int mov2BC_reg;
}SND_Spatializing_Ctx;

SND_Spatializing_Ctx ctx = { 0 };
Expand Down Expand Up @@ -439,9 +442,23 @@ void S_FillAddress()
(PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize)
{//3B 05 8C 61 3E 11 cmp eax, cl_viewentity
gAudEngine.cl_viewentity = (decltype(gAudEngine.cl_viewentity))pinst->detail->x86.operands[1].mem.disp;
ctx->cmp_instCount = instCount;
}

if (!ctx->branch_succ && instCount == ctx->cmp_instCount + 1)
{
if ((pinst->id == X86_INS_JMP || (pinst->id >= X86_INS_JAE && pinst->id <= X86_INS_JS)) &&
pinst->detail->x86.op_count == 1 &&
pinst->detail->x86.operands[0].type == X86_OP_IMM)
{
void* imm = (void*)pinst->detail->x86.operands[0].imm;

ctx->branch_succ = imm;
}
}

if (gAudEngine.cl_viewentity)

if (gAudEngine.cl_viewentity && ctx->branch_succ)
return TRUE;

if (address[0] == 0xCC)
Expand All @@ -454,6 +471,73 @@ void S_FillAddress()
}, 0, &ctx);

Sig_FuncNotFound(cl_viewentity);

if (!ctx.branch_succ)
{
Sig_NotFound("SND_Spatialize_branch_succ");
}

g_pMetaHookAPI->DisasmRanges(ctx.branch_succ, 0x100, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context)
{
auto pinst = (cs_insn*)inst;
auto ctx = (SND_Spatializing_Ctx*)context;

if (!gAudEngine.cl_num_entities &&
pinst->id == X86_INS_CMP &&
pinst->detail->x86.op_count == 2 &&
pinst->detail->x86.operands[0].type == X86_OP_REG &&
pinst->detail->x86.operands[1].type == X86_OP_MEM &&
(PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase &&
(PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize)
{// cmp eax, cl_num_entities

if ((ULONG_PTR)pinst->detail->x86.operands[1].mem.disp > (ULONG_PTR)gAudEngine.cl_viewentity &&
(ULONG_PTR)pinst->detail->x86.operands[1].mem.disp < (ULONG_PTR)gAudEngine.cl_viewentity + 4 * sizeof(ULONG_PTR))
{
gAudEngine.cl_num_entities = (decltype(gAudEngine.cl_num_entities))pinst->detail->x86.operands[1].mem.disp;
}
}

if (!ctx->mov2BC_instCount &&
pinst->id == X86_INS_MOV &&
pinst->detail->x86.op_count == 2 &&
pinst->detail->x86.operands[0].type == X86_OP_REG &&
pinst->detail->x86.operands[1].type == X86_OP_MEM &&
(PUCHAR)pinst->detail->x86.operands[1].mem.base != 0 &&
pinst->detail->x86.operands[1].mem.disp == 0x2BC)
{
// mov eax, [ecx + 2BCh]

ctx->mov2BC_instCount = instCount;
ctx->mov2BC_reg = pinst->detail->x86.operands[0].reg;
}

if (!gAudEngine.cl_parsecount &&ctx->mov2BC_instCount &&
instCount > ctx->mov2BC_instCount && instCount < ctx->mov2BC_instCount + 5 &&
pinst->id == X86_INS_CMP &&
pinst->detail->x86.op_count == 2 &&
pinst->detail->x86.operands[0].type == X86_OP_REG &&
pinst->detail->x86.operands[0].reg == ctx->mov2BC_reg &&
pinst->detail->x86.operands[1].type == X86_OP_MEM &&
(PUCHAR)pinst->detail->x86.operands[1].mem.disp >(PUCHAR)g_dwEngineDataBase &&
(PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize)
{
//cmp eax, cl_parsecount

gAudEngine.cl_parsecount = (decltype(gAudEngine.cl_parsecount))pinst->detail->x86.operands[1].mem.disp;
}

if (gAudEngine.cl_num_entities && gAudEngine.cl_parsecount)
return TRUE;

if (address[0] == 0xCC)
return TRUE;

if (pinst->id == X86_INS_RET)
return TRUE;

return FALSE;
}, 0, & ctx);
}

if (1)
Expand Down Expand Up @@ -588,6 +672,33 @@ void S_FillAddress()
Sig_FuncNotFound(g_SND_VoiceOverdrive);
}

if (1)
{
g_pMetaHookAPI->DisasmRanges(gAudEngine.S_FindName, 0x120, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context)
{
auto pinst = (cs_insn*)inst;

if (pinst->id == X86_INS_CMP && pinst->detail->x86.op_count == 2 &&
pinst->detail->x86.operands[0].type == X86_OP_REG &&
pinst->detail->x86.operands[1].type == X86_OP_MEM &&
(PUCHAR)pinst->detail->x86.operands[1].mem.disp > (PUCHAR)g_dwEngineDataBase &&
(PUCHAR)pinst->detail->x86.operands[1].mem.disp < (PUCHAR)g_dwEngineDataBase + g_dwEngineDataSize)
{ //8B 0D CC 37 F0 02 mov ecx, cl_viewentity

gAudEngine.cl_servercount = (decltype(gAudEngine.cl_servercount))pinst->detail->x86.operands[1].mem.disp;
}

if (address[0] == 0xCC)
return TRUE;

if (pinst->id == X86_INS_RET)
return TRUE;

return FALSE;
}, 0, NULL);

Sig_FuncNotFound(cl_servercount);
}

if (1)
{
Expand Down Expand Up @@ -723,22 +834,35 @@ void S_FillAddress()

ULONG_PTR addr;

//Deprecated way
if (!gAudEngine.cl_viewentity)
{
addr = (ULONG_PTR)Search_Pattern_From_Size((void*)gAudEngine.SND_Spatialize, 0x10, "\x8B\x0D");
addr = (ULONG_PTR)Search_Pattern_From_Size((void*)gAudEngine.SND_Spatialize, 0x100, "\x8B\x0D");

Sig_AddrNotFound(cl_viewentity);

gAudEngine.cl_viewentity = *(int**)((ULONG_PTR)addr + 2);

//idk why but cl_num_entities always be at &cl_viewentity + sizeof(uintptr_t) * 3 no matter in Sven or in HL
gAudEngine.cl_num_entities = gAudEngine.cl_viewentity + 3;
}

gAudEngine.cl_num_entities = gAudEngine.cl_viewentity + 3;
gAudEngine.cl_parsecount = gAudEngine.cl_viewentity - (0x1789C8 / 4);
gAudEngine.cl_servercount = gAudEngine.cl_parsecount - 2;
gAudEngine.cl_waterlevel = gAudEngine.cl_servercount + 0x450 / 4;
//gAudEngine.cl_parsecount = gAudEngine.cl_viewentity - (0x1789C8 / 4);
//gAudEngine.cl_servercount = gAudEngine.cl_parsecount - 2;
//gAudEngine.cl_waterlevel = gAudEngine.cl_servercount + 0x450 / 4;

addr = (ULONG_PTR)Search_Pattern_From_Size((void*)gEngfuncs.GetClientTime, 0x20, "\xDD\x05");
Sig_AddrNotFound("cl_time");
gAudEngine.cl_time = (decltype(gAudEngine.cl_time))*(ULONG_PTR*)(addr + 2);
gAudEngine.cl_oldtime = (decltype(gAudEngine.cl_oldtime))(gAudEngine.cl_time + 1);

#define CL_WATERLEVEL_SIG "\x83\x3D\x2A\x2A\x2A\x2A\x02\xA1\x2A\x2A\x2A\x2A\x2A\x2A\x85\xC0"
addr = (ULONG_PTR)Search_Pattern(CL_WATERLEVEL_SIG);
Sig_AddrNotFound("cl_waterlevel");
gAudEngine.cl_waterlevel = (decltype(gAudEngine.cl_waterlevel))*(ULONG_PTR*)(addr + 2);

gAudEngine.cl_time = (double *)(gAudEngine.cl_waterlevel + 11);
gAudEngine.cl_oldtime = gAudEngine.cl_time + 1;
// gAudEngine.cl_time = (double *)(gAudEngine.cl_waterlevel + 11);
// gAudEngine.cl_oldtime = gAudEngine.cl_time + 1;

if (!gAudEngine.cszrawsentences)
{
Expand Down

0 comments on commit 014ee07

Please sign in to comment.