1.1 --- a/extensions/sdktools/vhelpers.cpp Mon Mar 31 22:44:18 2008 +0000
1.2 +++ b/extensions/sdktools/vhelpers.cpp Mon Mar 31 23:13:31 2008 +0000
1.3 @@ -614,4 +614,220 @@
1.4
1.5 }
1.6
1.7 +char *UTIL_FlagsToString(int flags)
1.8 +{
1.9 + static char str[1024];
1.10 + str[0] = 0;
1.11
1.12 + if (flags & FTYPEDESC_GLOBAL)
1.13 + {
1.14 + strcat(str, "Global|");
1.15 + }
1.16 + if (flags & FTYPEDESC_SAVE)
1.17 + {
1.18 + strcat(str, "Save|");
1.19 + }
1.20 + if (flags & FTYPEDESC_KEY)
1.21 + {
1.22 + strcat(str, "Key|");
1.23 + }
1.24 + if (flags & FTYPEDESC_INPUT)
1.25 + {
1.26 + strcat(str, "Input|");
1.27 + }
1.28 + if (flags & FTYPEDESC_OUTPUT)
1.29 + {
1.30 + strcat(str, "Output|");
1.31 + }
1.32 + if (flags & FTYPEDESC_FUNCTIONTABLE)
1.33 + {
1.34 + strcat(str, "FunctionTable|");
1.35 + }
1.36 + if (flags & FTYPEDESC_PTR)
1.37 + {
1.38 + strcat(str, "Ptr|");
1.39 + }
1.40 + if (flags & FTYPEDESC_OVERRIDE)
1.41 + {
1.42 + strcat(str, "Override|");
1.43 + }
1.44 +
1.45 + int len = strlen(str) - 1;
1.46 + if (len > 0)
1.47 + {
1.48 + str[len] = 0; // Strip the final '|'
1.49 + }
1.50 +
1.51 + return str;
1.52 +}
1.53 +
1.54 +void UTIL_DrawDataTable(FILE *fp, datamap_t *pMap, int level)
1.55 +{
1.56 + char spaces[255];
1.57 +
1.58 + for (int i=0; i<level; i++)
1.59 + {
1.60 + spaces[i] = ' ';
1.61 + }
1.62 +
1.63 + spaces[level] = '\0';
1.64 +
1.65 + const char *externalname;
1.66 + char *flags;
1.67 +
1.68 + while (pMap)
1.69 + {
1.70 + for (int i=0; i<pMap->dataNumFields; i++)
1.71 + {
1.72 + if (pMap->dataDesc[i].fieldName == NULL)
1.73 + {
1.74 + continue;
1.75 + }
1.76 +
1.77 + if (pMap->dataDesc[i].td)
1.78 + {
1.79 + fprintf(fp, " %sSub-Class Table (%d Deep): %s - %s\n", spaces, level+1, pMap->dataDesc[i].fieldName, pMap->dataDesc[i].td->dataClassName);
1.80 + UTIL_DrawDataTable(fp, pMap->dataDesc[i].td, level+1);
1.81 + }
1.82 + else
1.83 + {
1.84 + externalname = pMap->dataDesc[i].externalName;
1.85 + flags = UTIL_FlagsToString(pMap->dataDesc[i].flags);
1.86 +
1.87 + if (externalname == NULL)
1.88 + {
1.89 + fprintf(fp,"%s- %s (%s)(%i Bytes)\n", spaces, pMap->dataDesc[i].fieldName, flags, pMap->dataDesc[i].fieldSizeInBytes);
1.90 + }
1.91 + else
1.92 + {
1.93 + fprintf(fp,"%s- %s (%s)(%i Bytes) - %s\n", spaces, pMap->dataDesc[i].fieldName, flags, pMap->dataDesc[i].fieldSizeInBytes, externalname);
1.94 + }
1.95 + }
1.96 + }
1.97 + pMap = pMap->baseMap;
1.98 + }
1.99 +}
1.100 +
1.101 +CON_COMMAND(sm_dump_datamaps, "Dumps the data map list as a text file")
1.102 +{
1.103 +#if !defined ORANGEBOX_BUILD
1.104 + CCommand args;
1.105 +#endif
1.106 +
1.107 + if (args.ArgC() < 2)
1.108 + {
1.109 + META_CONPRINT("Usage: sm_dump_datamaps <file>\n");
1.110 + return;
1.111 + }
1.112 +
1.113 + const char *file = args.Arg(1);
1.114 + if (!file || file[0] == '\0')
1.115 + {
1.116 + META_CONPRINT("Usage: sm_dump_datamaps <file>\n");
1.117 + return;
1.118 + }
1.119 +
1.120 + ICallWrapper *pWrapper = NULL;
1.121 +
1.122 + if (!pWrapper)
1.123 + {
1.124 + PassInfo retData;
1.125 + retData.flags = PASSFLAG_BYVAL;
1.126 + retData.size = sizeof(void *);
1.127 + retData.type = PassType_Basic;
1.128 +
1.129 + void *addr;
1.130 + if (!g_pGameConf->GetMemSig("EntityFactory", &addr) || addr == NULL)
1.131 + {
1.132 + META_CONPRINT("Failed to locate function\n");
1.133 + return;
1.134 + }
1.135 +
1.136 + pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retData, NULL, 0);
1.137 + }
1.138 +
1.139 +
1.140 + void *returnData = NULL;
1.141 +
1.142 + pWrapper->Execute(NULL, &returnData);
1.143 +
1.144 + pWrapper->Destroy();
1.145 +
1.146 + if (returnData == NULL)
1.147 + {
1.148 + return;
1.149 + }
1.150 +
1.151 + CEntityFactoryDictionary *dict = ( CEntityFactoryDictionary * )returnData;
1.152 +
1.153 + if ( !dict )
1.154 + {
1.155 + return;
1.156 + }
1.157 +
1.158 + char path[PLATFORM_MAX_PATH];
1.159 + g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
1.160 +
1.161 + FILE *fp = NULL;
1.162 + if ((fp = fopen(path, "wt")) == NULL)
1.163 + {
1.164 + META_CONPRINTF("Could not open file \"%s\"\n", path);
1.165 + return;
1.166 + }
1.167 +
1.168 + char buffer[80];
1.169 + buffer[0] = 0;
1.170 +
1.171 +#if defined SUBPLATFORM_SECURECRT
1.172 + _invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter);
1.173 +#endif
1.174 +
1.175 + time_t t = g_pSM->GetAdjustedTime();
1.176 + size_t written = strftime(buffer, sizeof(buffer), "%d/%m/%Y", localtime(&t));
1.177 +
1.178 +#if defined SUBPLATFORM_SECURECRT
1.179 + _set_invalid_parameter_handler(handler);
1.180 +#endif
1.181 +
1.182 + fprintf(fp, "// Dump of all datamaps for \"%s\" as at %s\n//\n//\n", g_pSM->GetGameFolderName(), buffer);
1.183 +
1.184 +
1.185 + fprintf(fp, "// Flag Details:\n//\n");
1.186 +
1.187 + fprintf(fp, "// Global: This field is masked for global entity save/restore\n");
1.188 + fprintf(fp, "// Save: This field is saved to disk\n");
1.189 + fprintf(fp, "// Key: This field can be requested and written to by string name at load time\n");
1.190 + fprintf(fp, "// Input: This field can be written to by string name at run time, and a function called\n");
1.191 + fprintf(fp, "// Output: This field propogates it's value to all targets whenever it changes\n");
1.192 + fprintf(fp, "// FunctionTable: This is a table entry for a member function pointer\n");
1.193 + fprintf(fp, "// Ptr: This field is a pointer, not an embedded object\n");
1.194 + fprintf(fp, "// Override: The field is an override for one in a base class (only used by prediction system for now)\n");
1.195 +
1.196 + fprintf(fp, "//\n\n");
1.197 +
1.198 + for ( int i = dict->m_Factories.First(); i != dict->m_Factories.InvalidIndex(); i = dict->m_Factories.Next( i ) )
1.199 + {
1.200 + IServerNetworkable *entity = dict->Create(dict->m_Factories.GetElementName(i));
1.201 + ServerClass *sclass = entity->GetServerClass();
1.202 + datamap_t *pMap = gamehelpers->GetDataMap(entity->GetBaseEntity());
1.203 +
1.204 + fprintf(fp,"%s - %s\n", sclass->GetName(), dict->m_Factories.GetElementName(i));
1.205 +
1.206 + UTIL_DrawDataTable(fp, pMap, 0);
1.207 +
1.208 + typedescription_t *datamap = gamehelpers->FindInDataMap(pMap), "m_iEFlags");
1.209 +
1.210 + int *eflags = (int *)((char *)entity->GetBaseEntity() + datamap->fieldOffset[TD_OFFSET_NORMAL]);
1.211 + *eflags |= (1<<0); // EFL_KILLME
1.212 + }
1.213 +
1.214 + fclose(fp);
1.215 +
1.216 +}
1.217 +
1.218 +
1.219 +
1.220 +
1.221 +
1.222 +
1.223 +