Add AI Network methods and add hook for AIN connection debug

This commit is contained in:
Kawe Mazidjatari 2022-04-03 03:10:48 +02:00
parent a4b4bb6ef5
commit 7258a35ff5
13 changed files with 192 additions and 7 deletions

View File

@ -171,6 +171,7 @@ void Systems_Init()
#ifndef CLIENT_DLL
CAI_Utility_Attach();
CAI_Network_Attach();
CAI_NetworkManager_Attach();
#endif // !#ifndef CLIENT_DLL
// Patch instructions
@ -271,6 +272,7 @@ void Systems_Shutdown()
#ifndef CLIENT_DLL
CAI_Utility_Detach();
CAI_Network_Detach();
CAI_NetworkManager_Detach();
#endif // !CLIENT_DLL

View File

@ -0,0 +1,136 @@
//=============================================================================//
//
// Purpose:
//
//=============================================================================//
#include "core/stdafx.h"
#include "tier0/cvar.h"
#include "engine/sys_utils.h"
#include "game/server/ai_network.h"
int g_DebugConnectNode1 = -1;
int g_DebugConnectNode2 = -1;
#define DebuggingConnect( node1, node2 ) ( ( node1 == g_DebugConnectNode1 && node2 == g_DebugConnectNode2 ) || ( node1 == g_DebugConnectNode2 && node2 == g_DebugConnectNode1 ) )
//-----------------------------------------------------------------------------
// Purpose: debug logs node connections
// Input : node1 -
// node2 -
// *pszFormat -
// ... -
//-----------------------------------------------------------------------------
void CAI_Network::DebugConnectMsg(int node1, int node2, const char* pszFormat, ...)
{
if (ai_ainDebugConnect->GetBool())
{
if (DebuggingConnect(node1, node2))
{
static char buf[1024] = {};
{/////////////////////////////
va_list args{};
va_start(args, pszFormat);
vsnprintf(buf, sizeof(buf), pszFormat, args);
buf[sizeof(buf) - 1] = 0;
va_end(args);
}/////////////////////////////
DevMsg(eDLL_T::SERVER, "%s", buf);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: gets the AI Network VTable
// Output : void*
//-----------------------------------------------------------------------------
void* CAI_Network::GetVTable(void) const
{
return m_pVTable;
}
//-----------------------------------------------------------------------------
// Purpose: gets the number of node links
// Output : int
//-----------------------------------------------------------------------------
int CAI_Network::GetNumLinks(void) const
{
return m_iNumLinks;
}
//-----------------------------------------------------------------------------
// Purpose: gets the number of zones
// Output : int
//-----------------------------------------------------------------------------
int CAI_Network::GetNumZones(void) const
{
return m_iNumZones;
}
//-----------------------------------------------------------------------------
// Purpose: gets the number of hints
// Output : int
//-----------------------------------------------------------------------------
int CAI_Network::GetNumHints(void) const
{
return m_iNumHints;
}
//-----------------------------------------------------------------------------
// Purpose: gets the number of script nodes
// Output : int
//-----------------------------------------------------------------------------
int CAI_Network::GetNumScriptNodes(void) const
{
return m_iNumScriptNodes;
}
//-----------------------------------------------------------------------------
// Purpose: gets the path nodes
// Output : int64_t
//-----------------------------------------------------------------------------
int64_t CAI_Network::GetNumPathNodes(void) const
{
return m_iNumNodes;
}
//-----------------------------------------------------------------------------
// Purpose: gets the specified hint from static array
// Input : nIndex -
// Output : int
//-----------------------------------------------------------------------------
short CAI_Network::GetHint(int nIndex) const
{
return m_Hints[nIndex];
}
//-----------------------------------------------------------------------------
// Purpose: gets the pointer to script node array
// Output : CAI_ScriptNode*
//-----------------------------------------------------------------------------
CAI_ScriptNode* CAI_Network::GetScriptNodes(void) const
{
return m_ScriptNode;
}
//-----------------------------------------------------------------------------
// Purpose: gets the pointer to path nodes
// Output : CAI_Node**
//-----------------------------------------------------------------------------
CAI_Node** CAI_Network::GetPathNodes(void) const
{
return m_pAInode;
}
//-----------------------------------------------------------------------------
void CAI_Network_Attach()
{
DetourAttach((LPVOID*)&v_CAI_Network__DebugConnectMsg, &CAI_Network::DebugConnectMsg);
}
void CAI_Network_Detach()
{
DetourDetach((LPVOID*)&v_CAI_Network__DebugConnectMsg, &CAI_Network::DebugConnectMsg);
}

View File

@ -8,6 +8,19 @@
//-----------------------------------------------------------------------------
class CAI_Network
{
public:
static void DebugConnectMsg(int node1, int node2, const char* pszFormat, ...);
void* GetVTable(void) const;
int GetNumLinks(void) const;
int GetNumZones(void) const;
int GetNumHints(void) const;
int GetNumScriptNodes(void) const;
int64_t GetNumPathNodes(void) const;
short GetHint(int nIndex) const;
CAI_ScriptNode* GetScriptNodes(void) const;
CAI_Node** GetPathNodes(void) const;
public:
void* m_pVTable; // <-- 'this'.
@ -30,3 +43,25 @@ public:
int64_t m_iNumNodes; // +0x1070
CAI_Node** m_pAInode; // +0x1078
};
void CAI_Network_Attach();
void CAI_Network_Detach();
namespace
{
ADDRESS p_CAI_Network__DebugConnectMsg = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x4C\x24\x00\x48\x83\xEC\x18", "xxxx?xxxx");
void (*v_CAI_Network__DebugConnectMsg)(int node1, int node2, const char* pszFormat, ...) = (void (*)(int, int, const char*, ...))p_CAI_Network__DebugConnectMsg.GetPtr(); /*4C 89 4C 24 ? 48 83 EC 18*/
}
///////////////////////////////////////////////////////////////////////////////
class HAI_Network : public IDetour
{
virtual void debugp()
{
std::cout << "| FUN: CAI_Network::DebugConnectMsg : 0x" << std::hex << std::uppercase << p_CAI_Network__DebugConnectMsg.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
}
};
///////////////////////////////////////////////////////////////////////////////
REGISTER(HAI_Network);

View File

@ -133,7 +133,7 @@ void CAI_NetworkBuilder::SaveNetworkGraph(CAI_Network* pNetwork)
DevMsg(eDLL_T::SERVER, " |-- Calculated linkcount: '%d'\n", nCalculatedLinkcount);
nCalculatedLinkcount /= 2;
if (ai_dumpAINfileFromLoad->GetBool())
if (ai_ainDumpOnLoad->GetBool())
{
if (pNetwork->m_iNumLinks != nCalculatedLinkcount)
{
@ -303,7 +303,7 @@ void HCAI_NetworkManager__LoadNetworkGraph(void* aimanager, void* buf, const cha
CAI_NetworkManager__LoadNetworkGraph(aimanager, buf, filename);
#endif
if (ai_dumpAINfileFromLoad->GetBool())
if (ai_ainDumpOnLoad->GetBool())
{
DevMsg(eDLL_T::SERVER, "Running BuildAINFile for loaded file '%s'\n", filename);
CAI_NetworkBuilder::SaveNetworkGraph(*(CAI_Network**)(reinterpret_cast<char*>(aimanager) + AINETWORK_OFFSET));

View File

@ -26,4 +26,5 @@ sv_visualizetraces "1" // Show native and script related debug tr
//// CAI ////
//////////////////////////
ai_ainRebuildOnMapStart "0" // Whether to rebuild the AI Network graph on level load.
ai_dumpAINfileFromLoad "0" // Whether to dump the parsed AI Network graph file loaded from disk.
ai_ainDumpOnLoad "0" // Whether to dump the parsed AI Network graph file loaded from disk.
ai_ainDebugConnect "1" // Show AI Network graph connection debug.

View File

@ -55,7 +55,8 @@ void ConVar::Init(void) const
rcon_password = new ConVar("rcon_password", "" , FCVAR_SERVER_CANNOT_QUERY | FCVAR_DONTRECORD | FCVAR_RELEASE, "Remote server access password (rcon is disabled if empty).", false, 0.f, false, 0.f, nullptr, nullptr);
//-------------------------------------------------------------------------
// SERVER |
ai_dumpAINfileFromLoad = new ConVar("ai_dumpAINfileFromLoad" , "0", FCVAR_DEVELOPMENTONLY, "Dumps AIN data from node graphs loaded from the disk on load.", false, 0.f, false, 0.f, nullptr, nullptr);
ai_ainDumpOnLoad = new ConVar("ai_ainDumpOnLoad" , "0", FCVAR_DEVELOPMENTONLY, "Dumps AIN data from node graphs loaded from the disk on load.", false, 0.f, false, 0.f, nullptr, nullptr);
ai_ainDebugConnect = new ConVar("ai_ainDebugConnect" , "0", FCVAR_DEVELOPMENTONLY, "Debug AIN node connections.", false, 0.f, false, 0.f, nullptr, nullptr);
navmesh_always_reachable = new ConVar("navmesh_always_reachable" , "1", FCVAR_DEVELOPMENTONLY, "Marks poly from agent to target on navmesh as reachable regardless of table data ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); // !TODO: Default to '0' once the reachability table gets properly parsed.
sv_showconnecting = new ConVar("sv_showconnecting" , "1", FCVAR_RELEASE, "Logs information about the connecting client to the console.", false, 0.f, false, 0.f, nullptr, nullptr);

View File

@ -14,7 +14,8 @@ ConVar* rcon_address = nullptr;
ConVar* rcon_password = nullptr;
//-----------------------------------------------------------------------------
// SERVER |
ConVar* ai_dumpAINfileFromLoad = nullptr;
ConVar* ai_ainDumpOnLoad = nullptr;
ConVar* ai_ainDebugConnect = nullptr;
ConVar* navmesh_always_reachable = nullptr;
ConVar* sv_showconnecting = nullptr;

View File

@ -26,7 +26,8 @@ extern ConVar* rcon_address;
extern ConVar* rcon_password;
//-------------------------------------------------------------------------
// SERVER |
extern ConVar* ai_dumpAINfileFromLoad;
extern ConVar* ai_ainDumpOnLoad;
extern ConVar* ai_ainDebugConnect;
extern ConVar* navmesh_always_reachable;
extern ConVar* sv_showconnecting;
extern ConVar* sv_pylonvisibility;

View File

@ -68,7 +68,7 @@ void bf_write::SetOverflowFlag()
{
if (this->m_bAssertOnOverflow)
{
Assert(false);
assert(false);
}
this->m_bOverflow = true;

View File

@ -379,6 +379,7 @@
<ClCompile Include="..\engine\sys_dll2.cpp" />
<ClCompile Include="..\engine\sys_engine.cpp" />
<ClCompile Include="..\engine\sys_utils.cpp" />
<ClCompile Include="..\game\server\ai_network.cpp" />
<ClCompile Include="..\game\server\ai_networkmanager.cpp" />
<ClCompile Include="..\game\server\ai_utility.cpp" />
<ClCompile Include="..\game\server\gameinterface.cpp" />

View File

@ -1034,6 +1034,9 @@
<ClCompile Include="..\client\vengineclient_impl.cpp">
<Filter>sdk\client</Filter>
</ClCompile>
<ClCompile Include="..\game\server\ai_network.cpp">
<Filter>sdk\game\server</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\Dedicated.def" />

View File

@ -44,6 +44,7 @@
<ClCompile Include="..\engine\sys_utils.cpp" />
<ClCompile Include="..\gameui\IConsole.cpp" />
<ClCompile Include="..\gameui\IBrowser.cpp" />
<ClCompile Include="..\game\server\ai_network.cpp" />
<ClCompile Include="..\game\server\ai_networkmanager.cpp" />
<ClCompile Include="..\game\server\ai_utility.cpp" />
<ClCompile Include="..\game\server\gameinterface.cpp" />

View File

@ -420,6 +420,9 @@
<ClCompile Include="..\tier1\bitbuf.cpp">
<Filter>sdk\tier1</Filter>
</ClCompile>
<ClCompile Include="..\game\server\ai_network.cpp">
<Filter>sdk\game\server</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\cdll_engine_int.h">