From 92edf22b0787af8b5ff6e2128bcb5350566fdc16 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sun, 20 Mar 2022 17:03:46 +0100 Subject: [PATCH] The beginning of SaveAINFile --- r5dev/core/init.cpp | 2 + r5dev/game/server/ai_network.h | 8 +- r5dev/game/server/ai_networkmanager.cpp | 302 ++++++++++++------------ r5dev/game/server/ai_networkmanager.h | 18 +- r5dev/game/server/ai_node.h | 4 +- 5 files changed, 178 insertions(+), 156 deletions(-) diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 71b861e1..24eb80ca 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -151,6 +151,7 @@ void Systems_Init() //DebugOverlays_Attach(); #endif // !DEDICATED CAI_Utility_Attach(); + CAI_NetworkManager_Attach(); // Patch instructions RuntimePtc_Init(); @@ -242,6 +243,7 @@ void Systems_Shutdown() //DebugOverlays_Detach(); #endif // !DEDICATED CAI_Utility_Detach(); + CAI_NetworkManager_Detach(); // Commit the transaction DetourTransactionCommit(); diff --git a/r5dev/game/server/ai_network.h b/r5dev/game/server/ai_network.h index 723d8a8e..eb8931bf 100644 --- a/r5dev/game/server/ai_network.h +++ b/r5dev/game/server/ai_network.h @@ -9,7 +9,7 @@ class CAI_Network { public: - char unk0[8]; // +0 + void* m_pVTable; // this is uninitialised and never set on ain build, fun! int linkcount; // +8 @@ -25,9 +25,11 @@ public: // these probably aren't actually hints, but there's 1 of them per hint so idk short hints[2000]; // +168 int scriptnodecount; // +4168 + char pad[28]; // unk + int64_t nodecount; // +4200 + CAI_Node** nodes; // +4208 + CAI_ScriptNode scriptnodes[4000]; // +4172 - int nodecount; // +84172 - CAI_Node** nodes; // +84176 public: static void BuildAINFile(CAI_Network* aiNetwork); diff --git a/r5dev/game/server/ai_networkmanager.cpp b/r5dev/game/server/ai_networkmanager.cpp index 64bc95aa..e817846e 100644 --- a/r5dev/game/server/ai_networkmanager.cpp +++ b/r5dev/game/server/ai_networkmanager.cpp @@ -30,184 +30,187 @@ CAI_NetworkBuilder::BuildFile */ void CAI_NetworkBuilder::BuildFile(CAI_Network* pNetwork) { - //std::filesystem::path fsWritePath("platform/maps/graphs"); - //fsWritePath /= g_pHostState->m_levelName; - //fsWritePath += ".ain"; + std::filesystem::path fsWritePath("platform\\maps\\graphs\\"); + fsWritePath /= g_pHostState->m_levelName; + fsWritePath += ".ain"; - //// Dump from memory. - //DevMsg(eDLL_T::SERVER, "++++--------------------------------------------------------------------------------------------------------------------------++++\n"); - //DevMsg(eDLL_T::SERVER, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AI NODE GRAPH FILE CONSTRUCTION STARTED <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); - //DevMsg(eDLL_T::SERVER, "++++--------------------------------------------------------------------------------------------------------------------------++++\n"); - //DevMsg(eDLL_T::SERVER, "Output file: '%s'\n", fsWritePath.string()); + // Dump from memory. + DevMsg(eDLL_T::SERVER, "++++--------------------------------------------------------------------------------------------------------------------------++++\n"); + DevMsg(eDLL_T::SERVER, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> AI NETWORK GRAPH FILE CONSTRUCTION STARTED <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + DevMsg(eDLL_T::SERVER, "++++--------------------------------------------------------------------------------------------------------------------------++++\n"); + DevMsg(eDLL_T::SERVER, "Output file: '%s'\n", fsWritePath.string().c_str()); - //std::ofstream writeStream(fsWritePath, std::ofstream::binary); - //DevMsg(eDLL_T::SERVER, "Writing AINet version: %d\n", AINET_VERSION_NUMBER); - //writeStream.write((char*)&AINET_VERSION_NUMBER, sizeof(int)); + std::ofstream writeStream(fsWritePath, std::ofstream::binary); + DevMsg(eDLL_T::SERVER, "Writing AINet version: '%d'\n", AINET_VERSION_NUMBER); + writeStream.write((char*)&AINET_VERSION_NUMBER, sizeof(int)); - //// Could probably be cleaner but whatever - ////int nMapVersion = *(int*)(*pUnkServerMapversionGlobal + 104); // TODO: Find in apex - ////DevMsg(eDLL_T::SERVER, "Writing map version: %d\n", nMapVersion); // temp - ////writeStream.write((char*)&nMapVersion, sizeof(int)); + int nMapVersion = g_ServerGlobalVariables->m_nMapVersion; + DevMsg(eDLL_T::SERVER, "Writing map version: '%d'\n", nMapVersion); + writeStream.write((char*)&nMapVersion, sizeof(int)); - //DevMsg(eDLL_T::SERVER, "Writing placeholder crc: %d\n", PLACEHOLDER_CRC); - //writeStream.write((char*)&PLACEHOLDER_CRC, sizeof(int)); + DevMsg(eDLL_T::SERVER, "Writing placeholder CRC: '%d'\n", PLACEHOLDER_CRC); + writeStream.write((char*)&PLACEHOLDER_CRC, sizeof(int)); - //int nCalculatedLinkcount = 0; + int nCalculatedLinkcount = 0; - //// Path nodes - //DevMsg(eDLL_T::SERVER, "Writing nodecount: %d\n", pNetwork->nodecount); - //writeStream.write((char*)&pNetwork->nodecount, sizeof(int)); + // Path nodes + DevMsg(eDLL_T::SERVER, "Writing nodecount: '%d'\n", pNetwork->nodecount); + writeStream.write((char*)&pNetwork->nodecount, sizeof(int)); - //for (int i = 0; i < pNetwork->nodecount; i++) - //{ - // // construct on-disk node struct - // CAI_NodeDisk diskNode{}; - // diskNode.x = pNetwork->nodes[i]->x; - // diskNode.y = pNetwork->nodes[i]->y; - // diskNode.z = pNetwork->nodes[i]->z; - // diskNode.yaw = pNetwork->nodes[i]->yaw; - // memcpy(diskNode.hulls, pNetwork->nodes[i]->hulls, sizeof(diskNode.hulls)); - // diskNode.unk0 = (char)pNetwork->nodes[i]->unk0; - // diskNode.unk1 = pNetwork->nodes[i]->unk1; + for (int i = 0; i < pNetwork->nodecount; i++) + { + sizeof(CAI_Network); - // for (int j = 0; j < MAX_HULLS; j++) - // { - // diskNode.unk2[j] = (short)pNetwork->nodes[i]->unk2[j]; - // spdlog::info((short)pNetwork->nodes[i]->unk2[j]); - // } + // Construct on-disk node struct. + CAI_NodeDisk diskNode{}; + diskNode.x = pNetwork->nodes[i]->x; + diskNode.y = pNetwork->nodes[i]->y; + diskNode.z = pNetwork->nodes[i]->z; + diskNode.yaw = pNetwork->nodes[i]->yaw; + memcpy(diskNode.hulls, pNetwork->nodes[i]->hulls, sizeof(diskNode.hulls)); + diskNode.unk0 = (char)pNetwork->nodes[i]->unk0; + diskNode.unk1 = pNetwork->nodes[i]->unk1; - // memcpy(diskNode.unk3, pNetwork->nodes[i]->unk3, sizeof(diskNode.unk3)); - // diskNode.unk4 = pNetwork->nodes[i]->unk6; - // diskNode.unk5 = - // -1; // aiNetwork->nodes[i]->unk8; // This field is wrong, however it's always -1 in original navmeshes anyway. - // memcpy(diskNode.unk6, pNetwork->nodes[i]->unk10, sizeof(diskNode.unk6)); + for (int j = 0; j < MAX_HULLS; j++) + { + diskNode.unk2[j] = (short)pNetwork->nodes[i]->unk2[j]; + spdlog::info((short)pNetwork->nodes[i]->unk2[j]); + } - // DevMsg(eDLL_T::SERVER, "Writing node %d from %d to %x\n", pNetwork->nodes[i]->index, (void*)pNetwork->nodes[i], writeStream.tellp()); - // writeStream.write((char*)&diskNode, sizeof(CAI_NodeDisk)); + memcpy(diskNode.unk3, pNetwork->nodes[i]->unk3, sizeof(diskNode.unk3)); + diskNode.unk4 = pNetwork->nodes[i]->unk6; + diskNode.unk5 = -1; // aiNetwork->nodes[i]->unk8; // This field is wrong, however it's always -1 in original navmeshes anyway. + memcpy(diskNode.unk6, pNetwork->nodes[i]->unk10, sizeof(diskNode.unk6)); - // nCalculatedLinkcount += pNetwork->nodes[i]->linkcount; - //} + DevMsg(eDLL_T::SERVER, "Writing node '%d' from '%d' to '%x'\n", pNetwork->nodes[i]->index, (void*)pNetwork->nodes[i], writeStream.tellp()); + writeStream.write((char*)&diskNode, sizeof(CAI_NodeDisk)); - //// links - //DevMsg(eDLL_T::SERVER, "Linkcount: %d\n", pNetwork->linkcount); - //DevMsg(eDLL_T::SERVER, "Calculated total linkcount: %d\n", nCalculatedLinkcount); + nCalculatedLinkcount += pNetwork->nodes[i]->linkcount; + } - //nCalculatedLinkcount /= 2; - //if (ai_dumpAINfileFromLoad->GetBool()) - //{ - // if (pNetwork->linkcount == nCalculatedLinkcount) - // DevMsg(eDLL_T::SERVER, "Caculated linkcount is normal!"); - // else - // DevMsg(eDLL_T::SERVER, "Calculated linkcount has weird value! this is expected on build!"); - //} + // links + DevMsg(eDLL_T::SERVER, "Linkcount: '%d'\n", pNetwork->linkcount); + DevMsg(eDLL_T::SERVER, "Calculated total linkcount: '%d'\n", nCalculatedLinkcount); - //spdlog::info("Writing linkcount: %d\n", nCalculatedLinkcount); - //writeStream.write((char*)&nCalculatedLinkcount, sizeof(int)); + nCalculatedLinkcount /= 2; + if (ai_dumpAINfileFromLoad->GetBool()) + { + if (pNetwork->linkcount == nCalculatedLinkcount) + { + DevMsg(eDLL_T::SERVER, "Caculated linkcount is normal!"); + } + else + { + DevMsg(eDLL_T::SERVER, "Calculated linkcount has unexpected value. This is expected on build!"); + } + } - //for (int i = 0; i < pNetwork->nodecount; i++) - //{ - // for (int j = 0; j < pNetwork->nodes[i]->linkcount; j++) - // { - // // skip links that don't originate from current node - // if (pNetwork->nodes[i]->links[j]->srcId != pNetwork->nodes[i]->index) - // continue; + DevMsg(eDLL_T::SERVER, "Writing linkcount: '%d'\n", nCalculatedLinkcount); + writeStream.write((char*)&nCalculatedLinkcount, sizeof(int)); - // CAI_NodeLinkDisk diskLink{}; - // diskLink.srcId = pNetwork->nodes[i]->links[j]->srcId; - // diskLink.destId = pNetwork->nodes[i]->links[j]->destId; - // diskLink.unk0 = pNetwork->nodes[i]->links[j]->unk1; - // memcpy(diskLink.hulls, pNetwork->nodes[i]->links[j]->hulls, sizeof(diskLink.hulls)); + for (int i = 0; i < pNetwork->nodecount; i++) + { + for (int j = 0; j < pNetwork->nodes[i]->linkcount; j++) + { + // skip links that don't originate from current node + if (pNetwork->nodes[i]->links[j]->srcId != pNetwork->nodes[i]->index) + continue; - // DevMsg(eDLL_T::SERVER, "Writing link %d => %d to %x\n", diskLink.srcId, diskLink.destId, writeStream.tellp()); - // writeStream.write((char*)&diskLink, sizeof(CAI_NodeLinkDisk)); - // } - //} + CAI_NodeLinkDisk diskLink{}; + diskLink.srcId = pNetwork->nodes[i]->links[j]->srcId; + diskLink.destId = pNetwork->nodes[i]->links[j]->destId; + diskLink.unk0 = pNetwork->nodes[i]->links[j]->unk1; + memcpy(diskLink.hulls, pNetwork->nodes[i]->links[j]->hulls, sizeof(diskLink.hulls)); - //// Don't know what this is, it's likely a block from tf1 that got deprecated? should just be 1 int per node - //DevMsg(eDLL_T::SERVER, "Writing %x bytes for unknown block at %x\n", pNetwork->nodecount * sizeof(uint32_t), writeStream.tellp()); - //uint32_t* unkNodeBlock = new uint32_t[pNetwork->nodecount]; - //memset(unkNodeBlock, 0, pNetwork->nodecount * sizeof(uint32_t)); - //writeStream.write((char*)unkNodeBlock, pNetwork->nodecount * sizeof(uint32_t)); - //delete[] unkNodeBlock; + DevMsg(eDLL_T::SERVER, "Writing link '%d' => '%d' to '%x'\n", diskLink.srcId, diskLink.destId, writeStream.tellp()); + writeStream.write((char*)&diskLink, sizeof(CAI_NodeLinkDisk)); + } + } - //// TODO: this is traverse nodes i think? these aren't used in tf2 ains so we can get away with just writing count=0 and skipping - //// but ideally should actually dump these - //DevMsg(eDLL_T::SERVER, "Writing %d traversal nodes at %x\n", 0, writeStream.tellp()); - //short traverseNodeCount = 0; - //writeStream.write((char*)&traverseNodeCount, sizeof(short)); - //// Only write count since count=0 means we don't have to actually do anything here + // Don't know what this is, it's likely a block from tf1 that got deprecated? should just be 1 int per node + DevMsg(eDLL_T::SERVER, "Writing '%x' bytes for unknown block at '%x'\n", pNetwork->nodecount * sizeof(uint32_t), writeStream.tellp()); + uint32_t* unkNodeBlock = new uint32_t[pNetwork->nodecount]; + memset(unkNodeBlock, 0, pNetwork->nodecount * sizeof(uint32_t)); + writeStream.write((char*)unkNodeBlock, pNetwork->nodecount * sizeof(uint32_t)); + delete[] unkNodeBlock; - //// TODO: ideally these should be actually dumped, but they're always 0 in tf2 from what i can tell - //DevMsg(eDLL_T::SERVER, "Writing %d bytes for unknown hull block at %x\n", MAX_HULLS * 8, writeStream.tellp()); - //char* unkHullBlock = new char[MAX_HULLS * 8]; - //memset(unkHullBlock, 0, MAX_HULLS * 8); - //writeStream.write(unkHullBlock, MAX_HULLS * 8); - //delete[] unkHullBlock; + // TODO: this is traverse nodes i think? these aren't used in tf2 ains so we can get away with just writing count=0 and skipping + // but ideally should actually dump these + DevMsg(eDLL_T::SERVER, "Writing '%d' traversal nodes at '%x'\n", 0, writeStream.tellp()); + short traverseNodeCount = 0; + writeStream.write((char*)&traverseNodeCount, sizeof(short)); + // Only write count since count=0 means we don't have to actually do anything here - //// Snknown struct that's seemingly node-related - //DevMsg(eDLL_T::SERVER, "Writing %d unknown node structs at %x\n", *pUnkStruct0Count, writeStream.tellp()); - //writeStream.write((char*)pUnkStruct0Count, sizeof(*pUnkStruct0Count)); - //for (int i = 0; i < *pUnkStruct0Count; i++) - //{ - // DevMsg(eDLL_T::SERVER, "Writing unknown node struct %d at %x\n", i, writeStream.tellp()); - // UnkNodeStruct0* nodeStruct = (*pppUnkNodeStruct0s)[i]; + // TODO: ideally these should be actually dumped, but they're always 0 in tf2 from what i can tell + DevMsg(eDLL_T::SERVER, "Writing '%d' bytes for unknown hull block at '%x'\n", MAX_HULLS * 8, writeStream.tellp()); + char* unkHullBlock = new char[MAX_HULLS * 8]; + memset(unkHullBlock, 0, MAX_HULLS * 8); + writeStream.write(unkHullBlock, MAX_HULLS * 8); + delete[] unkHullBlock; - // writeStream.write((char*)&nodeStruct->index, sizeof(nodeStruct->index)); - // writeStream.write((char*)&nodeStruct->unk1, sizeof(nodeStruct->unk1)); + DevMsg(eDLL_T::SERVER, "Writing '%d' node clusters at '%x'\n", *g_nAiNodeClusters, writeStream.tellp()); + writeStream.write((char*)g_nAiNodeClusters, sizeof(*g_nAiNodeClusters)); + for (int i = 0; i < *g_nAiNodeClusters; i++) + { + DevMsg(eDLL_T::SERVER, "Writing unknown node struct '%d' at '%x'\n", i, writeStream.tellp()); + AINodeClusters* nodeClusters = (*g_pppAiNodeClusters)[i]; - // writeStream.write((char*)&nodeStruct->x, sizeof(nodeStruct->x)); - // writeStream.write((char*)&nodeStruct->y, sizeof(nodeStruct->y)); - // writeStream.write((char*)&nodeStruct->z, sizeof(nodeStruct->z)); + writeStream.write((char*)&nodeClusters->index, sizeof(nodeClusters->index)); + writeStream.write((char*)&nodeClusters->unk1, sizeof(nodeClusters->unk1)); - // writeStream.write((char*)&nodeStruct->unkcount0, sizeof(nodeStruct->unkcount0)); - // for (int j = 0; j < nodeStruct->unkcount0; j++) - // { - // short unk2Short = (short)nodeStruct->unk2[j]; - // writeStream.write((char*)&unk2Short, sizeof(unk2Short)); - // } + writeStream.write((char*)&nodeClusters->x, sizeof(nodeClusters->x)); + writeStream.write((char*)&nodeClusters->y, sizeof(nodeClusters->y)); + writeStream.write((char*)&nodeClusters->z, sizeof(nodeClusters->z)); - // writeStream.write((char*)&nodeStruct->unkcount1, sizeof(nodeStruct->unkcount1)); - // for (int j = 0; j < nodeStruct->unkcount1; j++) - // { - // short unk3Short = (short)nodeStruct->unk3[j]; - // writeStream.write((char*)&unk3Short, sizeof(unk3Short)); - // } + writeStream.write((char*)&nodeClusters->unkcount0, sizeof(nodeClusters->unkcount0)); + for (int j = 0; j < nodeClusters->unkcount0; j++) + { + short unk2Short = (short)nodeClusters->unk2[j]; + writeStream.write((char*)&unk2Short, sizeof(unk2Short)); + } - // writeStream.write((char*)&nodeStruct->unk5, sizeof(nodeStruct->unk5)); - //} + writeStream.write((char*)&nodeClusters->unkcount1, sizeof(nodeClusters->unkcount1)); + for (int j = 0; j < nodeClusters->unkcount1; j++) + { + short unk3Short = (short)nodeClusters->unk3[j]; + writeStream.write((char*)&unk3Short, sizeof(unk3Short)); + } - //// Unknown struct that's seemingly link-related - //DevMsg(eDLL_T::SERVER, "Writing %d unknown link structs at %x\n", *pUnkLinkStruct1Count, writeStream.tellp()); - //writeStream.write((char*)pUnkLinkStruct1Count, sizeof(*pUnkLinkStruct1Count)); - //for (int i = 0; i < *pUnkLinkStruct1Count; i++) - //{ - // // disk and memory structs are literally identical here so just directly write - // DevMsg(eDLL_T::SERVER, "Writing unknown link struct %d at %x\n", i, writeStream.tellp()); - // writeStream.write((char*)(*pppUnkStruct1s)[i], sizeof(*(*pppUnkStruct1s)[i])); - //} + writeStream.write((char*)&nodeClusters->unk5, sizeof(nodeClusters->unk5)); + } - //// Some weird int idk what this is used for - //writeStream.write((char*)&pNetwork->unk5, sizeof(pNetwork->unk5)); + // Unknown struct that's seemingly link-related + DevMsg(eDLL_T::SERVER, "Writing '%d' unknown link structs at '%x'\n", *g_nAiNodeClusterLinks, writeStream.tellp()); + writeStream.write((char*)g_nAiNodeClusterLinks, sizeof(*g_nAiNodeClusterLinks)); + for (int i = 0; i < *g_nAiNodeClusterLinks; i++) + { + // Disk and memory structs are literally identical here so just directly write. + DevMsg(eDLL_T::SERVER, "Writing unknown link struct '%d' at '%x'\n", i, writeStream.tellp()); + writeStream.write((char*)(*g_pppAiNodeClusterLinks)[i], sizeof(*(*g_pppAiNodeClusterLinks)[i])); + } - //// Tf2-exclusive stuff past this point, i.e. ain v57 only - //DevMsg(eDLL_T::SERVER, "Writing %d script nodes at %x\n", pNetwork->scriptnodecount, writeStream.tellp()); - //writeStream.write((char*)&pNetwork->scriptnodecount, sizeof(pNetwork->scriptnodecount)); - //for (int i = 0; i < pNetwork->scriptnodecount; i++) - //{ - // // disk and memory structs are literally identical here so just directly write - // DevMsg(eDLL_T::SERVER, "Writing script node %d at %x\n", i, writeStream.tellp()); - // writeStream.write((char*)&pNetwork->scriptnodes[i], sizeof(pNetwork->scriptnodes[i])); - //} + // Some weird int idk what this is used for. + writeStream.write((char*)&pNetwork->unk5, sizeof(pNetwork->unk5)); - //DevMsg(eDLL_T::SERVER, "Writing %d hints at %x\n", pNetwork->hintcount, writeStream.tellp()); - //writeStream.write((char*)&pNetwork->hintcount, sizeof(pNetwork->hintcount)); - //for (int i = 0; i < pNetwork->hintcount; i++) - //{ - // DevMsg(eDLL_T::SERVER, "Writing hint data %d at %x\n", i, writeStream.tellp()); - // writeStream.write((char*)&pNetwork->hints[i], sizeof(pNetwork->hints[i])); - //} + // Tf2-exclusive stuff past this point, i.e. ain v57 only. + DevMsg(eDLL_T::SERVER, "Writing '%d' script nodes at '%x'\n", pNetwork->scriptnodecount, writeStream.tellp()); + writeStream.write((char*)&pNetwork->scriptnodecount, sizeof(pNetwork->scriptnodecount)); + for (int i = 0; i < pNetwork->scriptnodecount; i++) + { + // disk and memory structs are literally identical here so just directly write + //DevMsg(eDLL_T::SERVER, "Writing script node %d at %x\n", i, writeStream.tellp()); + //writeStream.write((char*)&pNetwork->scriptnodes[i], sizeof(pNetwork->scriptnodes[i])); + } - //writeStream.close(); + DevMsg(eDLL_T::SERVER, "Writing '%d' hints at '%x'\n", pNetwork->hintcount, writeStream.tellp()); + writeStream.write((char*)&pNetwork->hintcount, sizeof(pNetwork->hintcount)); + for (int i = 0; i < pNetwork->hintcount; i++) + { + DevMsg(eDLL_T::SERVER, "Writing hint data '%d' at '%x'\n", i, writeStream.tellp()); + writeStream.write((char*)&pNetwork->hints[i], sizeof(pNetwork->hints[i])); + } + + writeStream.close(); } void HCAI_NetworkManager__LoadNetworkGraph(void* aimanager, void* buf, const char* filename) @@ -220,15 +223,14 @@ void HCAI_NetworkManager__LoadNetworkGraph(void* aimanager, void* buf, const cha if (ai_dumpAINfileFromLoad->GetBool()) { - DevMsg(eDLL_T::SERVER, "Running BuildAINFile for loaded file %s\n", filename); - CAI_NetworkBuilder::BuildFile(*(CAI_Network**)((char*)aimanager + 2536)); // TODO: Verify in r5apex.exe. + DevMsg(eDLL_T::SERVER, "Running BuildAINFile for loaded file '%s'\n", filename); + CAI_NetworkBuilder::BuildFile(*(CAI_Network**)((char*)aimanager + 2840)); } } void HCAI_NetworkBuilder__Build(void* builder, CAI_Network* aiNetwork, void* a3, int a4) { CAI_NetworkBuilder__Build(builder, aiNetwork, a3, a4); - CAI_NetworkBuilder::BuildFile(aiNetwork); } diff --git a/r5dev/game/server/ai_networkmanager.h b/r5dev/game/server/ai_networkmanager.h index e7ce4065..29bcef36 100644 --- a/r5dev/game/server/ai_networkmanager.h +++ b/r5dev/game/server/ai_networkmanager.h @@ -23,11 +23,27 @@ namespace ADDRESS p_CAI_NetworkBuilder__Build = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x4C\x24\x00\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x30\x48\x63\xBA\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxx????"); void* (*CAI_NetworkBuilder__Build)(void* thisptr, CAI_Network* pNetWork, void* a3, int a4) = (void* (*)(void*, CAI_Network*, void*, int))p_CAI_NetworkBuilder__Build.GetPtr(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 4C 24 ? 57 41 54 41 55 41 56 41 57 48 83 EC 30 48 63 BA ? ? ? ?*/ #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - ADDRESS p_CAI_NetworkBuilder__Build = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\x48\x8B\x0D\x00\x00\x00\x00\x8B\x41\x6C", "xxxxxxxxxxxx????xxx"); + ADDRESS p_CAI_NetworkBuilder__Build = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x54\x24\x00\x48\x89\x4C\x24\x00\x53\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x38\x8B\xB2\x00\x00\x00\x00", "xxxx?xxxx?xxxxxxxxxxxxxxxxxx????"); void* (*CAI_NetworkBuilder__Build)(void* thisptr, CAI_Network* pNetWork, void* a3, int a4) = (void* (*)(void*, CAI_Network*, void*, int))p_CAI_NetworkBuilder__Build.GetPtr(); /*48 89 54 24 ? 48 89 4C 24 ? 53 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 38 8B B2 ? ? ? ?*/ #endif } +void CAI_NetworkManager_Attach(); +void CAI_NetworkManager_Detach(); + +// dword_165DAD808 = g_nAiNodeClusters +// qword_165DAD7F0 = pppUnkNodeStruct0s +// dword_165DB18E8 = g_nAiNodeClusterLinks +// qword_165DB18D0 = pppUnkStruct1s + +namespace // !TODO: [AMOS] don't hardocde. +{ + int* g_nAiNodeClusters = ADDRESS(0x165DAD808).RCast(); + AINodeClusters*** g_pppAiNodeClusters = ADDRESS(0x165DB18E8).RCast(); + int* g_nAiNodeClusterLinks = ADDRESS(0x165DB18E8).RCast(); + AINodeClusterLinks*** g_pppAiNodeClusterLinks = ADDRESS(0x165DB18E8).RCast(); +} + //----------------------------------------------------------------------------- // CAI_NetworkBuilder // diff --git a/r5dev/game/server/ai_node.h b/r5dev/game/server/ai_node.h index 74ae887c..2515b8c2 100644 --- a/r5dev/game/server/ai_node.h +++ b/r5dev/game/server/ai_node.h @@ -98,7 +98,7 @@ struct CAI_ScriptNode uint64_t scriptdata; }; -struct UnkNodeStruct0 +struct AINodeClusters { int index; char unk0; @@ -126,7 +126,7 @@ struct UnkNodeStruct0 //int* pUnkStruct0Count; //UnkNodeStruct0*** pppUnkNodeStruct0s; -struct UnkLinkStruct1 +struct AINodeClusterLinks { short unk0; short unk1;