csgo-2018-source/engine/hltvbroadcast.h

204 lines
6.3 KiB
C
Raw Normal View History

2021-07-25 12:11:47 +08:00
//========= Copyright <20> Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef HLTVBROADCAST_HDR
#define HLTVBROADCAST_HDR
#ifdef _WIN32
#pragma once
#endif
#include <filesystem.h>
//#include "demo.h"
#include "broadcast.h"
#include "tier0/microprofiler.h"
#include "tier1/utlincrementalvector.h"
#include "steam/steam_api.h"
#include "steam/isteamhttp.h"
class CHLTVFrame;
class CHLTVServer;
class CEngineGotvSyncPacket; // forward declare protobuf message here
class CHLTVBroadcast
{
protected:
class CMemoryStream
{
protected:
CUtlMemory< uint8 > m_Buffer; // data chunk that will get uploaded
uint m_nCommitted; // the number of bytes in payload buffer that will need to be uploaded
uint8 *m_pReserved;
// the total number of bytes allocated in payload buffer includes committed portion + reserved portion that is being filled in right now. m_pPayloadReserved == NULL after upload, otherwise we forgot to commit.
public:
CMemoryStream();
void *Reserve( uint nReserveBytes );
const void *GetReservedBase()const { return m_Buffer.Base() + m_nCommitted; }
const void *Base()const { return m_Buffer.Base(); }
uint GetReservedSize()const { return m_Buffer.Count() - m_nCommitted; }
void Commit( uint nCommitBytes );
void Purge();
bool IsEmpty()const { return m_nCommitted == 0; }
uint GetCommitSize()const { return m_nCommitted; }
void Reset() { m_nCommitted = 0; }
void WriteCmdHeader( unsigned char cmd, int tick, int nPlayerSlot );
};
class CInStreamMsg : public bf_write
{
protected:
CMemoryStream &m_Stream;
// int m_nCmd;
// int m_nTick;
// int m_nPlayerSlot,
public:
CInStreamMsg( CMemoryStream &stream, const char *pDebugName, uint nReserveSize = 256 * 1024 ) :
m_Stream( stream ),
bf_write( pDebugName, stream.Reserve(nReserveSize), nReserveSize )
{
}
~CInStreamMsg()
{
m_Stream.Commit( GetNumBytesWritten() );
}
};
class CInStreamMsgWithSize : public CInStreamMsg
{
protected:
public:
CInStreamMsgWithSize( CMemoryStream &stream, const char *pDebugName, uint nReserveSize = 256 * 1024 ) :
CInStreamMsg( stream, pDebugName, nReserveSize )
{
this->WriteLong( 0 ); // we'll write this in the end
}
~CInStreamMsgWithSize()
{
// the length of the message, after the initial 4 bytes that contain the length of the message. Binarily compatible with .dem file
*( int32* )( this->GetBasePointer() ) = this->GetNumBytesWritten() - sizeof( int32 );
}
};
class CHttpCallback : public CCallbackBase
{
public:
CHttpCallback( CHLTVBroadcast *pParent, HTTPRequestHandle hRequest, const char *pResource );
~CHttpCallback();
virtual void Run( void *pvParam ) OVERRIDE; // success; HTTPRequestCompleted_t
virtual void Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall ) OVERRIDE; // result; HTTPRequestCompleted_t
void DetachFromParent() { m_pParent = NULL; }
void SetProtobufMsgForGCUponSuccess( const CEngineGotvSyncPacket *pProtobufMsgForGCUponSuccess );
public:
int m_nIncrementalVectorIndex;
protected:
virtual int GetCallbackSizeBytes() OVERRIDE { return sizeof( HTTPRequestCompleted_t ); }
CHLTVBroadcast *m_pParent;
HTTPRequestHandle m_hRequest;
CUtlString m_Resource;
const CEngineGotvSyncPacket *m_pProtobufMsgForGCUponSuccess;
};
public:
CHLTVBroadcast( CHLTVServer *pHltvServer );
virtual ~CHLTVBroadcast();
int GetRecordingTick( void )
{
return m_nLastWrittenTick/* - m_nStartTick*/;
}
void OnMasterStarted();
void StartRecording( const char *pBroadcastUrl );
const char *GetUrl()const { return m_Url.Get(); }
void SetSignonState( int state ) {}; // not need by HLTV recorder
bool IsRecording( void );
void PauseRecording( void ) {};
void ResumeRecording( void ) {};
void StopRecording();
void DumpStats();
void RecordCommand( const char *cmdstring );
void RecordUserInput( int cmdnumber ) {}; // not need by HLTV recorder
//void RecordMessages( bf_read &data, int bits );
void RecordServerClasses( CMemoryStream &stream, ServerClass *pClasses );
void RecordStringTables( CMemoryStream &stream );
void ResetDemoInterpolation( void ) {};
public:
void WriteFrame( CHLTVFrame *pFrame, bf_write *additionaldata = NULL );
void ResendStartup();
void RecordSnapshot( CHLTVFrame * pFrame, bf_write * additionaldata, bf_write &msg, int nDeltaTick );
void CloseFile();
void Reset();
void WriteServerInfo( CMemoryStream &stream );
void WriteSignonData(); // write all necessary signon data and returns written bytes
void WriteMessages( CMemoryStream &stream, unsigned char cmd );
void SendSignonData();
int GetMaxAckTickCount();
void OnHttpRequestFailed();
void OnHttpRequestResetContent();
void OnHttpRequestSuccess();
void Register( CHttpCallback *pCallback );
void Unregister( CHttpCallback *pCallback );
protected:
void FlushCollectedStreams(const char *pExtraParams = "");
CHttpCallback * Send( const char* pPath, CMemoryStream &stream );
CHttpCallback * Send( const char* pPath, const void *pBase, uint nSize );
CHttpCallback * LowLevelSend( const CUtlString &path, const void *pBase, uint nSize );
protected:
bool m_bIsRecording;
int m_nFrameCount;
int m_nKeyframeTick;
int m_nStartTick;
int m_nDeltaTick;
int m_nSignonTick;
int m_nCurrentTick;
int m_nSignonDataAckTick; // when signon data was sent out last
int m_nLastWrittenTick;
uint64 m_nMasterCookie;
CHLTVServer *m_pHltvServer;
CMicroProfiler m_mpKeyframe, m_mpFrame, m_mpLowLevelSend;
int64 m_nMaxKeyframeTicks, m_nDecayMaxKeyframeTicks, m_nMaxLowLevelSendTicks;
int64 m_nKeyframeBytes, m_nDeltaFrameBytes;
FileHandle_t m_pFile;
// The following fields are exclusive to the HTTP broadcast implementation, they are not needed for writing into file, memory or netchan streams
//HTTPRequestHandle m_hHTTPRequestHandle;
CMemoryStream m_DeltaStream; // this is being collected every tick, and flushed every so often
CMemoryStream m_SignonDataStream;
int m_nSignonDataFragment;
CUtlString m_Url;
float m_flTimeout;
int m_nFailedHttpRequests;
friend class CHttpCallback;
CUtlIncrementalVector< CHttpCallback > m_HttpRequests; // requests in flight
int m_nHttpRequestBacklogHighWatermark;
int m_nMatchFragmentCounter;
float m_flBroadcastKeyframeInterval;
};
#endif // HLTVBROADCAST_HDR