From fbcee16f97c6f0b1ea1b49c68182ed12c955f7e8 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 24 Jun 2022 16:56:28 +0200 Subject: [PATCH] CAI_NetworkBuilder::SaveNetworkGraph improvements Use CIOStream class. Use proper type for CAI_Network::m_iNumNodes. Improved CIOStream to take std::filesystem::path instead of std::string. --- r5dev/game/server/ai_network.h | 2 +- r5dev/game/server/ai_networkmanager.cpp | 97 ++++++++++++------------- r5dev/public/binstream.cpp | 11 +-- r5dev/public/include/binstream.h | 5 +- 4 files changed, 52 insertions(+), 63 deletions(-) diff --git a/r5dev/game/server/ai_network.h b/r5dev/game/server/ai_network.h index 4a40ec65..f3da9cc9 100644 --- a/r5dev/game/server/ai_network.h +++ b/r5dev/game/server/ai_network.h @@ -40,7 +40,7 @@ public: char pad0[0x14]; // +0x1054 <-- !TODO - int64_t m_iNumNodes; // +0x1070 + int m_iNumNodes; // +0x1070 CAI_Node** m_pAInode; // +0x1078 }; diff --git a/r5dev/game/server/ai_networkmanager.cpp b/r5dev/game/server/ai_networkmanager.cpp index 25ae978b..d53e1b79 100644 --- a/r5dev/game/server/ai_networkmanager.cpp +++ b/r5dev/game/server/ai_networkmanager.cpp @@ -9,6 +9,7 @@ #include "tier1/cvar.h" #include "tier1/cmd.h" #include "mathlib/crc32.h" +#include "public/include/binstream.h" #include "public/include/edict.h" #include "public/include/utility.h" #include "engine/host_state.h" @@ -39,6 +40,8 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) CFastTimer masterTimer; CFastTimer timer; + CIOStream writer(fsGraphPath, CIOStream::Mode_t::WRITE); + int nCalculatedLinkcount = 0; // Build from memory. @@ -52,38 +55,30 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) CreateDirectories(svGraphDir); - ofstream writeStream(fsGraphPath, ofstream::binary); DevMsg(eDLL_T::SERVER, " |-- AINet version: '%d'\n", AINET_VERSION_NUMBER); - writeStream.write(reinterpret_cast(&AINET_VERSION_NUMBER), sizeof(int)); + writer.Write(&AINET_VERSION_NUMBER, sizeof(int)); - int nMapVersion = g_ServerGlobalVariables->m_nMapVersion; - DevMsg(eDLL_T::SERVER, " |-- Map version: '%d'\n", nMapVersion); - writeStream.write(reinterpret_cast(&nMapVersion), sizeof(int)); + DevMsg(eDLL_T::SERVER, " |-- Map version: '%d'\n", g_ServerGlobalVariables->m_nMapVersion); + writer.Write(&g_ServerGlobalVariables->m_nMapVersion, sizeof(int)); - ifstream iNavMesh(fsMeshPath, fstream::binary); - vector uNavMesh; + CIOStream reader(fsMeshPath, CIOStream::Mode_t::READ); uint32_t nNavMeshHash = NULL; - if (iNavMesh.good()) + if (reader.IsReadable()) { - iNavMesh.seekg(0, fstream::end); - uNavMesh.resize(iNavMesh.tellg()); - iNavMesh.seekg(0, fstream::beg); - iNavMesh.read(reinterpret_cast(uNavMesh.data()), uNavMesh.size()); - - nNavMeshHash = crc32::update(NULL, uNavMesh.data(), uNavMesh.size()); + nNavMeshHash = crc32::update(NULL, reader.GetData(), reader.GetSize()); } else { - Warning(eDLL_T::SERVER, "%s - No %s NavMesh found. Unable to calculate CRC for AI Network\n", __FUNCTION__, HULL_SIZE[3].c_str()); + Warning(eDLL_T::SERVER, "%s - No %s NavMesh found. Unable to calculate CRC for AI Network.\n", __FUNCTION__, HULL_SIZE[3].c_str()); } // Large NavMesh CRC. DevMsg(eDLL_T::SERVER, " |-- NavMesh CRC: '%lx'\n", nNavMeshHash); - writeStream.write(reinterpret_cast(&nNavMeshHash), sizeof(int)); + writer.Write(&nNavMeshHash, sizeof(int)); // Path nodes. DevMsg(eDLL_T::SERVER, " |-- Nodecount: '%d'\n", pNetwork->m_iNumNodes); - writeStream.write(reinterpret_cast(&pNetwork->m_iNumNodes), sizeof(int)); + writer.Write(&pNetwork->m_iNumNodes, sizeof(int)); timer.End(); DevMsg(eDLL_T::SERVER, "...done writing header. %lf seconds\n", timer.GetDuration().GetSeconds()); @@ -116,8 +111,8 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) memcpy(diskNode.unk6, pNetwork->m_pAInode[i]->unk10, sizeof(diskNode.unk6)); - DevMsg(eDLL_T::SERVER, " |-- Copying node '#%d' from '0x%p' to '0x%llX'\n", pNetwork->m_pAInode[i]->m_nIndex, reinterpret_cast(pNetwork->m_pAInode[i]), static_cast(writeStream.tellp())); - writeStream.write(reinterpret_cast(&diskNode), sizeof(CAI_NodeDisk)); + DevMsg(eDLL_T::SERVER, " |-- Copying node '#%d' from '0x%p' to '0x%zX'\n", pNetwork->m_pAInode[i]->m_nIndex, reinterpret_cast(pNetwork->m_pAInode[i]), writer.GetPosition()); + writer.Write(&diskNode, sizeof(CAI_NodeDisk)); nCalculatedLinkcount += pNetwork->m_pAInode[i]->m_nNumLinks; } @@ -140,7 +135,7 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) } } - writeStream.write(reinterpret_cast(&nCalculatedLinkcount), sizeof(int)); + writer.Write(&nCalculatedLinkcount, sizeof(int)); if (pNetwork->m_pAInode) { @@ -160,8 +155,8 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) diskLink.unk0 = pNetwork->m_pAInode[i]->links[j]->unk1; memcpy(diskLink.m_bHulls, pNetwork->m_pAInode[i]->links[j]->m_bHulls, sizeof(diskLink.m_bHulls)); - DevMsg(eDLL_T::SERVER, " |-- Writing link '%d' => '%d' to '0x%llX'\n", diskLink.m_iSrcID, diskLink.m_iDestID, static_cast(writeStream.tellp())); - writeStream.write(reinterpret_cast(&diskLink), sizeof(CAI_NodeLinkDisk)); + DevMsg(eDLL_T::SERVER, " |-- Writing link '%d' => '%d' to '0x%zX'\n", diskLink.m_iSrcID, diskLink.m_iDestID, writer.GetPosition()); + writer.Write(&diskLink, sizeof(CAI_NodeLinkDisk)); } } } @@ -172,27 +167,27 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) timer.Start(); DevMsg(eDLL_T::SERVER, "+- Writing hull data...\n"); // 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 '%d' bytes for unknown block at '0x%llX'\n", pNetwork->m_iNumNodes * sizeof(uint32_t), static_cast(writeStream.tellp())); + DevMsg(eDLL_T::SERVER, " |-- Writing '%d' bytes for unknown block at '0x%zX'\n", pNetwork->m_iNumNodes * sizeof(uint32_t), writer.GetPosition()); if (static_cast(pNetwork->m_iNumNodes) > 0) { uint32_t* unkNodeBlock = new uint32_t[pNetwork->m_iNumNodes]; memset(&unkNodeBlock, '\0', pNetwork->m_iNumNodes * sizeof(uint32_t)); - writeStream.write(reinterpret_cast(*unkNodeBlock), pNetwork->m_iNumNodes * sizeof(uint32_t)); + writer.Write(&*unkNodeBlock, pNetwork->m_iNumNodes * sizeof(uint32_t)); delete[] unkNodeBlock; } // TODO: This is traverse nodes i think? these aren't used in r2 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 '0x%llX'\n", 0, static_cast(writeStream.tellp())); + DevMsg(eDLL_T::SERVER, " |-- Writing '%d' traversal nodes at '0x%zX'\n", 0, static_cast(writer.GetPosition())); short traverseNodeCount = 0; // Only write count since count=0 means we don't have to actually do anything here. - writeStream.write(reinterpret_cast(&traverseNodeCount), sizeof(short)); + writer.Write(&traverseNodeCount, sizeof(short)); // TODO: Ideally these should be actually dumped, but they're always 0 in r2 from what i can tell. - DevMsg(eDLL_T::SERVER, " |-- Writing '%d' bytes for unknown hull block at '0x%llX'\n", MAX_HULLS * 8, static_cast(writeStream.tellp())); + DevMsg(eDLL_T::SERVER, " |-- Writing '%d' bytes for unknown hull block at '0x%zX'\n", MAX_HULLS * 8, writer.GetPosition()); char* unkHullBlock = new char[MAX_HULLS * 8]; memset(unkHullBlock, '\0', MAX_HULLS * 8); - writeStream.write(unkHullBlock, MAX_HULLS * 8); + writer.Write(&unkHullBlock, MAX_HULLS * 8); delete[] unkHullBlock; timer.End(); @@ -201,34 +196,34 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) timer.Start(); DevMsg(eDLL_T::SERVER, "+- Writing clusters...\n"); - writeStream.write(reinterpret_cast(g_nAiNodeClusters), sizeof(*g_nAiNodeClusters)); + writer.Write(&*g_nAiNodeClusters, sizeof(*g_nAiNodeClusters)); for (int i = 0; i < *g_nAiNodeClusters; i++) { - DevMsg(eDLL_T::SERVER, " |-- Writing cluster '#%d' at '0x%llX'\n", i, static_cast(writeStream.tellp())); + DevMsg(eDLL_T::SERVER, " |-- Writing cluster '#%d' at '0x%zX'\n", i, writer.GetPosition()); AINodeClusters* nodeClusters = (*g_pppAiNodeClusters)[i]; - writeStream.write(reinterpret_cast(&nodeClusters->m_nIndex), sizeof(nodeClusters->m_nIndex)); - writeStream.write(reinterpret_cast(&nodeClusters->unk1), sizeof(nodeClusters->unk1)); + writer.Write(&nodeClusters->m_nIndex, sizeof(nodeClusters->m_nIndex)); + writer.Write(&nodeClusters->unk1, sizeof(nodeClusters->unk1)); - writeStream.write(reinterpret_cast(&nodeClusters->m_vOrigin.x), sizeof(nodeClusters->m_vOrigin.x)); - writeStream.write(reinterpret_cast(&nodeClusters->m_vOrigin.y), sizeof(nodeClusters->m_vOrigin.y)); - writeStream.write(reinterpret_cast(&nodeClusters->m_vOrigin.z), sizeof(nodeClusters->m_vOrigin.z)); + writer.Write(&nodeClusters->m_vOrigin.x, sizeof(nodeClusters->m_vOrigin.x)); + writer.Write(&nodeClusters->m_vOrigin.y, sizeof(nodeClusters->m_vOrigin.y)); + writer.Write(&nodeClusters->m_vOrigin.z, sizeof(nodeClusters->m_vOrigin.z)); - writeStream.write(reinterpret_cast(&nodeClusters->unkcount0), sizeof(nodeClusters->unkcount0)); + writer.Write(&nodeClusters->unkcount0, sizeof(nodeClusters->unkcount0)); for (int j = 0; j < nodeClusters->unkcount0; j++) { short unk2Short = static_cast(nodeClusters->unk2[j]); - writeStream.write(reinterpret_cast(&unk2Short), sizeof(unk2Short)); + writer.Write(&unk2Short, sizeof(unk2Short)); } - writeStream.write(reinterpret_cast(&nodeClusters->unkcount1), sizeof(nodeClusters->unkcount1)); + writer.Write(&nodeClusters->unkcount1, sizeof(nodeClusters->unkcount1)); for (int j = 0; j < nodeClusters->unkcount1; j++) { short unk3Short = static_cast(nodeClusters->unk3[j]); - writeStream.write(reinterpret_cast(&unk3Short), sizeof(unk3Short)); + writer.Write(&unk3Short, sizeof(unk3Short)); } - writeStream.write(reinterpret_cast(&nodeClusters->unk5), sizeof(nodeClusters->unk5)); + writer.Write(&nodeClusters->unk5, sizeof(nodeClusters->unk5)); } timer.End(); @@ -237,32 +232,32 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) timer.Start(); DevMsg(eDLL_T::SERVER, "+- Writing cluster links...\n"); - writeStream.write(reinterpret_cast(g_nAiNodeClusterLinks), sizeof(*g_nAiNodeClusterLinks)); + writer.Write(&*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 cluster link '#%d' at '0x%llX'\n", i, static_cast(writeStream.tellp())); - writeStream.write(reinterpret_cast((*g_pppAiNodeClusterLinks)[i]), sizeof(*(*g_pppAiNodeClusterLinks)[i])); + DevMsg(eDLL_T::SERVER, " |-- Writing cluster link '#%d' at '0x%zX'\n", i, writer.GetPosition()); + writer.Write(&*g_pppAiNodeClusterLinks[i], sizeof(*(*g_pppAiNodeClusterLinks)[i])); } timer.End(); DevMsg(eDLL_T::SERVER, "...done writing cluster links. %lf seconds (%d cluster links)\n", timer.GetDuration().GetSeconds(), *g_nAiNodeClusterLinks); // This is always set to '-1'. Likely a field for maintaining compatibility. - writeStream.write(reinterpret_cast(&pNetwork->unk5), sizeof(pNetwork->unk5)); + writer.Write(&pNetwork->unk5, sizeof(pNetwork->unk5)); // AIN v57 and above only (not present in r1, static array in r2, pointer to dynamic array in r5). timer.Start(); DevMsg(eDLL_T::SERVER, "+- Writing script nodes...\n"); - writeStream.write(reinterpret_cast(&pNetwork->m_iNumScriptNodes), sizeof(pNetwork->m_iNumScriptNodes)); + writer.Write(&pNetwork->m_iNumScriptNodes, sizeof(pNetwork->m_iNumScriptNodes)); for (int i = 0; i < pNetwork->m_iNumScriptNodes; i++) { // Disk and memory structs for script nodes are identical. - DevMsg(eDLL_T::SERVER, " |-- Writing script node '#%d' at '0x%llX'\n", i, static_cast(writeStream.tellp())); + DevMsg(eDLL_T::SERVER, " |-- Writing script node '#%d' at '0x%zX'\n", i, writer.GetPosition()); if (!IsBadReadPtrV2(reinterpret_cast(&pNetwork->m_ScriptNode[i]))) { - writeStream.write(reinterpret_cast(&pNetwork->m_ScriptNode[i]), sizeof(CAI_ScriptNode)); + writer.Write(&pNetwork->m_ScriptNode[i], sizeof(CAI_ScriptNode)); } else { @@ -276,11 +271,11 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) timer.Start(); DevMsg(eDLL_T::SERVER, "+- Writing hint data...\n"); - writeStream.write(reinterpret_cast(&pNetwork->m_iNumHints), sizeof(pNetwork->m_iNumHints)); + writer.Write(&pNetwork->m_iNumHints, sizeof(pNetwork->m_iNumHints)); for (int i = 0; i < pNetwork->m_iNumHints; i++) { - DevMsg(eDLL_T::SERVER, " |-- Writing hint data '#%d' at '0x%llX'\n", i, static_cast(writeStream.tellp())); - writeStream.write(reinterpret_cast(&pNetwork->m_Hints[i]), sizeof(pNetwork->m_Hints[i])); + DevMsg(eDLL_T::SERVER, " |-- Writing hint data '#%d' at '0x%zX'\n", i, writer.GetPosition()); + writer.Write(&pNetwork->m_Hints[i], sizeof(pNetwork->m_Hints[i])); } timer.End(); @@ -290,8 +285,6 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork) DevMsg(eDLL_T::SERVER, "...done writing AI node graph. %lf seconds\n", masterTimer.GetDuration().GetSeconds()); DevMsg(eDLL_T::SERVER, "++++--------------------------------------------------------------------------------------------------------------------------++++\n"); DevMsg(eDLL_T::SERVER, "++++--------------------------------------------------------------------------------------------------------------------------++++\n"); - - writeStream.close(); } /* diff --git a/r5dev/public/binstream.cpp b/r5dev/public/binstream.cpp index bc291995..2b4c6138 100644 --- a/r5dev/public/binstream.cpp +++ b/r5dev/public/binstream.cpp @@ -8,7 +8,7 @@ CIOStream::CIOStream() { m_eCurrentMode = Mode_t::NONE; } -CIOStream::CIOStream(const string& svFileFullPath, Mode_t eMode) +CIOStream::CIOStream(const fs::path& svFileFullPath, Mode_t eMode) { Open(svFileFullPath, eMode); } @@ -29,9 +29,8 @@ CIOStream::~CIOStream() // Input : fileFullPath - mode // Output : true if operation is successfull //----------------------------------------------------------------------------- -bool CIOStream::Open(const string& svFilePath, Mode_t eMode) +bool CIOStream::Open(const fs::path& fsFilePath, Mode_t eMode) { - m_svFilePath = svFilePath; m_eCurrentMode = eMode; switch (m_eCurrentMode) @@ -41,10 +40,9 @@ bool CIOStream::Open(const string& svFilePath, Mode_t eMode) { m_iStream.close(); } - m_iStream.open(m_svFilePath.c_str(), std::ios::binary | std::ios::in); + m_iStream.open(fsFilePath, std::ios::binary | std::ios::in); if (!m_iStream.is_open() || !m_iStream.good()) { - Error(eDLL_T::FS, "Error opening file '%s' for read operation.\n", m_svFilePath.c_str()); m_eCurrentMode = Mode_t::NONE; return false; } @@ -61,10 +59,9 @@ bool CIOStream::Open(const string& svFilePath, Mode_t eMode) { m_oStream.close(); } - m_oStream.open(m_svFilePath.c_str(), std::ios::binary | std::ios::out); + m_oStream.open(fsFilePath, std::ios::binary | std::ios::out); if (!m_oStream.is_open() || !m_oStream.good()) { - Error(eDLL_T::FS, "Error opening file '%s' for write operation.\n", m_svFilePath.c_str()); m_eCurrentMode = Mode_t::NONE; return false; } diff --git a/r5dev/public/include/binstream.h b/r5dev/public/include/binstream.h index e2834214..a132689a 100644 --- a/r5dev/public/include/binstream.h +++ b/r5dev/public/include/binstream.h @@ -11,10 +11,10 @@ public: }; CIOStream(); - CIOStream(const string& svFileFullPath, Mode_t eMode); + CIOStream(const fs::path& fsFileFullPath, Mode_t eMode); ~CIOStream(); - bool Open(const string& svFileFullPath, Mode_t eMode); + bool Open(const fs::path& fsFileFullPath, Mode_t eMode); void Close(); void Flush(); @@ -94,7 +94,6 @@ private: ofstream m_oStream; // Output file stream. ifstream m_iStream; // Input file stream. - string m_svFilePath; // Filepath. vector m_vData; // Data vector Mode_t m_eCurrentMode; // Current active mode. };