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