summaryrefslogtreecommitdiff
path: root/game/server/saverestore_gamedll.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/saverestore_gamedll.cpp')
-rw-r--r--game/server/saverestore_gamedll.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/game/server/saverestore_gamedll.cpp b/game/server/saverestore_gamedll.cpp
new file mode 100644
index 0000000..768262e
--- /dev/null
+++ b/game/server/saverestore_gamedll.cpp
@@ -0,0 +1,241 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "isaverestore.h"
+#include "saverestoretypes.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: iterates through a typedescript data block, so it can insert key/value data into the block
+// Input : *pObject - pointer to the struct or class the data is to be insterted into
+// *pFields - description of the data
+// iNumFields - number of fields contained in pFields
+// char *szKeyName - name of the variable to look for
+// char *szValue - value to set the variable to
+// Output : Returns true if the variable is found and set, false if the key is not found.
+//-----------------------------------------------------------------------------
+bool ParseKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, const char *szKeyName, const char *szValue )
+{
+ int i;
+ typedescription_t *pField;
+
+ for ( i = 0; i < iNumFields; i++ )
+ {
+ pField = &pFields[i];
+
+ int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ];
+
+ // Check the nested classes, but only if they aren't in array form.
+ if ((pField->fieldType == FIELD_EMBEDDED) && (pField->fieldSize == 1))
+ {
+ for ( datamap_t *dmap = pField->td; dmap != NULL; dmap = dmap->baseMap )
+ {
+ void *pEmbeddedObject = (void*)((char*)pObject + fieldOffset);
+ if ( ParseKeyvalue( pEmbeddedObject, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue) )
+ return true;
+ }
+ }
+
+ if ( (pField->flags & FTYPEDESC_KEY) && !stricmp(pField->externalName, szKeyName) )
+ {
+ switch( pField->fieldType )
+ {
+ case FIELD_MODELNAME:
+ case FIELD_SOUNDNAME:
+ case FIELD_STRING:
+ (*(string_t *)((char *)pObject + fieldOffset)) = AllocPooledString( szValue );
+ return true;
+
+ case FIELD_TIME:
+ case FIELD_FLOAT:
+ (*(float *)((char *)pObject + fieldOffset)) = atof( szValue );
+ return true;
+
+ case FIELD_BOOLEAN:
+ (*(bool *)((char *)pObject + fieldOffset)) = (bool)(atoi( szValue ) != 0);
+ return true;
+
+ case FIELD_CHARACTER:
+ (*(char *)((char *)pObject + fieldOffset)) = (char)atoi( szValue );
+ return true;
+
+ case FIELD_SHORT:
+ (*(short *)((char *)pObject + fieldOffset)) = (short)atoi( szValue );
+ return true;
+
+ case FIELD_INTEGER:
+ case FIELD_TICK:
+ (*(int *)((char *)pObject + fieldOffset)) = atoi( szValue );
+ return true;
+
+ case FIELD_POSITION_VECTOR:
+ case FIELD_VECTOR:
+ UTIL_StringToVector( (float *)((char *)pObject + fieldOffset), szValue );
+ return true;
+
+ case FIELD_VMATRIX:
+ case FIELD_VMATRIX_WORLDSPACE:
+ UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue );
+ return true;
+
+ case FIELD_MATRIX3X4_WORLDSPACE:
+ UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue );
+ return true;
+
+ case FIELD_COLOR32:
+ UTIL_StringToColor32( (color32 *) ((char *)pObject + fieldOffset), szValue );
+ return true;
+
+ case FIELD_CUSTOM:
+ {
+ SaveRestoreFieldInfo_t fieldInfo =
+ {
+ (char *)pObject + fieldOffset,
+ pObject,
+ pField
+ };
+ pField->pSaveRestoreOps->Parse( fieldInfo, szValue );
+ return true;
+ }
+
+ default:
+ case FIELD_INTERVAL: // Fixme, could write this if needed
+ case FIELD_CLASSPTR:
+ case FIELD_MODELINDEX:
+ case FIELD_MATERIALINDEX:
+ case FIELD_EDICT:
+ Warning( "Bad field in entity!!\n" );
+ Assert(0);
+ break;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: iterates through a typedescript data block, so it can insert key/value data into the block
+// Input : *pObject - pointer to the struct or class the data is to be insterted into
+// *pFields - description of the data
+// iNumFields - number of fields contained in pFields
+// char *szKeyName - name of the variable to look for
+// char *szValue - value to set the variable to
+// Output : Returns true if the variable is found and set, false if the key is not found.
+//-----------------------------------------------------------------------------
+bool ExtractKeyvalue( void *pObject, typedescription_t *pFields, int iNumFields, const char *szKeyName, char *szValue, int iMaxLen )
+{
+ int i;
+ typedescription_t *pField;
+
+ for ( i = 0; i < iNumFields; i++ )
+ {
+ pField = &pFields[i];
+
+ int fieldOffset = pField->fieldOffset[ TD_OFFSET_NORMAL ];
+
+ // Check the nested classes, but only if they aren't in array form.
+ if ((pField->fieldType == FIELD_EMBEDDED) && (pField->fieldSize == 1))
+ {
+ for ( datamap_t *dmap = pField->td; dmap != NULL; dmap = dmap->baseMap )
+ {
+ void *pEmbeddedObject = (void*)((char*)pObject + fieldOffset);
+ if ( ExtractKeyvalue( pEmbeddedObject, dmap->dataDesc, dmap->dataNumFields, szKeyName, szValue, iMaxLen ) )
+ return true;
+ }
+ }
+
+ if ( (pField->flags & FTYPEDESC_KEY) && !stricmp(pField->externalName, szKeyName) )
+ {
+ switch( pField->fieldType )
+ {
+ case FIELD_MODELNAME:
+ case FIELD_SOUNDNAME:
+ case FIELD_STRING:
+ Q_strncpy( szValue, ((char *)pObject + fieldOffset), iMaxLen );
+ return true;
+
+ case FIELD_TIME:
+ case FIELD_FLOAT:
+ Q_snprintf( szValue, iMaxLen, "%f", (*(float *)((char *)pObject + fieldOffset)) );
+ return true;
+
+ case FIELD_BOOLEAN:
+ Q_snprintf( szValue, iMaxLen, "%d", (*(bool *)((char *)pObject + fieldOffset)) != 0);
+ return true;
+
+ case FIELD_CHARACTER:
+ Q_snprintf( szValue, iMaxLen, "%d", (*(char *)((char *)pObject + fieldOffset)) );
+ return true;
+
+ case FIELD_SHORT:
+ Q_snprintf( szValue, iMaxLen, "%d", (*(short *)((char *)pObject + fieldOffset)) );
+ return true;
+
+ case FIELD_INTEGER:
+ case FIELD_TICK:
+ Q_snprintf( szValue, iMaxLen, "%d", (*(int *)((char *)pObject + fieldOffset)) );
+ return true;
+
+ case FIELD_POSITION_VECTOR:
+ case FIELD_VECTOR:
+ Q_snprintf( szValue, iMaxLen, "%f %f %f",
+ ((float *)((char *)pObject + fieldOffset))[0],
+ ((float *)((char *)pObject + fieldOffset))[1],
+ ((float *)((char *)pObject + fieldOffset))[2] );
+ return true;
+
+ case FIELD_VMATRIX:
+ case FIELD_VMATRIX_WORLDSPACE:
+ //UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 16, szValue );
+ return false;
+
+ case FIELD_MATRIX3X4_WORLDSPACE:
+ //UTIL_StringToFloatArray( (float *)((char *)pObject + fieldOffset), 12, szValue );
+ return false;
+
+ case FIELD_COLOR32:
+ Q_snprintf( szValue, iMaxLen, "%d %d %d %d",
+ ((int *)((char *)pObject + fieldOffset))[0],
+ ((int *)((char *)pObject + fieldOffset))[1],
+ ((int *)((char *)pObject + fieldOffset))[2],
+ ((int *)((char *)pObject + fieldOffset))[3] );
+ return true;
+
+ case FIELD_CUSTOM:
+ {
+ /*
+ SaveRestoreFieldInfo_t fieldInfo =
+ {
+ (char *)pObject + fieldOffset,
+ pObject,
+ pField
+ };
+ pField->pSaveRestoreOps->Parse( fieldInfo, szValue );
+ */
+ return false;
+ }
+
+ default:
+ case FIELD_INTERVAL: // Fixme, could write this if needed
+ case FIELD_CLASSPTR:
+ case FIELD_MODELINDEX:
+ case FIELD_MATERIALINDEX:
+ case FIELD_EDICT:
+ Warning( "Bad field in entity!!\n" );
+ Assert(0);
+ break;
+ }
+ }
+ }
+
+ return false;
+}