1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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<LPVOID*>(&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;
}
}
|