You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.0 KiB
199 lines
6.0 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
//---------------------------------------------------------------------------------------- |
|
|
|
#ifndef REPLAYSERVER_H |
|
#define REPLAYSERVER_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "baseserver.h" |
|
#include "replaydemo.h" |
|
#include "clientframe.h" |
|
#include "networkstringtable.h" |
|
#include "dt_recv.h" |
|
#include "replay/ireplayserver.h" |
|
#include <convar.h> |
|
|
|
#define REPLAY_BUFFER_DIRECTOR 0 // director commands |
|
#define REPLAY_BUFFER_RELIABLE 1 // reliable messages |
|
#define REPLAY_BUFFER_UNRELIABLE 2 // unreliable messages |
|
#define REPLAY_BUFFER_VOICE 3 // player voice data |
|
#define REPLAY_BUFFER_SOUNDS 4 // unreliable sounds |
|
#define REPLAY_BUFFER_TEMPENTS 5 // temporary/event entities |
|
#define REPLAY_BUFFER_MAX 6 // end marker |
|
|
|
// proxy dispatch modes |
|
#define DISPATCH_MODE_OFF 0 |
|
#define DISPATCH_MODE_AUTO 1 |
|
#define DISPATCH_MODE_ALWAYS 2 |
|
|
|
class CReplayFrame : public CClientFrame |
|
{ |
|
public: |
|
CReplayFrame(); |
|
virtual ~CReplayFrame(); |
|
|
|
void Reset(); // resets all data & buffers |
|
void FreeBuffers(); |
|
void AllocBuffers(); |
|
bool HasData(); |
|
void CopyReplayData( CReplayFrame &frame ); |
|
virtual bool IsMemPoolAllocated() { return false; } |
|
|
|
public: |
|
|
|
// message buffers: |
|
bf_write m_Messages[REPLAY_BUFFER_MAX]; |
|
}; |
|
|
|
struct CReplayFrameCacheEntry_s |
|
{ |
|
CClientFrame* pFrame; |
|
int nTick; |
|
}; |
|
|
|
class CReplayDeltaEntityCache |
|
{ |
|
struct DeltaEntityEntry_s |
|
{ |
|
DeltaEntityEntry_s *pNext; |
|
int nDeltaTick; |
|
int nBits; |
|
}; |
|
|
|
public: |
|
CReplayDeltaEntityCache(); |
|
~CReplayDeltaEntityCache(); |
|
|
|
void SetTick( int nTick, int nMaxEntities ); |
|
unsigned char* FindDeltaBits( int nEntityIndex, int nDeltaTick, int &nBits ); |
|
void AddDeltaBits( int nEntityIndex, int nDeltaTick, int nBits, bf_write *pBuffer ); |
|
void Flush(); |
|
|
|
protected: |
|
int m_nTick; // current tick |
|
int m_nMaxEntities; // max entities = length of cache |
|
int m_nCacheSize; |
|
DeltaEntityEntry_s* m_Cache[MAX_EDICTS]; // array of pointers to delta entries |
|
}; |
|
|
|
|
|
class CGameClient; |
|
class CGameServer; |
|
class IReplayDirector; |
|
class IServerReplayContext; |
|
|
|
class CReplayServer : public IGameEventListener2, |
|
public CBaseServer, |
|
public CClientFrameManager, |
|
public IReplayServer |
|
{ |
|
typedef CBaseServer BaseClass; |
|
|
|
public: |
|
CReplayServer(); |
|
virtual ~CReplayServer(); |
|
|
|
public: // CBaseServer interface: |
|
virtual bool IsMultiplayer() const { return true; }; |
|
virtual bool IsReplay() const { return true; }; |
|
virtual void Init( bool bIsDedicated ); |
|
virtual void Clear(); |
|
virtual void Shutdown(); |
|
virtual void FillServerInfo(SVC_ServerInfo &serverinfo); |
|
virtual void GetNetStats( float &avgIn, float &avgOut ); |
|
virtual int GetChallengeType ( netadr_t &adr ); |
|
virtual const char *GetName() const; |
|
virtual const char *GetPassword() const; |
|
IClient *ConnectClient ( netadr_t &adr, int protocol, int challenge, int clientChallenge, int authProtocol, |
|
const char *name, const char *password, const char *hashedCDkey, int cdKeyLen ); |
|
|
|
void ReplyChallenge(netadr_t &adr, int clientChallenge ); |
|
void ReplyServerChallenge(netadr_t &adr); |
|
void RejectConnection( const netadr_t &adr, int clientChallenge, const char *s ); |
|
CBaseClient *CreateFakeClient(const char *name); |
|
|
|
public: // IGameEventListener2 interface: |
|
void FireGameEvent( IGameEvent *event ); |
|
int m_nDebugID; |
|
int GetEventDebugID(); |
|
|
|
public: // IReplayServer interface: |
|
virtual IServer *GetBaseServer(); |
|
virtual IReplayDirector *GetDirector() { return NULL; } |
|
virtual int GetReplaySlot(); // return entity index-1 of Replay in game |
|
virtual float GetOnlineTime(); // seconds since broadcast started |
|
virtual void BroadcastEvent( IGameEvent *event ) { } |
|
virtual bool IsRecording() { return m_DemoRecorder.IsRecording(); } |
|
virtual void StartRecording(); |
|
virtual void StopRecording(); |
|
|
|
public: // CBaseServer overrides: |
|
virtual void SetMaxClients( int number ); |
|
virtual void UserInfoChanged( int nClientIndex ); |
|
|
|
public: |
|
void StartMaster(CGameClient *client); // start Replay server as master proxy |
|
bool SendNetMsg( INetMessage &msg, bool bForceReliable = false ); |
|
void RunFrame(); |
|
void Changelevel(); |
|
CClientFrame *AddNewFrame( CClientFrame * pFrame ); // add new frame, returns Replay's copy |
|
void LinkInstanceBaselines(); |
|
bf_write *GetBuffer( int nBuffer); |
|
CClientFrame *GetDeltaFrame( int nTick ); |
|
|
|
protected: |
|
virtual bool ShouldUpdateMasterServer(); |
|
|
|
private: |
|
void UpdateTick(); |
|
void InstallStringTables(); |
|
void RestoreTick( int tick ); |
|
void EntityPVSCheck( CClientFrame *pFrame ); |
|
void InitClientRecvTables(); |
|
void FreeClientRecvTables(); |
|
void ResyncDemoClock(); |
|
|
|
public: |
|
CGameClient *m_MasterClient; // if != NULL, this is the master Replay |
|
CReplayDemoRecorder m_DemoRecorder; // Replay demo object for recording and playback |
|
CGameServer *m_Server; // pointer to source server (sv.) |
|
int m_nFirstTick; // first known server tick; |
|
int m_nLastTick; // last tick from AddFrame() |
|
CReplayFrame *m_CurrentFrame; // current delayed Replay frame |
|
int m_nViewEntity; // the current entity Replay is tracking |
|
int m_nPlayerSlot; // slot of Replay client on game server |
|
CReplayFrame m_ReplayFrame; // all incoming messages go here until Snapshot is made |
|
|
|
bool m_bSignonState; // true if connecting to server |
|
float m_flStartTime; |
|
float m_flFPS; // FPS the proxy is running; |
|
int m_nGameServerMaxClients; // max clients on game server |
|
float m_fNextSendUpdateTime; // time to send next Replay status messages |
|
RecvTable *m_pRecvTables[MAX_DATATABLES]; |
|
int m_nRecvTables; |
|
Vector m_vPVSOrigin; |
|
bool m_bMasterOnlyMode; |
|
|
|
netadr_t m_RootServer; // Replay root server |
|
int m_nGlobalSlots; |
|
int m_nGlobalClients; |
|
int m_nGlobalProxies; |
|
|
|
CNetworkStringTableContainer m_NetworkStringTables; |
|
|
|
CReplayDeltaEntityCache m_DeltaCache; |
|
CUtlVector<CReplayFrameCacheEntry_s> m_FrameCache; |
|
|
|
private: |
|
void SendPendingEvents(); // Send events to clients regarding start/stop/replays available |
|
|
|
float m_flStartRecordTime; |
|
float m_flStopRecordTime; |
|
}; |
|
|
|
extern CReplayServer *replay; // The global Replay server/object. NULL on xbox. |
|
|
|
#endif // REPLAYSERVER_H
|
|
|