Add sm_dump_datamaps_xml (#1409)
This commit is contained in:
parent
1a11d92fd9
commit
6c2be9bdcc
@ -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<subtable name='%s' offset='%d' classname='%s' deep='%d'>\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</subtable>\n", spaces);
|
||||
}
|
||||
else
|
||||
{
|
||||
externalname = pMap->dataDesc[i].externalName;
|
||||
flags = UTIL_DataFlagsToString(pMap->dataDesc[i].flags);
|
||||
|
||||
fprintf(fp, " %s<datamap name='%s'>\n", spaces, pMap->dataDesc[i].fieldName);
|
||||
fprintf(fp, " %s<offset>%d</offset>\n", spaces, GetTypeDescOffs(&pMap->dataDesc[i]));
|
||||
fprintf(fp, " %s<flags>%s</flags>\n", spaces, flags);
|
||||
fprintf(fp, " %s<bytes>%d</bytes>\n", spaces, pMap->dataDesc[i].fieldSizeInBytes);
|
||||
if (externalname != NULL)
|
||||
{
|
||||
fprintf(fp, " %s<external>%s</external>\n", spaces, externalname);
|
||||
}
|
||||
|
||||
fprintf(fp, " %s</datamap>\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 <file>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *file = args.Arg(1);
|
||||
if (!file || file[0] == '\0')
|
||||
{
|
||||
META_CONPRINT("Usage: sm_dump_datamaps_xml <file>\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, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
|
||||
|
||||
fprintf(fp, "<!-- Dump of all datamaps for \"%s\" as at %s -->\n\n\n", g_pSM->GetGameFolderName(), buffer);
|
||||
|
||||
|
||||
fprintf(fp, "<!-- Flag Details: -->\n\n");
|
||||
|
||||
fprintf(fp, "<!-- Global: This field is masked for global entity save/restore -->\n");
|
||||
fprintf(fp, "<!-- Save: This field is saved to disk -->\n");
|
||||
fprintf(fp, "<!-- Key: This field can be requested and written to by string name at load time -->\n");
|
||||
fprintf(fp, "<!-- Input: This field can be written to by string name at run time, and a function called -->\n");
|
||||
fprintf(fp, "<!-- Output: This field propogates it's value to all targets whenever it changes -->\n");
|
||||
fprintf(fp, "<!-- FunctionTable: This is a table entry for a member function pointer -->\n");
|
||||
fprintf(fp, "<!-- Ptr: This field is a pointer, not an embedded object -->\n");
|
||||
fprintf(fp, "<!-- Override: The field is an override for one in a base class (only used by prediction system for now) -->\n");
|
||||
|
||||
fprintf(fp, "\n\n");
|
||||
|
||||
fprintf(fp, "<datamaps>\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, " <serverclass name='%s' element='%s'>\n", sclass->GetName(), dict->m_Factories.GetElementName(i));
|
||||
|
||||
UTIL_DrawDataTable_XML(fp, pMap, 1);
|
||||
|
||||
fprintf(fp, " </serverclass>\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, "</datamaps>\n");
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user