diff options
Diffstat (limited to 'internal_rewrite/Valve')
| -rw-r--r-- | internal_rewrite/Valve/checksum_crc.cpp | 169 | ||||
| -rw-r--r-- | internal_rewrite/Valve/checksum_crc.h | 30 | ||||
| -rw-r--r-- | internal_rewrite/Valve/dt_common.h | 226 | ||||
| -rw-r--r-- | internal_rewrite/Valve/dt_recv.h | 586 |
4 files changed, 1011 insertions, 0 deletions
diff --git a/internal_rewrite/Valve/checksum_crc.cpp b/internal_rewrite/Valve/checksum_crc.cpp new file mode 100644 index 0000000..bc7b433 --- /dev/null +++ b/internal_rewrite/Valve/checksum_crc.cpp @@ -0,0 +1,169 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Generic CRC functions +// +//=============================================================================// + + +#include "checksum_crc.h" + +#define CRC32_INIT_VALUE 0xFFFFFFFFUL +#define CRC32_XOR_VALUE 0xFFFFFFFFUL + +#define NUM_BYTES 256 +static const CRC32_t pulCRCTable[ NUM_BYTES ] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +void CRC32_Init( CRC32_t *pulCRC ) { + *pulCRC = CRC32_INIT_VALUE; +} + +void CRC32_Final( CRC32_t *pulCRC ) { + *pulCRC ^= CRC32_XOR_VALUE; +} + +CRC32_t CRC32_GetTableEntry( unsigned int slot ) { + return pulCRCTable[ ( unsigned char )slot ]; +} + +void CRC32_ProcessBuffer( CRC32_t *pulCRC, const void *pBuffer, int nBuffer ) { + CRC32_t ulCrc = *pulCRC; + unsigned char *pb = ( unsigned char * )pBuffer; + unsigned int nFront; + int nMain; + +JustAfew: + + switch( nBuffer ) { + case 7: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + + case 6: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + + case 5: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + + case 4: + ulCrc ^= *( CRC32_t * )pb; + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + *pulCRC = ulCrc; + return; + + case 3: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + + case 2: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + + case 1: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + + case 0: + *pulCRC = ulCrc; + return; + } + + // We may need to do some alignment work up front, and at the end, so that + // the main loop is aligned and only has to worry about 8 byte at a time. + // + // The low-order two bits of pb and nBuffer in total control the + // upfront work. + // + nFront = ( ( unsigned int )pb ) & 3; + nBuffer -= nFront; + switch( nFront ) { + case 3: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + case 2: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + case 1: + ulCrc = pulCRCTable[ *pb++ ^ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + } + + nMain = nBuffer >> 3; + while( nMain-- ) { + ulCrc ^= *( CRC32_t * )pb ; + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc ^= *( CRC32_t * )( pb + 4 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + ulCrc = pulCRCTable[ ( unsigned char )ulCrc ] ^ ( ulCrc >> 8 ); + pb += 8; + } + + nBuffer &= 7; + goto JustAfew; +} diff --git a/internal_rewrite/Valve/checksum_crc.h b/internal_rewrite/Valve/checksum_crc.h new file mode 100644 index 0000000..356de67 --- /dev/null +++ b/internal_rewrite/Valve/checksum_crc.h @@ -0,0 +1,30 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Generic CRC functions +// +// $NoKeywords: $ +//=============================================================================// +#ifndef CHECKSUM_CRC_H +#define CHECKSUM_CRC_H +#ifdef _WIN32 +#pragma once +#endif + +typedef unsigned int CRC32_t; + +void CRC32_Init( CRC32_t *pulCRC ); +void CRC32_ProcessBuffer( CRC32_t *pulCRC, const void *p, int len ); +void CRC32_Final( CRC32_t *pulCRC ); +CRC32_t CRC32_GetTableEntry( unsigned int slot ); + +inline CRC32_t CRC32_ProcessSingleBuffer( const void *p, int len ) { + CRC32_t crc; + + CRC32_Init( &crc ); + CRC32_ProcessBuffer( &crc, p, len ); + CRC32_Final( &crc ); + + return crc; +} + +#endif // CHECKSUM_CRC_H diff --git a/internal_rewrite/Valve/dt_common.h b/internal_rewrite/Valve/dt_common.h new file mode 100644 index 0000000..9555056 --- /dev/null +++ b/internal_rewrite/Valve/dt_common.h @@ -0,0 +1,226 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef DATATABLE_COMMON_H +#define DATATABLE_COMMON_H + +#ifdef _WIN32 +#pragma once +#endif + +#include <stdio.h> + +#ifdef LINUX +#undef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + +// Max number of properties in a datatable and its children. +#define MAX_DATATABLES 1024 // must be a power of 2. +#define MAX_DATATABLE_PROPS 4096 + +#define MAX_ARRAY_ELEMENTS 2048 // a network array should have more that 1024 elements + +#define HIGH_DEFAULT -121121.121121f + +#define BITS_FULLRES -1 // Use the full resolution of the type being encoded. +#define BITS_WORLDCOORD -2 // Encode as a world coordinate. + +#define DT_MAX_STRING_BITS 9 +#define DT_MAX_STRING_BUFFERSIZE (1<<DT_MAX_STRING_BITS) // Maximum length of a string that can be sent. + +#define STRINGBUFSIZE(className, varName) sizeof( ((className*)0)->varName ) + +// Gets the size of a variable in a class. +#define PROPSIZEOF(className, varName) sizeof(((className*)0)->varName) + + +// SendProp::m_Flags. +#define SPROP_UNSIGNED (1<<0) // Unsigned integer data. + +#define SPROP_COORD (1<<1) // If this is set, the float/vector is treated like a world coordinate. +// Note that the bit count is ignored in this case. + +#define SPROP_NOSCALE (1<<2) // For floating point, don't scale into range, just take value as is. + +#define SPROP_ROUNDDOWN (1<<3) // For floating point, limit high value to range minus one bit unit + +#define SPROP_ROUNDUP (1<<4) // For floating point, limit low value to range minus one bit unit + +#define SPROP_NORMAL (1<<5) // If this is set, the vector is treated like a normal (only valid for vectors) + +#define SPROP_EXCLUDE (1<<6) // This is an exclude prop (not excludED, but it points at another prop to be excluded). + +#define SPROP_XYZE (1<<7) // Use XYZ/Exponent encoding for vectors. + +#define SPROP_INSIDEARRAY (1<<8) // This tells us that the property is inside an array, so it shouldn't be put into the +// flattened property list. Its array will point at it when it needs to. + +#define SPROP_PROXY_ALWAYS_YES (1<<9) // Set for datatable props using one of the default datatable proxies like +// SendProxy_DataTableToDataTable that always send the data to all clients. + +#define SPROP_CHANGES_OFTEN (1<<10) // this is an often changed field, moved to head of sendtable so it gets a small index + +#define SPROP_IS_A_VECTOR_ELEM (1<<11) // Set automatically if SPROP_VECTORELEM is used. + +#define SPROP_COLLAPSIBLE (1<<12) // Set automatically if it's a datatable with an offset of 0 that doesn't change the pointer +// (ie: for all automatically-chained base classes). +// In this case, it can get rid of this SendPropDataTable altogether and spare the +// trouble of walking the hierarchy more than necessary. + +#define SPROP_COORD_MP (1<<13) // Like SPROP_COORD, but special handling for multiplayer games +#define SPROP_COORD_MP_LOWPRECISION (1<<14) // Like SPROP_COORD, but special handling for multiplayer games where the fractional component only gets a 3 bits instead of 5 +#define SPROP_COORD_MP_INTEGRAL (1<<15) // SPROP_COORD_MP, but coordinates are rounded to integral boundaries + +#define SPROP_VARINT SPROP_NORMAL // reuse existing flag so we don't break demo. note you want to include SPROP_UNSIGNED if needed, its more efficient + +#define SPROP_NUMFLAGBITS_NETWORKED 16 + +// This is server side only, it's used to mark properties whose SendProxy_* functions encode against gpGlobals->tickcount (the only ones that currently do this are +// m_flAnimTime and m_flSimulationTime. MODs shouldn't need to mess with this probably +#define SPROP_ENCODED_AGAINST_TICKCOUNT (1<<16) + +// See SPROP_NUMFLAGBITS_NETWORKED for the ones which are networked +#define SPROP_NUMFLAGBITS 17 + +// Used by the SendProp and RecvProp functions to disable debug checks on type sizes. +#define SIZEOF_IGNORE -1 + + +// Use this to extern send and receive datatables, and reference them. +#define EXTERN_SEND_TABLE(tableName) namespace tableName {extern SendTable g_SendTable;} +#define EXTERN_RECV_TABLE(tableName) namespace tableName {extern RecvTable g_RecvTable;} + +#define REFERENCE_SEND_TABLE(tableName) tableName::g_SendTable +#define REFERENCE_RECV_TABLE(tableName) tableName::g_RecvTable + + +class SendProp; + +// The day we do this, we break all mods until they recompile. +//#define SUPPORTS_INT64 + +typedef enum +{ + DPT_Int = 0, + DPT_Float, + DPT_Vector, + DPT_VectorXY, // Only encodes the XY of a vector, ignores Z + DPT_String, + DPT_Array, // An array of the base types (can't be of datatables). + DPT_DataTable, +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + DPT_Quaternion, +#endif + +#ifdef SUPPORTS_INT64 + DPT_Int64, +#endif + + DPT_NUMSendPropTypes + +} SendPropType; + + +class DVariant +{ +public: + DVariant() + { + m_Type = DPT_Float; + } + DVariant( float val ) + { + m_Type = DPT_Float; m_Float = val; + } + + const char *ToString() + { + static char text[ 128 ]; + + switch( m_Type ) + { + case DPT_Int: + sprintf( text, "%i", m_Int ); + break; + case DPT_Float: + sprintf( text, "%.3f", m_Float ); + break; + case DPT_Vector: + sprintf( text, "(%.3f,%.3f,%.3f)", + m_Vector[ 0 ], m_Vector[ 1 ], m_Vector[ 2 ] ); + break; + case DPT_VectorXY: + sprintf( text, "(%.3f,%.3f)", + m_Vector[ 0 ], m_Vector[ 1 ] ); + break; +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + case DPT_Quaternion: + snprintf( text, sizeof( text ), "(%.3f,%.3f,%.3f %.3f)", + m_Vector[ 0 ], m_Vector[ 1 ], m_Vector[ 2 ], m_Vector[ 3 ] ); + break; +#endif + case DPT_String: + if( m_pString ) + return m_pString; + else + return "NULL"; + break; + case DPT_Array: + sprintf( text, "Array" ); + break; + case DPT_DataTable: + sprintf( text, "DataTable" ); + break; +#ifdef SUPPORTS_INT64 + case DPT_Int64: + snprintf( text, sizeof( text ), "%I64d", m_Int64 ); + break; +#endif + default: + sprintf( text, "DVariant type %i unknown", m_Type ); + break; + } + + return text; + } + + union + { + float m_Float; + int m_Int; + const char *m_pString; + void *m_pData; // For DataTables. +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + float m_Vector[ 4 ]; +#else + float m_Vector[ 3 ]; +#endif + +#ifdef SUPPORTS_INT64 + int64 m_Int64; +#endif + }; + SendPropType m_Type; +}; + + +// This can be used to set the # of bits used to transmit a number between 0 and nMaxElements-1. +inline int NumBitsForCount( int nMaxElements ) +{ + int nBits = 0; + while( nMaxElements > 0 ) + { + ++nBits; + nMaxElements >>= 1; + } + return nBits; +} + + +#endif // DATATABLE_COMMON_H
\ No newline at end of file diff --git a/internal_rewrite/Valve/dt_recv.h b/internal_rewrite/Valve/dt_recv.h new file mode 100644 index 0000000..b47922c --- /dev/null +++ b/internal_rewrite/Valve/dt_recv.h @@ -0,0 +1,586 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef DATATABLE_RECV_H +#define DATATABLE_RECV_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "dt_common.h" + +#define ADDRESSPROXY_NONE -1 + + +class RecvTable; +class RecvProp; + + +// This is passed into RecvProxy functions. +class CRecvProxyData +{ +public: + const RecvProp *m_pRecvProp; // The property it's receiving. + + DVariant m_Value; // The value given to you to store. + + int m_iElement; // Which array element you're getting. + + int m_ObjectID; // The object being referred to. +}; + + +//----------------------------------------------------------------------------- +// pStruct = the base structure of the datatable this variable is in (like C_BaseEntity) +// pOut = the variable that this this proxy represents (like C_BaseEntity::m_SomeValue). +// +// Convert the network-standard-type value in m_Value into your own format in pStruct/pOut. +//----------------------------------------------------------------------------- +typedef void( *RecvVarProxyFn )( const CRecvProxyData *pData, void *pStruct, void *pOut ); + +// ------------------------------------------------------------------------ // +// ArrayLengthRecvProxies are optionally used to get the length of the +// incoming array when it changes. +// ------------------------------------------------------------------------ // +typedef void( *ArrayLengthRecvProxyFn )( void *pStruct, int objectID, int currentArrayLength ); + + +// NOTE: DataTable receive proxies work differently than the other proxies. +// pData points at the object + the recv table's offset. +// pOut should be set to the location of the object to unpack the data table into. +// If the parent object just contains the child object, the default proxy just does *pOut = pData. +// If the parent object points at the child object, you need to dereference the pointer here. +// NOTE: don't ever return null from a DataTable receive proxy function. Bad things will happen. +typedef void( *DataTableRecvVarProxyFn )( const RecvProp *pProp, void **pOut, void *pData, int objectID ); + + +// This is used to fork over the standard proxy functions to the engine so it can +// make some optimizations. +class CStandardRecvProxies +{ +public: + CStandardRecvProxies(); + + RecvVarProxyFn m_Int32ToInt8; + RecvVarProxyFn m_Int32ToInt16; + RecvVarProxyFn m_Int32ToInt32; + RecvVarProxyFn m_FloatToFloat; + RecvVarProxyFn m_VectorToVector; +#ifdef SUPPORTS_INT64 + RecvVarProxyFn m_Int64ToInt64; +#endif +}; +extern CStandardRecvProxies g_StandardRecvProxies; + + +class CRecvDecoder; + + +class RecvProp +{ + // This info comes from the receive data table. +public: + RecvProp(); + + void InitArray( int nElements, int elementStride ); + + int GetNumElements() const; + void SetNumElements( int nElements ); + + int GetElementStride() const; + void SetElementStride( int stride ); + + int GetFlags() const; + + const char* GetName() const; + SendPropType GetType() const; + + RecvTable* GetDataTable() const; + void SetDataTable( RecvTable *pTable ); + + RecvVarProxyFn GetProxyFn() const; + void SetProxyFn( RecvVarProxyFn fn ); + + DataTableRecvVarProxyFn GetDataTableProxyFn() const; + void SetDataTableProxyFn( DataTableRecvVarProxyFn fn ); + + int GetOffset() const; + void SetOffset( int o ); + + // Arrays only. + RecvProp* GetArrayProp() const; + void SetArrayProp( RecvProp *pProp ); + + // Arrays only. + void SetArrayLengthProxy( ArrayLengthRecvProxyFn proxy ); + ArrayLengthRecvProxyFn GetArrayLengthProxy() const; + + bool IsInsideArray() const; + void SetInsideArray(); + + // Some property types bind more data to the prop in here. + const void* GetExtraData() const; + void SetExtraData( const void *pData ); + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char* GetParentArrayPropName(); + void SetParentArrayPropName( const char *pArrayPropName ); + +public: + + const char *m_pVarName; + SendPropType m_RecvType; + int m_Flags; + int m_StringBufferSize; + + +public: + + bool m_bInsideArray; // Set to true by the engine if this property sits inside an array. + + // Extra data that certain special property types bind to the property here. + const void *m_pExtraData; + + // If this is an array (DPT_Array). + RecvProp *m_pArrayProp; + ArrayLengthRecvProxyFn m_ArrayLengthProxy; + + RecvVarProxyFn m_ProxyFn; + DataTableRecvVarProxyFn m_DataTableProxyFn; // For RDT_DataTable. + + RecvTable *m_pDataTable; // For RDT_DataTable. + int m_Offset; + + int m_ElementStride; + int m_nElements; + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char *m_pParentArrayPropName; +}; + + +class RecvTable +{ +public: + + typedef RecvProp PropType; + + RecvTable(); + RecvTable( RecvProp *pProps, int nProps, const char *pNetTableName ); + ~RecvTable(); + + void Construct( RecvProp *pProps, int nProps, const char *pNetTableName ); + + int GetNumProps(); + RecvProp* GetProp( int i ); + + const char* GetName(); + + // Used by the engine while initializing array props. + void SetInitialized( bool bInitialized ); + bool IsInitialized() const; + + // Used by the engine. + void SetInMainList( bool bInList ); + bool IsInMainList() const; + + +public: + + // Properties described in a table. + RecvProp *m_pProps; + int m_nProps; + + // The decoder. NOTE: this covers each RecvTable AND all its children (ie: its children + // will have their own decoders that include props for all their children). + CRecvDecoder *m_pDecoder; + + const char *m_pNetTableName; // The name matched between client and server. + + +private: + + bool m_bInitialized; + bool m_bInMainList; +}; + + +inline int RecvTable::GetNumProps() +{ + return m_nProps; +} + +inline RecvProp* RecvTable::GetProp( int i ) +{ + return &m_pProps[ i ]; +} + +inline const char* RecvTable::GetName() +{ + return m_pNetTableName; +} + +inline void RecvTable::SetInitialized( bool bInitialized ) +{ + m_bInitialized = bInitialized; +} + +inline bool RecvTable::IsInitialized() const +{ + return m_bInitialized; +} + +inline void RecvTable::SetInMainList( bool bInList ) +{ + m_bInMainList = bInList; +} + +inline bool RecvTable::IsInMainList() const +{ + return m_bInMainList; +} + + +// ------------------------------------------------------------------------------------------------------ // +// See notes on BEGIN_SEND_TABLE for a description. These macros work similarly. +// ------------------------------------------------------------------------------------------------------ // +#define BEGIN_RECV_TABLE(className, tableName) \ + BEGIN_RECV_TABLE_NOBASE(className, tableName) \ + RecvPropDataTable("baseclass", 0, 0, className::BaseClass::m_pClassRecvTable, DataTableRecvProxy_StaticDataTable), + +#define BEGIN_RECV_TABLE_NOBASE(className, tableName) \ + template <typename T> int ClientClassInit(T *); \ + namespace tableName { \ + struct ignored; \ + } \ + template <> int ClientClassInit<tableName::ignored>(tableName::ignored *); \ + namespace tableName { \ + RecvTable g_RecvTable; \ + int g_RecvTableInit = ClientClassInit((tableName::ignored *)NULL); \ + } \ + template <> int ClientClassInit<tableName::ignored>(tableName::ignored *) \ + { \ + typedef className currentRecvDTClass; \ + const char *pRecvTableName = #tableName; \ + RecvTable &RecvTable = tableName::g_RecvTable; \ + static RecvProp RecvProps[] = { \ + RecvPropInt("should_never_see_this", 0, sizeof(int)), // It adds a dummy property at the start so you can define "empty" SendTables. + +#define END_RECV_TABLE() \ + }; \ + RecvTable.Construct(RecvProps+1, sizeof(RecvProps) / sizeof(RecvProp) - 1, pRecvTableName); \ + return 1; \ + } + + +#define RECVINFO(varName) #varName, offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) +#define RECVINFO_NAME(varName, remoteVarName) #remoteVarName, offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) +#define RECVINFO_STRING(varName) #varName, offsetof(currentRecvDTClass, varName), STRINGBUFSIZE(currentRecvDTClass, varName) +#define RECVINFO_BASECLASS(tableName) RecvPropDataTable("this", 0, 0, &REFERENCE_RECV_TABLE(tableName)) +#define RECVINFO_ARRAY(varName) #varName, offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName[0]), sizeof(((currentRecvDTClass*)0)->varName)/sizeof(((currentRecvDTClass*)0)->varName[0]) + +// Just specify the name and offset. Used for strings and data tables. +#define RECVINFO_NOSIZE(varName) #varName, offsetof(currentRecvDTClass, varName) +#define RECVINFO_DT(varName) RECVINFO_NOSIZE(varName) +#define RECVINFO_DTNAME(varName,remoteVarName) #remoteVarName, offsetof(currentRecvDTClass, varName) + + +void RecvProxy_FloatToFloat( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_VectorToVector( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_VectorXYToVectorXY( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_QuaternionToQuaternion( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_Int32ToInt8( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_Int32ToInt16( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_StringToString( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_Int32ToInt32( const CRecvProxyData *pData, void *pStruct, void *pOut ); +#ifdef SUPPORTS_INT64 +void RecvProxy_Int64ToInt64( const CRecvProxyData *pData, void *pStruct, void *pOut ); +#endif + +// StaticDataTable does *pOut = pData. +void DataTableRecvProxy_StaticDataTable( const RecvProp *pProp, void **pOut, void *pData, int objectID ); + +// PointerDataTable does *pOut = *((void**)pData) (ie: pData is a pointer to the object to decode into). +void DataTableRecvProxy_PointerDataTable( const RecvProp *pProp, void **pOut, void *pData, int objectID ); + + +RecvProp RecvPropFloat( + const char *pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags = 0, + RecvVarProxyFn varProxy = RecvProxy_FloatToFloat + ); + +RecvProp RecvPropVector( + const char *pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags = 0, + RecvVarProxyFn varProxy = RecvProxy_VectorToVector + ); + +RecvProp RecvPropVectorXY( + const char *pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags = 0, + RecvVarProxyFn varProxy = RecvProxy_VectorXYToVectorXY + ); + +// This is here so the RecvTable can look more like the SendTable. +#define RecvPropQAngles RecvPropVector + +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + +RecvProp RecvPropQuaternion( + const char *pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags = 0, + RecvVarProxyFn varProxy = RecvProxy_QuaternionToQuaternion + ); +#endif + +RecvProp RecvPropInt( + const char *pVarName, + int offset, + int sizeofVar = SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags = 0, + RecvVarProxyFn varProxy = 0 + ); + +RecvProp RecvPropString( + const char *pVarName, + int offset, + int bufferSize, + int flags = 0, + RecvVarProxyFn varProxy = RecvProxy_StringToString + ); + +RecvProp RecvPropDataTable( + const char *pVarName, + int offset, + int flags, + RecvTable *pTable, + DataTableRecvVarProxyFn varProxy = DataTableRecvProxy_StaticDataTable + ); + +RecvProp RecvPropArray3( + const char *pVarName, + int offset, + int sizeofVar, + int elements, + RecvProp pArrayProp, + DataTableRecvVarProxyFn varProxy = DataTableRecvProxy_StaticDataTable + ); + +// Use the macro to let it automatically generate a table name. You shouldn't +// ever need to reference the table name. If you want to exclude this array, then +// reference the name of the variable in varTemplate. +RecvProp InternalRecvPropArray( + const int elementCount, + const int elementStride, + const char *pName, + ArrayLengthRecvProxyFn proxy + ); + + +// +// Use this if you want to completely manage the way the array data is stored. +// You'll need to provide a proxy inside varTemplate that looks for 'iElement' +// to figure out where to store the specified element. +// +#define RecvPropVirtualArray( arrayLengthProxy, maxArrayLength, varTemplate, propertyName ) \ + varTemplate, \ + InternalRecvPropArray( \ + maxArrayLength, \ + 0, \ + #propertyName, \ + arrayLengthProxy \ + ) + + +// Use this and pass the array name and it will figure out the count and stride automatically. +#define RecvPropVariableLengthArray( arrayLengthProxy, varTemplate, arrayName ) \ + varTemplate, \ + InternalRecvPropArray( \ + sizeof(((currentRecvDTClass*)0)->arrayName) / PROPSIZEOF(currentRecvDTClass, arrayName[0]), \ + PROPSIZEOF(currentRecvDTClass, arrayName[0]), \ + #arrayName, \ + arrayLengthProxy \ + ) + + +// Use this and pass the array name and it will figure out the count and stride automatically. +#define RecvPropArray( varTemplate, arrayName ) \ + RecvPropVariableLengthArray( 0, varTemplate, arrayName ) + + +// Use this one to specify the element count and stride manually. +#define RecvPropArray2( arrayLengthProxy, varTemplate, elementCount, elementStride, arrayName ) \ + varTemplate, \ + InternalRecvPropArray( elementCount, elementStride, #arrayName, arrayLengthProxy ) + + +// ---------------------------------------------------------------------------------------- // +// Inlines. +// ---------------------------------------------------------------------------------------- // + +inline void RecvProp::InitArray( int nElements, int elementStride ) +{ + m_RecvType = DPT_Array; + m_nElements = nElements; + m_ElementStride = elementStride; +} + +inline int RecvProp::GetNumElements() const +{ + return m_nElements; +} + +inline void RecvProp::SetNumElements( int nElements ) +{ + m_nElements = nElements; +} + +inline int RecvProp::GetElementStride() const +{ + return m_ElementStride; +} + +inline void RecvProp::SetElementStride( int stride ) +{ + m_ElementStride = stride; +} + +inline int RecvProp::GetFlags() const +{ + return m_Flags; +} + +inline const char* RecvProp::GetName() const +{ + return m_pVarName; +} + +inline SendPropType RecvProp::GetType() const +{ + return m_RecvType; +} + +inline RecvTable* RecvProp::GetDataTable() const +{ + return m_pDataTable; +} + +inline void RecvProp::SetDataTable( RecvTable *pTable ) +{ + m_pDataTable = pTable; +} + +inline RecvVarProxyFn RecvProp::GetProxyFn() const +{ + return m_ProxyFn; +} + +inline void RecvProp::SetProxyFn( RecvVarProxyFn fn ) +{ + m_ProxyFn = fn; +} + +inline DataTableRecvVarProxyFn RecvProp::GetDataTableProxyFn() const +{ + return m_DataTableProxyFn; +} + +inline void RecvProp::SetDataTableProxyFn( DataTableRecvVarProxyFn fn ) +{ + m_DataTableProxyFn = fn; +} + +inline int RecvProp::GetOffset() const +{ + return m_Offset; +} + +inline void RecvProp::SetOffset( int o ) +{ + m_Offset = o; +} + +inline RecvProp* RecvProp::GetArrayProp() const +{ + return m_pArrayProp; +} + +inline void RecvProp::SetArrayProp( RecvProp *pProp ) +{ + m_pArrayProp = pProp; +} + +inline void RecvProp::SetArrayLengthProxy( ArrayLengthRecvProxyFn proxy ) +{ + m_ArrayLengthProxy = proxy; +} + +inline ArrayLengthRecvProxyFn RecvProp::GetArrayLengthProxy() const +{ + return m_ArrayLengthProxy; +} + +inline bool RecvProp::IsInsideArray() const +{ + return m_bInsideArray; +} + +inline void RecvProp::SetInsideArray() +{ + m_bInsideArray = true; +} + +inline const void* RecvProp::GetExtraData() const +{ + return m_pExtraData; +} + +inline void RecvProp::SetExtraData( const void *pData ) +{ + m_pExtraData = pData; +} + +inline const char* RecvProp::GetParentArrayPropName() +{ + return m_pParentArrayPropName; +} + +inline void RecvProp::SetParentArrayPropName( const char *pArrayPropName ) +{ + m_pParentArrayPropName = pArrayPropName; +} + +inline void**& GetVTable( void* instance ) +{ + return *reinterpret_cast<void***>( ( size_t )instance ); +} + +inline const void** GetVTable( const void* instance ) +{ + return *reinterpret_cast<const void***>( ( size_t )instance ); +} + +template<typename T> +inline T GetMethod( const void* instance, size_t index ) +{ + return reinterpret_cast<T>( GetVTable( instance )[ index ] ); +} + +#endif // DATATABLE_RECV_H
\ No newline at end of file |
