From faea1f108929fb01da91456ef36aecdca3e55d99 Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Fri, 28 Jan 2022 00:23:44 +0000 Subject: initial work on ain file dumping --- .../NorthstarDedicatedTest.vcxproj | 4 +- .../NorthstarDedicatedTest.vcxproj.filters | 6 + NorthstarDedicatedTest/buildainfile.cpp | 152 +++++++++++++++++++++ NorthstarDedicatedTest/buildainfile.h | 3 + NorthstarDedicatedTest/dllmain.cpp | 2 + 5 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 NorthstarDedicatedTest/buildainfile.cpp create mode 100644 NorthstarDedicatedTest/buildainfile.h diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj index 8aa300c8..a26d13ec 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj @@ -109,6 +109,7 @@ + @@ -550,6 +551,7 @@ + @@ -625,7 +627,7 @@ - + diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters index 777f2396..2011ca2f 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters @@ -1440,6 +1440,9 @@ Header Files\Client + + Header Files\Server + @@ -1568,6 +1571,9 @@ Source Files\Client + + Source Files\Server + diff --git a/NorthstarDedicatedTest/buildainfile.cpp b/NorthstarDedicatedTest/buildainfile.cpp new file mode 100644 index 00000000..25c3254f --- /dev/null +++ b/NorthstarDedicatedTest/buildainfile.cpp @@ -0,0 +1,152 @@ +#include "pch.h" +#include "buildainfile.h" +#include "hookutils.h" + +const int MAX_HULLS = 5; + +struct CAI_Node +{ + int index; // not present on disk + float x; + float y; + float z; + float yaw; + float hulls[MAX_HULLS]; + + int unk0; // always 2 in buildainfile, maps directly to unk0 in disk struct + int unk1; // maps directly to unk1 in disk struct + int unk2[MAX_HULLS]; // maps directly to unk2 in disk struct, despite being ints rather than shorts + + // view server.dll+393672 for context and death wish + char unk3[MAX_HULLS]; // hell on earth, should map to unk3 on disk + char pad[3]; // aligns next bytes + float unk4[MAX_HULLS]; // i have no fucking clue, calculated using some kind of demon hell function float magic + + char unk5[32]; // padding until next bits i know + short unk6; // should match up to unk4 on disk + char unk7[16]; // padding until next bit + short unk8; // should match up to unk5 on disk + char unk9[8]; // padding until next bit + char unk10[8]; // should match up to unk6 on disk +}; + +// the way CAI_Nodes are represented in on-disk ain files +struct CAI_NodeDisk +{ + float x; + float y; + float z; + float yaw; + float hulls[MAX_HULLS]; + + char unk0; + int unk1; + short unk2[MAX_HULLS]; + char unk3[MAX_HULLS]; + short unk4; + short unk5; + char unk6[8]; +}; // total size of 68 bytes + +struct CAI_Network +{ + char unk0[84172]; + int nodecount; + CAI_Node** nodes; +}; + +typedef void(*CAI_NetworkBuilder__BuildType)(void* builder, CAI_Network* aiNetwork, void* unknown); +CAI_NetworkBuilder__BuildType CAI_NetworkBuilder__Build; + +void CAI_NetworkBuilder__BuildHook(void* builder, CAI_Network* aiNetwork, void* unknown) +{ + CAI_NetworkBuilder__Build(builder, aiNetwork, unknown); + + // dump from memory + spdlog::info("DUMPING BUILDAINFILE INFO!!!"); + spdlog::info(""); + spdlog::info(""); + spdlog::info(""); + spdlog::info(""); + spdlog::info(""); + + // path nodes + spdlog::info("nodecount: {}", aiNetwork->nodecount); + for (int i = 0; i < aiNetwork->nodecount; i++) + { + //spdlog::info("x = {}", aiNetwork->nodes[i]->x); + //spdlog::info("y = {}", aiNetwork->nodes[i]->y); + //spdlog::info("z = {}", aiNetwork->nodes[i]->z); + //spdlog::info("yaw = {}", aiNetwork->nodes[i]->yaw); + //spdlog::info("hulls = {} {} {} {} {}", aiNetwork->nodes[i]->hulls[0], aiNetwork->nodes[i]->hulls[1], aiNetwork->nodes[i]->hulls[2], aiNetwork->nodes[i]->hulls[3], aiNetwork->nodes[i]->hulls[4]); + // + //spdlog::info("unk0 = {} (should always be 2)", aiNetwork->nodes[i]->unk0); + //spdlog::info("unk1 = {}", aiNetwork->nodes[i]->unk1); + //spdlog::info("unk2 = {} {} {} {} {}", aiNetwork->nodes[i]->unk2[0], aiNetwork->nodes[i]->unk2[1], aiNetwork->nodes[i]->unk2[2], aiNetwork->nodes[i]->unk2[3], aiNetwork->nodes[i]->unk2[4]); + // + //spdlog::info("unk3 = {} {} {} {} {}", (int)aiNetwork->nodes[i]->unk3[0], (int)aiNetwork->nodes[i]->unk3[1], (int)aiNetwork->nodes[i]->unk3[2], (int)aiNetwork->nodes[i]->unk3[3], (int)aiNetwork->nodes[i]->unk3[4]); + //spdlog::info("unk4 = {} {} {} {} {}", aiNetwork->nodes[i]->unk4[0], aiNetwork->nodes[i]->unk4[1], aiNetwork->nodes[i]->unk4[2], aiNetwork->nodes[i]->unk4[3], aiNetwork->nodes[i]->unk4[4]); + + // construct on-disk node struct + CAI_NodeDisk diskNode; + diskNode.x = aiNetwork->nodes[i]->x; + diskNode.y = aiNetwork->nodes[i]->y; + diskNode.z = aiNetwork->nodes[i]->z; + diskNode.yaw = aiNetwork->nodes[i]->yaw; + memcpy(diskNode.hulls, aiNetwork->nodes[i]->hulls, sizeof(diskNode.hulls)); + diskNode.unk0 = (char)aiNetwork->nodes[i]->unk0; + diskNode.unk1 = aiNetwork->nodes[i]->unk1; + + for (int j = 0; j < MAX_HULLS; j++) + diskNode.unk3[j] = (short)aiNetwork->nodes[i]->unk3[j]; + + diskNode.unk4 = aiNetwork->nodes[i]->unk6; + diskNode.unk5 = aiNetwork->nodes[i]->unk8; + memcpy(diskNode.unk6, aiNetwork->nodes[i]->unk10, sizeof(diskNode.unk6)); + + spdlog::info("node {} at {} has on-disk fields:", aiNetwork->nodes[i]->index, (void*)aiNetwork->nodes[i]); + spdlog::info("x = {}", diskNode.x); + spdlog::info("y = {}", diskNode.y); + spdlog::info("z = {}", diskNode.z); + spdlog::info("yaw = {}", diskNode.yaw); + spdlog::info("hulls = {} {} {} {} {}", diskNode.hulls[0], diskNode.hulls[1], diskNode.hulls[2], diskNode.hulls[3], diskNode.hulls[4]); + spdlog::info("unk0 = {}", (int)diskNode.unk0); + spdlog::info("unk1 = {}", diskNode.unk1); + spdlog::info("unk2 = {} {} {} {} {}", diskNode.unk2[0], diskNode.unk2[1], diskNode.unk2[2], diskNode.unk2[3], diskNode.unk2[4]); + spdlog::info("unk3 = {} {} {} {} {}", (int)diskNode.unk3[0], (int)diskNode.unk3[1], (int)diskNode.unk3[2], (int)diskNode.unk3[3], (int)diskNode.unk3[4]); + spdlog::info("unk4 = {}", diskNode.unk4); + spdlog::info("unk5 = {}", diskNode.unk5); + spdlog::info("unk6 = {} {} {} {} {} {} {} {}", (int)diskNode.unk6[0], (int)diskNode.unk6[1], (int)diskNode.unk6[2], (int)diskNode.unk6[3], (int)diskNode.unk6[4], (int)diskNode.unk6[5], (int)diskNode.unk6[6], (int)diskNode.unk6[7]); + + } +} + +void InitialiseBuildAINFileHooks(HMODULE baseAddress) +{ + HookEnabler hook; + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x385E20, &CAI_NetworkBuilder__BuildHook, reinterpret_cast(&CAI_NetworkBuilder__Build)); + + // remove a check that prevents a logging function in link generation from working + // due to the sheer amount of logging this is a massive perf hit to generation, but spewlog_enable 0 exists so whatever + { + void* ptr = (char*)baseAddress + 0x3889B6; + TempReadWrite rw(ptr); + *((char*)ptr) = (char)0x90; + *((char*)ptr + 1) = (char)0x90; + *((char*)ptr + 2) = (char)0x90; + *((char*)ptr + 3) = (char)0x90; + *((char*)ptr + 4) = (char)0x90; + *((char*)ptr + 5) = (char)0x90; + } + + { + void* ptr = (char*)baseAddress + 0x3889BF; + TempReadWrite rw(ptr); + *((char*)ptr) = (char)0x90; + *((char*)ptr + 1) = (char)0x90; + *((char*)ptr + 2) = (char)0x90; + *((char*)ptr + 3) = (char)0x90; + *((char*)ptr + 4) = (char)0x90; + *((char*)ptr + 5) = (char)0x90; + } +} \ No newline at end of file diff --git a/NorthstarDedicatedTest/buildainfile.h b/NorthstarDedicatedTest/buildainfile.h new file mode 100644 index 00000000..a3c0e090 --- /dev/null +++ b/NorthstarDedicatedTest/buildainfile.h @@ -0,0 +1,3 @@ +#pragma once + +void InitialiseBuildAINFileHooks(HMODULE baseAddress); \ No newline at end of file diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index db422467..dad0d3ee 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -32,6 +32,7 @@ #include "maxplayers.h" #include "languagehooks.h" #include "audio.h" +#include "buildainfile.h" bool initialised = false; @@ -125,6 +126,7 @@ bool InitialiseNorthstar() AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer); AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand); AddDllLoadCallback("server.dll", InitialiseMiscServerFixes); + AddDllLoadCallback("server.dll", InitialiseBuildAINFileHooks); AddDllLoadCallback("engine.dll", InitialisePlaylistHooks); -- cgit v1.2.3