diff --git a/extensions/sdktools/vhelpers.cpp b/extensions/sdktools/vhelpers.cpp index 24e5524b..187a15ae 100644 --- a/extensions/sdktools/vhelpers.cpp +++ b/extensions/sdktools/vhelpers.cpp @@ -940,3 +940,154 @@ CON_COMMAND(sm_dump_datamaps, "Dumps the data map list as a text file") fclose(fp); } + +void UTIL_DrawDataTable_XML(FILE *fp, datamap_t *pMap, int level) +{ + char spaces[255]; + + for (int i = 0; i < level; i++) + { + spaces[i] = ' '; + } + + spaces[level] = '\0'; + + const char *externalname; + char *flags; + + while (pMap) + { + for (int i = 0; i < pMap->dataNumFields; i++) + { + if (pMap->dataDesc[i].fieldName == NULL) + { + continue; + } + + if (pMap->dataDesc[i].td) + { + fprintf(fp, " %s\n", spaces, pMap->dataDesc[i].fieldName, GetTypeDescOffs(&pMap->dataDesc[i]), pMap->dataDesc[i].td->dataClassName, level + 1); + UTIL_DrawDataTable_XML(fp, pMap->dataDesc[i].td, level + 1); + fprintf(fp, " %s\n", spaces); + } + else + { + externalname = pMap->dataDesc[i].externalName; + flags = UTIL_DataFlagsToString(pMap->dataDesc[i].flags); + + fprintf(fp, " %s\n", spaces, pMap->dataDesc[i].fieldName); + fprintf(fp, " %s%d\n", spaces, GetTypeDescOffs(&pMap->dataDesc[i])); + fprintf(fp, " %s%s\n", spaces, flags); + fprintf(fp, " %s%d\n", spaces, pMap->dataDesc[i].fieldSizeInBytes); + if (externalname != NULL) + { + fprintf(fp, " %s%s\n", spaces, externalname); + } + + fprintf(fp, " %s\n", spaces); + } + } + pMap = pMap->baseMap; + } +} + +CON_COMMAND(sm_dump_datamaps_xml, "Dumps the data map list as an XML file") +{ +#if SOURCE_ENGINE <= SE_DARKMESSIAH + CCommand args; +#endif + + if (args.ArgC() < 2) + { + META_CONPRINT("Usage: sm_dump_datamaps_xml \n"); + return; + } + + const char *file = args.Arg(1); + if (!file || file[0] == '\0') + { + META_CONPRINT("Usage: sm_dump_datamaps_xml \n"); + return; + } + + CEntityFactoryDictionary *dict = GetEntityFactoryDictionary(); + if (dict == NULL) + { + META_CONPRINT("Failed to locate function\n"); + return; + } + + char path[PLATFORM_MAX_PATH]; + g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file); + + FILE *fp = NULL; + if ((fp = fopen(path, "wt")) == NULL) + { + META_CONPRINTF("Could not open file \"%s\"\n", path); + return; + } + + char buffer[80]; + buffer[0] = 0; + + time_t t = g_pSM->GetAdjustedTime(); + size_t written = 0; + { +#ifdef PLATFORM_WINDOWS + InvalidParameterHandler p; +#endif + written = strftime(buffer, sizeof(buffer), "%Y/%m/%d", localtime(&t)); + } + + fprintf(fp, "\n\n"); + + fprintf(fp, "\n\n\n", g_pSM->GetGameFolderName(), buffer); + + + fprintf(fp, "\n\n"); + + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fprintf(fp, "\n"); + fprintf(fp, "\n"); + + fprintf(fp, "\n\n"); + + fprintf(fp, "\n"); + + static int offsEFlags = -1; + for (int i = dict->m_Factories.First(); i != dict->m_Factories.InvalidIndex(); i = dict->m_Factories.Next(i)) + { + IServerNetworkable *entity = dict->Create(dict->m_Factories.GetElementName(i)); + ServerClass *sclass = entity->GetServerClass(); + datamap_t *pMap = gamehelpers->GetDataMap(entity->GetBaseEntity()); + + fprintf(fp, " \n", sclass->GetName(), dict->m_Factories.GetElementName(i)); + + UTIL_DrawDataTable_XML(fp, pMap, 1); + + fprintf(fp, " \n"); + + if (offsEFlags == -1) + { + sm_datatable_info_t info; + if (!gamehelpers->FindDataMapInfo(pMap, "m_iEFlags", &info)) + { + continue; + } + + offsEFlags = info.actual_offset; + } + + int *eflags = (int *)((char *)entity->GetBaseEntity() + offsEFlags); + *eflags |= (1 << 0); // EFL_KILLME + } + + fprintf(fp, "\n"); + + fclose(fp); +}