1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef PREDICTIONCOPY_H
#define PREDICTIONCOPY_H
#ifdef _WIN32
#pragma once
#endif
#include <memory.h>
#include "datamap.h"
#include "ehandle.h"
#include "tier1/utlstring.h"
#if defined( CLIENT_DLL )
class C_BaseEntity;
typedef CHandle<C_BaseEntity> EHANDLE;
#if defined( _DEBUG )
// #define COPY_CHECK_STRESSTEST
class IGameSystem;
IGameSystem* GetPredictionCopyTester( void );
#endif
#else
class CBaseEntity;
typedef CHandle<CBaseEntity> EHANDLE;
#endif
enum
{
PC_EVERYTHING = 0,
PC_NON_NETWORKED_ONLY,
PC_NETWORKED_ONLY,
};
#define PC_DATA_PACKED true
#define PC_DATA_NORMAL false
typedef void ( *FN_FIELD_COMPARE )( const char *classname, const char *fieldname, const char *fieldtype,
bool networked, bool noterrorchecked, bool differs, bool withintolerance, const char *value );
class CPredictionCopy
{
public:
typedef enum
{
DIFFERS = 0,
IDENTICAL,
WITHINTOLERANCE,
} difftype_t;
CPredictionCopy( int type, void *dest, bool dest_packed, void const *src, bool src_packed,
bool counterrors = false, bool reporterrors = false, bool performcopy = true,
bool describefields = false, FN_FIELD_COMPARE func = NULL );
void CopyShort( difftype_t dt, short *outvalue, const short *invalue, int count );
void CopyInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Copy an int
void CopyBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Copy a bool
void CopyFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Copy a float
void CopyString( difftype_t dt, char *outstring, const char *instring ); // Copy a null-terminated string
void CopyVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Copy a vector
void CopyVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Copy a vector array
void CopyQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Copy a quaternion
void CopyQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Copy a quaternion array
void CopyEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count );
void FORCEINLINE CopyData( difftype_t dt, int size, char *outdata, const char *indata ) // Copy a binary data block
{
if ( !m_bPerformCopy )
return;
if ( dt == IDENTICAL )
return;
memcpy( outdata, indata, size );
}
int TransferData( const char *operation, int entindex, datamap_t *dmap );
private:
void TransferData_R( int chaincount, datamap_t *dmap );
void DetermineWatchField( const char *operation, int entindex, datamap_t *dmap );
void DumpWatchField( typedescription_t *field );
void WatchMsg( PRINTF_FORMAT_STRING const char *fmt, ... );
difftype_t CompareShort( short *outvalue, const short *invalue, int count );
difftype_t CompareInt( int *outvalue, const int *invalue, int count ); // Compare an int
difftype_t CompareBool( bool *outvalue, const bool *invalue, int count ); // Compare a bool
difftype_t CompareFloat( float *outvalue, const float *invalue, int count ); // Compare a float
difftype_t CompareData( int size, char *outdata, const char *indata ); // Compare a binary data block
difftype_t CompareString( char *outstring, const char *instring ); // Compare a null-terminated string
difftype_t CompareVector( Vector& outValue, const Vector &inValue ); // Compare a vector
difftype_t CompareVector( Vector* outValue, const Vector *inValue, int count ); // Compare a vector array
difftype_t CompareQuaternion( Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion
difftype_t CompareQuaternion( Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array
difftype_t CompareEHandle( EHANDLE *outvalue, EHANDLE const *invalue, int count );
void DescribeShort( difftype_t dt, short *outvalue, const short *invalue, int count );
void DescribeInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Compare an int
void DescribeBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Compare a bool
void DescribeFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Compare a float
void DescribeData( difftype_t dt, int size, char *outdata, const char *indata ); // Compare a binary data block
void DescribeString( difftype_t dt, char *outstring, const char *instring ); // Compare a null-terminated string
void DescribeVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Compare a vector
void DescribeVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Compare a vector array
void DescribeQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion
void DescribeQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array
void DescribeEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count );
void WatchShort( difftype_t dt, short *outvalue, const short *invalue, int count );
void WatchInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Compare an int
void WatchBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Compare a bool
void WatchFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Compare a float
void WatchData( difftype_t dt, int size, char *outdata, const char *indata ); // Compare a binary data block
void WatchString( difftype_t dt, char *outstring, const char *instring ); // Compare a null-terminated string
void WatchVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Compare a vector
void WatchVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Compare a vector array
void WatchQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion
void WatchQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array
void WatchEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count );
// Report function
void ReportFieldsDiffer( PRINTF_FORMAT_STRING const char *fmt, ... );
void DescribeFields( difftype_t dt, PRINTF_FORMAT_STRING const char *fmt, ... );
bool CanCheck( void );
void CopyFields( int chaincount, datamap_t *pMap, typedescription_t *pFields, int fieldCount );
private:
int m_nType;
void *m_pDest;
void const *m_pSrc;
int m_nDestOffsetIndex;
int m_nSrcOffsetIndex;
bool m_bErrorCheck;
bool m_bReportErrors;
bool m_bDescribeFields;
typedescription_t *m_pCurrentField;
char const *m_pCurrentClassName;
datamap_t *m_pCurrentMap;
bool m_bShouldReport;
bool m_bShouldDescribe;
int m_nErrorCount;
bool m_bPerformCopy;
FN_FIELD_COMPARE m_FieldCompareFunc;
typedescription_t *m_pWatchField;
char const *m_pOperation;
};
typedef void (*FN_FIELD_DESCRIPTION)( const char *classname, const char *fieldname, const char *fieldtype,
bool networked, const char *value );
//-----------------------------------------------------------------------------
// Purpose: Simply dumps all data fields in object
//-----------------------------------------------------------------------------
class CPredictionDescribeData
{
public:
CPredictionDescribeData( void const *src, bool src_packed, FN_FIELD_DESCRIPTION func = 0 );
void DescribeShort( const short *invalue, int count );
void DescribeInt( const int *invalue, int count );
void DescribeBool( const bool *invalue, int count );
void DescribeFloat( const float *invalue, int count );
void DescribeData( int size, const char *indata );
void DescribeString( const char *instring );
void DescribeVector( const Vector &inValue );
void DescribeVector( const Vector *inValue, int count );
void DescribeQuaternion( const Quaternion &inValue );
void DescribeQuaternion( const Quaternion *inValue, int count );
void DescribeEHandle( EHANDLE const *invalue, int count );
void DumpDescription( datamap_t *pMap );
private:
void DescribeFields_R( int chain_count, datamap_t *pMap, typedescription_t *pFields, int fieldCount );
void const *m_pSrc;
int m_nSrcOffsetIndex;
void Describe( PRINTF_FORMAT_STRING const char *fmt, ... );
typedescription_t *m_pCurrentField;
char const *m_pCurrentClassName;
datamap_t *m_pCurrentMap;
bool m_bShouldReport;
FN_FIELD_DESCRIPTION m_FieldDescFunc;
};
#if defined( CLIENT_DLL )
class CValueChangeTracker
{
public:
CValueChangeTracker();
void Reset();
void StartTrack( char const *pchContext );
void EndTrack();
bool IsActive() const;
void SetupTracking( C_BaseEntity *ent, char const *pchFieldName );
void ClearTracking();
void Spew();
C_BaseEntity *GetEntity();
private:
enum
{
eChangeTrackerBufSize = 128,
};
// Returns field size
void GetValue( char *buf, size_t bufsize );
bool m_bActive : 1;
bool m_bTracking : 1;
EHANDLE m_hEntityToTrack;
CUtlVector< typedescription_t * > m_FieldStack;
CUtlString m_strFieldName;
CUtlString m_strContext;
// First 128 bytes of data is all we will consider
char m_OrigValueBuf[ eChangeTrackerBufSize ];
CUtlVector< CUtlString > m_History;
};
extern CValueChangeTracker *g_pChangeTracker;
class CValueChangeTrackerScope
{
public:
CValueChangeTrackerScope( char const *pchContext )
{
m_bCallEndTrack = true;
g_pChangeTracker->StartTrack( pchContext );
}
// Only calls Start/End if passed in entity matches entity to track
CValueChangeTrackerScope( C_BaseEntity *pEntity, char const *pchContext )
{
m_bCallEndTrack = g_pChangeTracker->GetEntity() == pEntity;
if ( m_bCallEndTrack )
{
g_pChangeTracker->StartTrack( pchContext );
}
}
~CValueChangeTrackerScope()
{
if ( m_bCallEndTrack )
{
g_pChangeTracker->EndTrack();
}
}
private:
bool m_bCallEndTrack;
};
#if defined( _DEBUG )
#define PREDICTION_TRACKVALUECHANGESCOPE( context ) CValueChangeTrackerScope scope( context );
#define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context ) CValueChangeTrackerScope scope( entity, context );
#define PREDICTION_STARTTRACKVALUE( context ) g_pChangeTracker->StartTrack( context );
#define PREDICTION_ENDTRACKVALUE() g_pChangeTracker->EndTrack();
#define PREDICTION_SPEWVALUECHANGES() g_pChangeTracker->Spew();
#else
#define PREDICTION_TRACKVALUECHANGESCOPE( context )
#define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context )
#define PREDICTION_STARTTRACKVALUE( context )
#define PREDICTION_ENDTRACKVALUE()
#define PREDICTION_SPEWVALUECHANGES()
#endif
#endif // !CLIENT_DLL
#endif // PREDICTIONCOPY_H
|