diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index cdd7a895..09129dae 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -61,6 +61,8 @@ bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late) g_CallHandle = handlesys->CreateType("ValveCall", this, 0, NULL, NULL, myself->GetIdentity(), NULL); + ConCommandBaseMgr::OneTimeInit(this); + return true; } @@ -133,3 +135,8 @@ void SDKTools::NotifyInterfaceDrop(SMInterface *pInterface) g_TEManager.Shutdown(); } + +bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar) +{ + return g_SMAPI->RegisterConCmdBase(g_PLAPI, pVar); +} diff --git a/extensions/sdktools/extension.h b/extensions/sdktools/extension.h index 191ed3d1..d35d57e6 100644 --- a/extensions/sdktools/extension.h +++ b/extensions/sdktools/extension.h @@ -34,16 +34,20 @@ #include #include #include +#include /** * @brief Implementation of the SDK Tools extension. * Note: Uncomment one of the pre-defined virtual functions in order to use it. */ -class SDKTools : public SDKExtension, public IHandleTypeDispatch +class SDKTools : + public SDKExtension, + public IHandleTypeDispatch, + public IConCommandBaseAccessor { -public: +public: //public IHandleTypeDispatch void OnHandleDestroy(HandleType_t type, void *object); -public: +public: //public SDKExtension virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); virtual void SDK_OnUnload(); virtual void SDK_OnAllLoaded(); @@ -57,6 +61,8 @@ public: //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlen); //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen); #endif +public: //IConCommandBaseAccessor + bool RegisterConCommandBase(ConCommandBase *pVar); }; extern IServerGameEnts *gameents; diff --git a/extensions/sdktools/tempents.cpp b/extensions/sdktools/tempents.cpp index 4d7f6c12..feca8fad 100644 --- a/extensions/sdktools/tempents.cpp +++ b/extensions/sdktools/tempents.cpp @@ -26,6 +26,42 @@ TempEntityManager g_TEManager; ICallWrapper *g_GetServerClass = NULL; +CON_COMMAND(sm_print_telist, "Prints the temp entity list") +{ + if (!g_TEManager.IsAvailable()) + { + META_CONPRINT("The tempent portion of SDKTools failed to load.\n"); + META_CONPRINT("Check that you have the latest sdktools.games.txt file!\n"); + return; + } + g_TEManager.DumpList(); +} + +CON_COMMAND(sm_dump_teprops, "Dumps tempentity props to a file") +{ + if (!g_TEManager.IsAvailable()) + { + META_CONPRINT("The tempent portion of SDKTools failed to load.\n"); + META_CONPRINT("Check that you have the latest sdktools.games.txt file!\n"); + return; + } + int argc = engine->Cmd_Argc(); + if (argc < 2) + { + META_CONPRINT("Usage: sm_dump_teprops \n"); + return; + } + const char *arg = engine->Cmd_Argv(1); + FILE *fp = NULL; + if (!arg || arg[0] == '\0' || ((fp = fopen(arg, "wt")) == NULL)) + { + META_CONPRINTF("Could not open file \"%s\"\n", arg); + return; + } + g_TEManager.DumpProps(fp); + fclose(fp); +} + /************************* * * * Temp Entities Wrappers * @@ -44,6 +80,11 @@ const char *TempEntityInfo::GetName() return m_Name.c_str(); } +ServerClass *TempEntityInfo::GetServerClass() +{ + return m_Sc; +} + bool TempEntityInfo::IsValidProp(const char *name) { return (g_pGameHelpers->FindInSendTable(m_Sc->GetName(), name)) ? true : false; @@ -263,3 +304,95 @@ TempEntityInfo *TempEntityManager::GetTempEntityInfo(const char *name) return te; } + +void TempEntityManager::DumpList() +{ + unsigned int index = 0; + META_CONPRINT("Listing temp entities:\n"); + void *iter = m_ListHead; + while (iter) + { + const char *realname = *(const char **)((unsigned char *)iter + m_NameOffs); + if (!realname) + { + break; + } + TempEntityInfo *info = GetTempEntityInfo(realname); + if (!info) + { + continue; + } + ServerClass *sc = info->GetServerClass(); + META_CONPRINTF("[%02d] %s (%s)\n", index++, realname, sc->GetName()); + iter = *(void **)((unsigned char *)iter + m_NextOffs); + } + META_CONPRINTF("%d tempent%s found.\n", index, (index == 1) ? " was" : "s were"); +} + +const char *SendPropTypeToString(SendPropType type) +{ + if (type == DPT_Int) + { + return "int"; + } else if (type == DPT_Float) { + return "float"; + } else if (type == DPT_Vector) { + return "vector"; + } else if (type == DPT_String) { + return "string"; + } else if (type == DPT_Array) { + return "array"; + } else if (type == DPT_DataTable) { + return "datatable"; + } else { + return "unknown"; + } +} + +void _DumpProps(FILE *fp, SendTable *pTable) +{ + SendTable *pOther; + for (int i=0; iGetNumProps(); i++) + { + SendProp *prop = pTable->GetProp(i); + if ((pOther = prop->GetDataTable()) != NULL) + { + _DumpProps(fp, pOther); + } else { + fprintf(fp, "\t\t\t\"%s\"\t\t\"%s\"\n", + prop->GetName() ? prop->GetName() : "unknown", + SendPropTypeToString(prop->GetType())); + } + } +} + +void TempEntityManager::DumpProps(FILE *fp) +{ + unsigned int index = 0; + void *iter = m_ListHead; + fprintf(fp, "\"TempEnts\"\n{\n"); + while (iter) + { + const char *realname = *(const char **)((unsigned char *)iter + m_NameOffs); + if (!realname) + { + break; + } + TempEntityInfo *info = GetTempEntityInfo(realname); + if (!info) + { + continue; + } + ServerClass *sc = info->GetServerClass(); + fprintf(fp, "\t\"%s\"\n", sc->GetName()); + fprintf(fp, "\t{\n"); + fprintf(fp, "\t\t\"name\"\t\t\"%s\"\n", realname); + fprintf(fp, "\t\t\"index\"\t\t\"%d\"\n", index++); + fprintf(fp, "\t\t\"SendTable\"\n\t\t{\n"); + _DumpProps(fp, sc->m_pTable); + fprintf(fp, "\t\t}\n\t}\n"); + iter = *(void **)((unsigned char *)iter + m_NextOffs); + } + fprintf(fp, "}\n"); + META_CONPRINTF("%d tempent%s written to file.\n", index, (index == 1) ? " was" : "s were"); +} diff --git a/extensions/sdktools/tempents.h b/extensions/sdktools/tempents.h index f294be4f..68d7c2a3 100644 --- a/extensions/sdktools/tempents.h +++ b/extensions/sdktools/tempents.h @@ -28,6 +28,7 @@ #include #include #include +#include using namespace SourceHook; @@ -37,6 +38,7 @@ public: TempEntityInfo(const char *name, void *me); public: const char *GetName(); + ServerClass *GetServerClass(); bool IsValidProp(const char *name); bool TE_SetEntData(const char *name, int value); bool TE_SetEntDataFloat(const char *name, float value); @@ -61,6 +63,9 @@ public: void Shutdown(); public: TempEntityInfo *GetTempEntityInfo(const char *name); +public: + void DumpList(); + void DumpProps(FILE *fp); private: List m_TEList; IBasicTrie *m_TempEntInfo;