Seaside/SpyCustom/predictioncopy.h
2021-06-16 16:11:47 +03:00

278 lines
9.5 KiB
C++

#ifndef PREDICTIONCOPY_H
#define PREDICTIONCOPY_H
#ifdef _WIN32
#pragma once
#endif
#include <memory.h>
#include "datamap.h"
#include "ehandle.h"
#include "utlstring.h"
#if defined( CLIENT_DLL )
class C_BaseEntity;
typedef CHandle<C_BaseEntity> EHANDLE;
#if defined( _DEBUG )
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);
void CopyBool(difftype_t dt, bool* outvalue, const bool* invalue, int count);
void CopyFloat(difftype_t dt, float* outvalue, const float* invalue, int count);
void CopyString(difftype_t dt, char* outstring, const char* instring);
void CopyVector(difftype_t dt, Vector& outValue, const Vector& inValue);
void CopyVector(difftype_t dt, Vector* outValue, const Vector* inValue, int count);
void CopyQuaternion(difftype_t dt, Quaternion& outValue, const Quaternion& inValue);
void CopyQuaternion(difftype_t dt, Quaternion* outValue, const Quaternion* inValue, int count);
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)
{
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);
difftype_t CompareBool(bool* outvalue, const bool* invalue, int count);
difftype_t CompareFloat(float* outvalue, const float* invalue, int count);
difftype_t CompareData(int size, char* outdata, const char* indata);
difftype_t CompareString(char* outstring, const char* instring);
difftype_t CompareVector(Vector& outValue, const Vector& inValue);
difftype_t CompareVector(Vector* outValue, const Vector* inValue, int count);
difftype_t CompareQuaternion(Quaternion& outValue, const Quaternion& inValue);
difftype_t CompareQuaternion(Quaternion* outValue, const Quaternion* inValue, int count);
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);
void DescribeBool(difftype_t dt, bool* outvalue, const bool* invalue, int count);
void DescribeFloat(difftype_t dt, float* outvalue, const float* invalue, int count);
void DescribeData(difftype_t dt, int size, char* outdata, const char* indata);
void DescribeString(difftype_t dt, char* outstring, const char* instring);
void DescribeVector(difftype_t dt, Vector& outValue, const Vector& inValue);
void DescribeVector(difftype_t dt, Vector* outValue, const Vector* inValue, int count);
void DescribeQuaternion(difftype_t dt, Quaternion& outValue, const Quaternion& inValue);
void DescribeQuaternion(difftype_t dt, Quaternion* outValue, const Quaternion* inValue, int count);
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);
void WatchBool(difftype_t dt, bool* outvalue, const bool* invalue, int count);
void WatchFloat(difftype_t dt, float* outvalue, const float* invalue, int count);
void WatchData(difftype_t dt, int size, char* outdata, const char* indata);
void WatchString(difftype_t dt, char* outstring, const char* instring);
void WatchVector(difftype_t dt, Vector& outValue, const Vector& inValue);
void WatchVector(difftype_t dt, Vector* outValue, const Vector* inValue, int count);
void WatchQuaternion(difftype_t dt, Quaternion& outValue, const Quaternion& inValue);
void WatchQuaternion(difftype_t dt, Quaternion* outValue, const Quaternion* inValue, int count);
void WatchEHandle(difftype_t dt, EHANDLE* outvalue, EHANDLE const* invalue, int count);
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);
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,
};
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;
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);
}
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
#endif