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 #ifndef CLIENT_DLL
CAI_Utility_Attach(); CAI_Utility_Attach();
CAI_Network_Attach();
CAI_NetworkManager_Attach(); CAI_NetworkManager_Attach();
#endif // !#ifndef CLIENT_DLL #endif // !#ifndef CLIENT_DLL
// Patch instructions // Patch instructions
@ -271,6 +272,7 @@ void Systems_Shutdown()
#ifndef CLIENT_DLL #ifndef CLIENT_DLL
CAI_Utility_Detach(); CAI_Utility_Detach();
CAI_Network_Detach();
CAI_NetworkManager_Detach(); CAI_NetworkManager_Detach();
#endif // !CLIENT_DLL #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 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: public:
void* m_pVTable; // <-- 'this'. void* m_pVTable; // <-- 'this'.
@ -30,3 +43,25 @@ public:
int64_t m_iNumNodes; // +0x1070 int64_t m_iNumNodes; // +0x1070
CAI_Node** m_pAInode; // +0x1078 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); DevMsg(eDLL_T::SERVER, " |-- Calculated linkcount: '%d'\n", nCalculatedLinkcount);
nCalculatedLinkcount /= 2; nCalculatedLinkcount /= 2;
if (ai_dumpAINfileFromLoad->GetBool()) if (ai_ainDumpOnLoad->GetBool())
{ {
if (pNetwork->m_iNumLinks != nCalculatedLinkcount) 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); CAI_NetworkManager__LoadNetworkGraph(aimanager, buf, filename);
#endif #endif
if (ai_dumpAINfileFromLoad->GetBool()) if (ai_ainDumpOnLoad->GetBool())
{ {
DevMsg(eDLL_T::SERVER, "Running BuildAINFile for loaded file '%s'\n", filename); DevMsg(eDLL_T::SERVER, "Running BuildAINFile for loaded file '%s'\n", filename);
CAI_NetworkBuilder::SaveNetworkGraph(*(CAI_Network**)(reinterpret_cast<char*>(aimanager) + AINETWORK_OFFSET)); 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 //// //// CAI ////
////////////////////////// //////////////////////////
ai_ainRebuildOnMapStart "0" // Whether to rebuild the AI Network graph on level load. 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); 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 | // 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. 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); 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; ConVar* rcon_password = nullptr;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// SERVER | // SERVER |
ConVar* ai_dumpAINfileFromLoad = nullptr; ConVar* ai_ainDumpOnLoad = nullptr;
ConVar* ai_ainDebugConnect = nullptr;
ConVar* navmesh_always_reachable = nullptr; ConVar* navmesh_always_reachable = nullptr;
ConVar* sv_showconnecting = nullptr; ConVar* sv_showconnecting = nullptr;

View File

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

View File

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

View File

@ -379,6 +379,7 @@
<ClCompile Include="..\engine\sys_dll2.cpp" /> <ClCompile Include="..\engine\sys_dll2.cpp" />
<ClCompile Include="..\engine\sys_engine.cpp" /> <ClCompile Include="..\engine\sys_engine.cpp" />
<ClCompile Include="..\engine\sys_utils.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_networkmanager.cpp" />
<ClCompile Include="..\game\server\ai_utility.cpp" /> <ClCompile Include="..\game\server\ai_utility.cpp" />
<ClCompile Include="..\game\server\gameinterface.cpp" /> <ClCompile Include="..\game\server\gameinterface.cpp" />

View File

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

View File

@ -44,6 +44,7 @@
<ClCompile Include="..\engine\sys_utils.cpp" /> <ClCompile Include="..\engine\sys_utils.cpp" />
<ClCompile Include="..\gameui\IConsole.cpp" /> <ClCompile Include="..\gameui\IConsole.cpp" />
<ClCompile Include="..\gameui\IBrowser.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_networkmanager.cpp" />
<ClCompile Include="..\game\server\ai_utility.cpp" /> <ClCompile Include="..\game\server\ai_utility.cpp" />
<ClCompile Include="..\game\server\gameinterface.cpp" /> <ClCompile Include="..\game\server\gameinterface.cpp" />

View File

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