diff --git a/core/sm_srvcmds.cpp b/core/sm_srvcmds.cpp index 9e0e9f60..cbacadd0 100644 --- a/core/sm_srvcmds.cpp +++ b/core/sm_srvcmds.cpp @@ -290,6 +290,34 @@ CON_COMMAND(sm, "SourceMod Menu") g_RootMenu.GotRootCmd(args); } +FILE *g_pHndlLog = NULL; + +void write_handles_to_log(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(g_pHndlLog, fmt, ap); + fprintf(g_pHndlLog, "\n"); + va_end(ap); +} + +void write_handles_to_game(const char *fmt, ...) +{ + size_t len; + va_list ap; + char buffer[1024]; + + va_start(ap, fmt); + len = UTIL_FormatArgs(buffer, sizeof(buffer)-2, fmt, ap); + va_end(ap); + + buffer[len] = '\n'; + buffer[len+1] = '\0'; + + engine->LogPrint(buffer); +} + CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks") { #if !defined ORANGEBOX_BUILD @@ -297,19 +325,28 @@ CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle le #endif if (args.ArgC() < 2) { - g_RootMenu.ConsolePrint("Usage: sm_dump_handles "); + g_RootMenu.ConsolePrint("Usage: sm_dump_handles or for game logs"); return; } - const char *arg = args.Arg(1); - FILE *fp = fopen(arg, "wt"); - if (!fp) + if (strcmp(args.Arg(1), "log") != 0) { - g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg); - return; + const char *arg = args.Arg(1); + FILE *fp = fopen(arg, "wt"); + if (!fp) + { + g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg); + return; + } + + g_pHndlLog = fp; + g_HandleSys.Dump(write_handles_to_log); + g_pHndlLog = NULL; + + fclose(fp); + } + else + { + g_HandleSys.Dump(write_handles_to_game); } - - g_HandleSys.Dump(fp); - - fclose(fp); } diff --git a/core/systems/HandleSys.cpp b/core/systems/HandleSys.cpp index 880b5f14..5d0e9885 100644 --- a/core/systems/HandleSys.cpp +++ b/core/systems/HandleSys.cpp @@ -994,10 +994,10 @@ bool HandleSystem::TryAndFreeSomeHandles() return g_PluginSys.UnloadPlugin(highest_owner); } -void HandleSystem::Dump(FILE *fp) +void HandleSystem::Dump(HANDLE_REPORTER rep) { - fprintf(fp, "%-10.10s\t%-20.20s\t%-20.20s\n", "Handle", "Owner", "Type"); - fprintf(fp, "---------------------------------------------\n"); + rep("%-10.10s\t%-20.20s\t%-20.20s", "Handle", "Owner", "Type"); + rep("---------------------------------------------"); for (unsigned int i = 1; i <= m_HandleTail; i++) { if (m_Handles[i].set != HandleSet_Used) @@ -1046,7 +1046,7 @@ void HandleSystem::Dump(FILE *fp) { type = m_strtab->GetString(pType->nameIdx); } - fprintf(fp, "0x%08x\t%-20.20s\t%-20.20s\n", index, owner, type); + rep("0x%08x\t%-20.20s\t%-20.20s", index, owner, type); } } diff --git a/core/systems/HandleSys.h b/core/systems/HandleSys.h index e0ef22b4..c49b1510 100644 --- a/core/systems/HandleSys.h +++ b/core/systems/HandleSys.h @@ -105,6 +105,8 @@ struct QHandleType int nameIdx; }; +typedef void (HANDLE_REPORTER)(const char *str, ...); + class HandleSystem : public IHandleSys { @@ -155,7 +157,7 @@ public: //IHandleSystem const HandleAccess *pAccess, HandleError *err); - void Dump(FILE *fp); + void Dump(HANDLE_REPORTER rep); protected: /** * Decodes a handle with sanity and security checking.