Counter Strike : Global Offensive Source Code
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.

1154 lines
33 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include <netmessages.h>
  9. #include "hltvclientstate.h"
  10. #include "hltvserver.h"
  11. #include "quakedef.h"
  12. #include "cl_main.h"
  13. #include "host.h"
  14. #include "dt_recv_eng.h"
  15. #include "dt_common_eng.h"
  16. #include "framesnapshot.h"
  17. #include "clientframe.h"
  18. #include "ents_shared.h"
  19. #include "server.h"
  20. #include "eiface.h"
  21. #include "server_class.h"
  22. #include "cdll_engine_int.h"
  23. #include "sv_main.h"
  24. #include "changeframelist.h"
  25. #include "GameEventManager.h"
  26. #include "dt_recv_decoder.h"
  27. #include "utllinkedlist.h"
  28. #include "cl_demo.h"
  29. #include "sv_steamauth.h"
  30. // memdbgon must be the last include file in a .cpp file!!!
  31. #include "tier0/memdbgon.h"
  32. // copy message data from in to out buffer
  33. #define CopyDataInToOut(msg) \
  34. int size = PAD_NUMBER( Bits2Bytes(msg->m_nLength), 4); \
  35. byte *buffer = (byte*) stackalloc( size ); \
  36. msg->m_DataIn.ReadBits( buffer, msg->m_nLength ); \
  37. msg->m_DataOut.StartWriting( buffer, size, msg->m_nLength );\
  38. static void HLTV_Callback_InstanceBaseline( void *object, INetworkStringTable *stringTable, int stringNumber, char const *newString, void const *newData )
  39. {
  40. // relink server classes to instance baselines
  41. CHLTVServer *pHLTV = (CHLTVServer*)object;
  42. pHLTV->m_ClientState.UpdateInstanceBaseline( stringNumber );
  43. pHLTV->LinkInstanceBaselines();
  44. }
  45. extern CUtlLinkedList< CRecvDecoder *, unsigned short > g_RecvDecoders;
  46. extern ConVar tv_autorecord;
  47. static ConVar tv_autoretry( "tv_autoretry", "1", FCVAR_RELEASE, "Relay proxies retry connection after network timeout" );
  48. static ConVar tv_timeout( "tv_timeout", "30", FCVAR_RELEASE, "GOTV connection timeout in seconds." );
  49. ConVar tv_snapshotrate("tv_snapshotrate", "32", FCVAR_RELEASE | FCVAR_REPLICATED, "Snapshots broadcasted per second" ); // for the best quality of replay, use 64
  50. ConVar tv_snapshotrate1( "tv_snapshotrate1", "32", FCVAR_RELEASE, "Snapshots broadcasted per second, GOTV[1]" ); // set this to 128 to record 128-tick server demo
  51. //////////////////////////////////////////////////////////////////////
  52. // Construction/Destruction
  53. //////////////////////////////////////////////////////////////////////
  54. CHLTVClientState::CHLTVClientState(CHLTVServer *pHltvServer) : m_pHLTV( pHltvServer )
  55. {
  56. m_pNewClientFrame = NULL;
  57. m_pCurrentClientFrame = NULL;
  58. m_bSaveMemory = false;
  59. eventid_hltv_status = -1;
  60. eventid_hltv_title = -1;
  61. }
  62. CHLTVClientState::~CHLTVClientState()
  63. {
  64. }
  65. void CHLTVClientState::CopyNewEntity(
  66. CEntityReadInfo &u,
  67. int iClass,
  68. int iSerialNum
  69. )
  70. {
  71. ServerClass *pServerClass = SV_FindServerClass( iClass );
  72. Assert( pServerClass );
  73. ClientClass *pClientClass = GetClientClass( iClass );
  74. Assert( pClientClass );
  75. const int ent = u.m_nNewEntity;
  76. // copy class & serial
  77. CFrameSnapshot *pSnapshot = u.m_pTo->GetSnapshot();
  78. pSnapshot->m_pEntities[ent].m_nSerialNumber = iSerialNum;
  79. pSnapshot->m_pEntities[ent].m_pClass = pServerClass;
  80. // Get either the static or instance baseline.
  81. int nFromTick = 0; // MOTODO get tick when baseline last changed
  82. SerializedEntityHandle_t oldbaseline = SERIALIZED_ENTITY_HANDLE_INVALID;
  83. PackedEntity *baseline = u.m_bAsDelta ? GetEntityBaseline( u.m_nBaseline, ent ) : NULL;
  84. if ( baseline && baseline->m_pClientClass == pClientClass )
  85. {
  86. oldbaseline = baseline->GetPackedData();
  87. }
  88. else
  89. {
  90. // Every entity must have a static or an instance baseline when we get here.
  91. ErrorIfNot(
  92. GetClassBaseline( iClass, &oldbaseline ),
  93. ("HLTV_CopyNewEntity: GetDynamicBaseline(%d) failed.", iClass)
  94. );
  95. }
  96. // create new ChangeFrameList containing all properties set as changed
  97. int nFlatProps = SendTable_GetNumFlatProps( pServerClass->m_pTable );
  98. CChangeFrameList *pChangeFrame = NULL;
  99. if ( !m_bSaveMemory )
  100. {
  101. pChangeFrame = new CChangeFrameList( nFlatProps, nFromTick );
  102. }
  103. // Now make a PackedEntity and store the new packed data in there.
  104. PackedEntity *pPackedEntity = framesnapshotmanager->CreatePackedEntity( pSnapshot, ent );
  105. pPackedEntity->SetChangeFrameList( pChangeFrame );
  106. pPackedEntity->SetServerAndClientClass( pServerClass, pClientClass );
  107. // Make space for the baseline data.
  108. SerializedEntityHandle_t newbaseline = g_pSerializedEntities->AllocateSerializedEntity(__FILE__, __LINE__);
  109. CUtlVector< int > changedProps;
  110. RecvTable_ReadFieldList( pClientClass->m_pRecvTable, *u.m_pBuf, u.m_DecodeEntity, -1, false );
  111. // decode basline, is compressed against zero values
  112. RecvTable_MergeDeltas( pClientClass->m_pRecvTable, oldbaseline, u.m_DecodeEntity, newbaseline, -1, &changedProps );
  113. // update change tick in ChangeFrameList
  114. if ( pChangeFrame )
  115. {
  116. pChangeFrame->SetChangeTick( changedProps.Base(), changedProps.Count(), pSnapshot->m_nTickCount );
  117. }
  118. if ( u.m_bUpdateBaselines )
  119. {
  120. SetEntityBaseline( (u.m_nBaseline==0)?1:0, pClientClass, u.m_nNewEntity, newbaseline );
  121. }
  122. pPackedEntity->CopyPackedData( newbaseline );
  123. // If ent doesn't think it's in PVS, signal that it is
  124. Assert( u.m_pTo->last_entity <= ent );
  125. u.m_pTo->last_entity = ent;
  126. u.m_pTo->transmit_entity.Set( ent );
  127. }
  128. static inline void HLTV_CopyExitingEnt( CEntityReadInfo &u )
  129. {
  130. if ( !u.m_bAsDelta ) // Should never happen on a full update.
  131. {
  132. Assert(0); // GetBaseLocalClient().validsequence = 0;
  133. ConMsg( "WARNING: CopyExitingEnt on full update.\n" );
  134. u.m_UpdateType = Failed; // break out
  135. return;
  136. }
  137. CFrameSnapshot *pFromSnapshot = u.m_pFrom->GetSnapshot(); // get from snapshot
  138. const int ent = u.m_nOldEntity;
  139. CFrameSnapshot *pSnapshot = u.m_pTo->GetSnapshot(); // get to snapshot
  140. // copy ent handle, serial numbers & class info
  141. Assert( ent < pFromSnapshot->m_nNumEntities );
  142. pSnapshot->m_pEntities[ent] = pFromSnapshot->m_pEntities[ent];
  143. Assert( pSnapshot->m_pEntities[ent].m_pPackedData != INVALID_PACKED_ENTITY_HANDLE );
  144. // increase PackedEntity reference counter
  145. PackedEntity *pEntity = framesnapshotmanager->GetPackedEntity( *pSnapshot, ent );
  146. Assert( pEntity );
  147. pEntity->m_ReferenceCount++;
  148. Assert( u.m_pTo->last_entity <= ent );
  149. // mark flags as received
  150. u.m_pTo->last_entity = ent;
  151. u.m_pTo->transmit_entity.Set( ent );
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose: A svc_signonnum has been received, perform a client side setup
  155. // Output : void CL_SignonReply
  156. //-----------------------------------------------------------------------------
  157. bool CHLTVClientState::SetSignonState ( int state, int count, const CNETMsg_SignonState *msg )
  158. {
  159. // ConDMsg ("CL_SignonReply: %i\n", GetBaseLocalClient().signon);
  160. if ( !CBaseClientState::SetSignonState( state, count, msg ) )
  161. return false;
  162. Assert ( m_nSignonState == state );
  163. switch ( m_nSignonState )
  164. {
  165. case SIGNONSTATE_CHALLENGE : break;
  166. case SIGNONSTATE_CONNECTED : {
  167. // allow longer timeout
  168. m_NetChannel->SetTimeout( SIGNON_TIME_OUT );
  169. m_NetChannel->Clear();
  170. // set user settings (rate etc)
  171. CNETMsg_SetConVar_t convars;
  172. Host_BuildUserInfoUpdateMessage( 0, convars.mutable_convars(), false );
  173. // also set all the userinfo vars that we will be modifying for accurate tracking
  174. SetLocalInfoConvarsForUpstreamConnection( *convars.mutable_convars(), true );
  175. m_NetChannel->SendNetMsg( convars );
  176. }
  177. break;
  178. case SIGNONSTATE_NEW : SendClientInfo();
  179. break;
  180. case SIGNONSTATE_PRESPAWN : break;
  181. case SIGNONSTATE_SPAWN : m_pHLTV->SignonComplete();
  182. break;
  183. case SIGNONSTATE_FULL : m_NetChannel->SetTimeout( tv_timeout.GetFloat() );
  184. // start new recording if autorecord is enabled
  185. if ( tv_autorecord.GetBool() )
  186. {
  187. m_pHLTV->m_DemoRecorder.StartAutoRecording();
  188. m_NetChannel->SetDemoRecorder( m_pHLTV->m_DemoRecorder.GetDemoRecorder() );
  189. }
  190. break;
  191. case SIGNONSTATE_CHANGELEVEL: m_pHLTV->Changelevel( true );
  192. m_NetChannel->SetTimeout( SIGNON_TIME_OUT ); // allow 5 minutes timeout
  193. break;
  194. }
  195. if ( m_nSignonState >= SIGNONSTATE_CONNECTED )
  196. {
  197. // tell server that we entered now that state
  198. CNETMsg_SignonState_t signonState( m_nSignonState, count );
  199. m_NetChannel->SendNetMsg( signonState );
  200. }
  201. return true;
  202. }
  203. void CHLTVClientState::SendClientInfo( void )
  204. {
  205. CCLCMsg_ClientInfo_t info;
  206. info.set_send_table_crc( SendTable_GetCRC() );
  207. info.set_server_count( m_nServerCount );
  208. info.set_is_hltv( true );
  209. #if defined( REPLAY_ENABLED )
  210. info.set_is_replay( false );
  211. #endif
  212. info.set_friends_id( 0 );
  213. // info.set_friends_name( "" );
  214. // CheckOwnCustomFiles(); // load & verfiy custom player files
  215. // for ( int i=0; i< MAX_CUSTOM_FILES; i++ )
  216. // info.add_custom_files( "" );
  217. m_NetChannel->SendNetMsg( info );
  218. }
  219. void CHLTVClientState::SendPacket()
  220. {
  221. if ( !IsConnected() )
  222. return;
  223. if ( ( net_time < m_flNextCmdTime ) || !m_NetChannel->CanPacket() )
  224. return;
  225. if ( IsActive() )
  226. {
  227. CNETMsg_Tick_t tick( m_nDeltaTick, host_frameendtime_computationduration, host_frametime_stddeviation, host_framestarttime_stddeviation );
  228. m_NetChannel->SendNetMsg( tick );
  229. }
  230. m_NetChannel->SendDatagram( NULL );
  231. if ( IsActive() )
  232. {
  233. // use full update rate when active
  234. float commandInterval = (2.0f/3.0f) / m_pHLTV->GetSnapshotRate();
  235. float maxDelta = MIN( host_state.interval_per_tick, commandInterval );
  236. float delta = clamp( net_time - m_flNextCmdTime, 0.0f, maxDelta );
  237. m_flNextCmdTime = net_time + commandInterval - delta;
  238. }
  239. else
  240. {
  241. // during signon process send only 5 packets/second
  242. m_flNextCmdTime = net_time + ( 1.0f / 5.0f );
  243. }
  244. }
  245. bool CHLTVClientState::NETMsg_StringCmd(const CNETMsg_StringCmd& msg)
  246. {
  247. CNETMsg_StringCmd_t stringcmd( msg.command().c_str() );
  248. stringcmd.SetReliable( m_NetChannel->WasLastMessageReliable() );
  249. return m_pHLTV->SendNetMsg( stringcmd ); // relay to server
  250. }
  251. bool CHLTVClientState::NETMsg_SetConVar(const CNETMsg_SetConVar& msg)
  252. {
  253. if ( !CBaseClientState::NETMsg_SetConVar( msg ) )
  254. return false;
  255. CNETMsg_SetConVar_t sendmsg;
  256. sendmsg.CopyFrom( msg );
  257. if ( sendmsg.convars().cvars_size() )
  258. { // Make sure convars are expanded using dictionary
  259. for ( int iCV = 0; iCV < sendmsg.convars().cvars_size(); ++iCV )
  260. {
  261. CMsg_CVars::CVar *convar = sendmsg.mutable_convars()->mutable_cvars( iCV );
  262. NetMsgExpandCVarUsingDictionary( convar );
  263. }
  264. }
  265. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  266. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  267. }
  268. bool CHLTVClientState::NETMsg_PlayerAvatarData( const CNETMsg_PlayerAvatarData& msg )
  269. {
  270. // Don't chain to the base client implementation
  271. return m_pHLTV->NETMsg_PlayerAvatarData( msg ); // relay to server
  272. }
  273. void CHLTVClientState::Clear()
  274. {
  275. CBaseClientState::Clear();
  276. m_pNewClientFrame = NULL;
  277. m_pCurrentClientFrame = NULL;
  278. eventid_hltv_status = -1;
  279. eventid_hltv_title = -1;
  280. }
  281. bool CHLTVClientState::SVCMsg_ServerInfo( const CSVCMsg_ServerInfo& msg )
  282. {
  283. // Reset client state
  284. Clear();
  285. // is server a HLTV proxy or demo file ?
  286. if ( !m_pHLTV->IsPlayingBack() )
  287. {
  288. if ( !msg.is_hltv() )
  289. {
  290. ConMsg ( "Server (%s) is not a GOTV proxy.\n", m_NetChannel->GetAddress() );
  291. Disconnect();
  292. return false;
  293. }
  294. }
  295. // tell HLTV relay to clear everything
  296. m_pHLTV->StartRelay();
  297. // Process the message
  298. if ( !CBaseClientState::SVCMsg_ServerInfo( msg ) )
  299. {
  300. Disconnect();
  301. return false;
  302. }
  303. m_StringTableContainer = m_pHLTV->m_StringTables;
  304. Assert( m_StringTableContainer->GetNumTables() == 0); // must be empty
  305. #ifndef SHARED_NET_STRING_TABLES
  306. // relay uses normal string tables without a change history
  307. m_StringTableContainer->EnableRollback( false );
  308. #endif
  309. // copy setting from HLTV client to HLTV server
  310. m_pHLTV->m_nGameServerMaxClients = m_nMaxClients;
  311. m_pHLTV->serverclasses = m_nServerClasses;
  312. m_pHLTV->serverclassbits = m_nServerClassBits;
  313. m_pHLTV->m_nPlayerSlot = m_nPlayerSlot;
  314. // copy other settings to HLTV server
  315. m_pHLTV->worldmapCRC = msg.map_crc();
  316. m_pHLTV->clientDllCRC = msg.client_crc();
  317. m_pHLTV->stringTableCRC = CRC32_ConvertFromUnsignedLong( msg.string_table_crc() );
  318. m_pHLTV->m_flTickInterval = msg.tick_interval();
  319. host_state.interval_per_tick = msg.tick_interval();
  320. Q_strncpy( m_pHLTV->m_szMapname, msg.map_name().c_str(), sizeof(m_pHLTV->m_szMapname) );
  321. Q_strncpy( m_pHLTV->m_szSkyname, msg.sky_name().c_str(), sizeof(m_pHLTV->m_szSkyname) );
  322. return true;
  323. }
  324. bool CHLTVClientState::SVCMsg_ClassInfo( const CSVCMsg_ClassInfo& msg )
  325. {
  326. if ( !msg.create_on_client() )
  327. {
  328. ConMsg("HLTV SendTable CRC differs from server.\n");
  329. Disconnect();
  330. return false;
  331. }
  332. #ifdef _HLTVTEST
  333. RecvTable_Term( false );
  334. #endif
  335. // Create all of the send tables locally
  336. DataTable_CreateClientTablesFromServerTables();
  337. // Now create all of the server classes locally, too
  338. DataTable_CreateClientClassInfosFromServerClasses( this );
  339. LinkClasses(); // link server and client classes
  340. #if defined(DEDICATED)
  341. bool bAllowMismatches = false;
  342. #else
  343. bool bAllowMismatches = ( g_pClientDemoPlayer && g_pClientDemoPlayer->IsPlayingBack() );
  344. #endif
  345. if ( !RecvTable_CreateDecoders( serverGameDLL->GetStandardSendProxies(), bAllowMismatches ) ) // create receive table decoders
  346. {
  347. Host_EndGame( true, "CL_ParseClassInfo_EndClasses: CreateDecoders failed.\n" );
  348. return false;
  349. }
  350. return true;
  351. }
  352. void CHLTVClientState::PacketEnd( void )
  353. {
  354. // did we get a snapshot with this packet ?
  355. if ( m_pNewClientFrame )
  356. {
  357. // if so, add a new frame to HLTV
  358. m_pCurrentClientFrame = m_pHLTV->AddNewFrame( m_pNewClientFrame );
  359. delete m_pNewClientFrame; // release own refernces
  360. m_pNewClientFrame = NULL;
  361. }
  362. }
  363. bool CHLTVClientState::HookClientStringTable( char const *tableName )
  364. {
  365. INetworkStringTable *table = GetStringTable( tableName );
  366. if ( !table )
  367. return false;
  368. // Hook instance baseline table
  369. if ( !Q_strcasecmp( tableName, INSTANCE_BASELINE_TABLENAME ) )
  370. {
  371. table->SetStringChangedCallback( m_pHLTV, HLTV_Callback_InstanceBaseline );
  372. return true;
  373. }
  374. return false;
  375. }
  376. void CHLTVClientState::InstallStringTableCallback( char const *tableName )
  377. {
  378. INetworkStringTable *table = GetStringTable( tableName );
  379. if ( !table )
  380. return;
  381. // Hook instance baseline table
  382. if ( !Q_strcasecmp( tableName, INSTANCE_BASELINE_TABLENAME ) )
  383. {
  384. table->SetStringChangedCallback( m_pHLTV, HLTV_Callback_InstanceBaseline );
  385. return;
  386. }
  387. }
  388. bool CHLTVClientState::SVCMsg_SetView( const CSVCMsg_SetView& msg )
  389. {
  390. if ( !CBaseClientState::SVCMsg_SetView( msg ) )
  391. return false;
  392. CSVCMsg_SetView_t sendmsg;
  393. sendmsg.CopyFrom( msg );
  394. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  395. return m_pHLTV->SendNetMsg( sendmsg );
  396. }
  397. bool CHLTVClientState::SVCMsg_VoiceInit( const CSVCMsg_VoiceInit& msg )
  398. {
  399. CSVCMsg_VoiceInit_t sendmsg;
  400. sendmsg.CopyFrom( msg );
  401. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  402. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  403. }
  404. bool CHLTVClientState::SVCMsg_VoiceData( const CSVCMsg_VoiceData &msg )
  405. {
  406. CSVCMsg_VoiceData_t sendmsg;
  407. sendmsg.CopyFrom( msg );
  408. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  409. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  410. }
  411. bool CHLTVClientState::SVCMsg_EncryptedData( const CSVCMsg_EncryptedData& msg )
  412. {
  413. CSVCMsg_EncryptedData_t sendmsg;
  414. sendmsg.CopyFrom( msg );
  415. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  416. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  417. }
  418. bool CHLTVClientState::SVCMsg_Sounds(const CSVCMsg_Sounds& msg)
  419. {
  420. CSVCMsg_Sounds_t sendmsg;
  421. sendmsg.CopyFrom( msg );
  422. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  423. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  424. }
  425. bool CHLTVClientState::SVCMsg_Prefetch( const CSVCMsg_Prefetch& msg )
  426. {
  427. CSVCMsg_Prefetch_t sendmsg;
  428. sendmsg.CopyFrom( msg );
  429. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  430. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  431. }
  432. bool CHLTVClientState::SVCMsg_FixAngle( const CSVCMsg_FixAngle& msg )
  433. {
  434. CSVCMsg_FixAngle_t sendmsg;
  435. sendmsg.CopyFrom( msg );
  436. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  437. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  438. }
  439. bool CHLTVClientState::SVCMsg_CrosshairAngle( const CSVCMsg_CrosshairAngle& msg )
  440. {
  441. CSVCMsg_CrosshairAngle_t sendmsg;
  442. sendmsg.CopyFrom( msg );
  443. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  444. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  445. }
  446. bool CHLTVClientState::SVCMsg_BSPDecal( const CSVCMsg_BSPDecal& msg )
  447. {
  448. CSVCMsg_BSPDecal_t sendmsg;
  449. sendmsg.CopyFrom( msg );
  450. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  451. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  452. }
  453. bool CHLTVClientState::SVCMsg_GameEvent( const CSVCMsg_GameEvent& msg )
  454. {
  455. const char *pszName = msg.event_name().c_str();
  456. bool bDontForward = false;
  457. if ( msg.eventid() == eventid_hltv_status || Q_strcmp( pszName, "hltv_status" ) == 0 )
  458. {
  459. IGameEvent *event = g_GameEventManager.UnserializeEvent( msg );
  460. m_pHLTV->m_nGlobalSlots = event->GetInt("slots");
  461. m_pHLTV->m_nGlobalProxies = event->GetInt("proxies");
  462. m_pHLTV->m_nGlobalClients = event->GetInt("clients");
  463. m_pHLTV->m_nExternalTotalViewers = event->GetInt( "externaltotal" );
  464. m_pHLTV->m_nExternalLinkedViewers = event->GetInt( "externallinked" );
  465. char const *szMasterAddress = event->GetString("master");
  466. if ( szMasterAddress && *szMasterAddress )
  467. m_pHLTV->m_RootServer.SetFromString( szMasterAddress );
  468. else if ( m_pHLTV->m_RootServer.IsValid() )
  469. m_pHLTV->m_RootServer.Clear();
  470. g_GameEventManager.FreeEvent( event );
  471. bDontForward = true;
  472. // make sure we update GC information now that we updated HLTV status
  473. if ( serverGameDLL && Steam3Server().GetGSSteamID().IsValid() )
  474. serverGameDLL->UpdateGCInformation();
  475. }
  476. else if ( msg.eventid() == eventid_hltv_title || Q_strcmp( pszName, "hltv_title" ) == 0 )
  477. {
  478. // ignore title messages
  479. bDontForward = true;
  480. }
  481. if ( bDontForward )
  482. return true;
  483. // forward event
  484. CSVCMsg_GameEvent_t sendmsg;
  485. sendmsg.CopyFrom( msg );
  486. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  487. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  488. }
  489. bool CHLTVClientState::SVCMsg_GameEventList( const CSVCMsg_GameEventList& msg )
  490. {
  491. if ( !CBaseClientState::SVCMsg_GameEventList( msg ) )
  492. return false;
  493. // cache off the eventids for hltv_status and hltv_title
  494. CGameEventDescriptor *pDescriptor_hltv_status = g_GameEventManager.GetEventDescriptor( "hltv_status" );
  495. CGameEventDescriptor *pDescriptor_hltv_title = g_GameEventManager.GetEventDescriptor( "hltv_title" );
  496. if ( pDescriptor_hltv_status )
  497. {
  498. eventid_hltv_status = pDescriptor_hltv_status->eventid;
  499. }
  500. if ( pDescriptor_hltv_title )
  501. {
  502. eventid_hltv_title = pDescriptor_hltv_title->eventid;
  503. }
  504. CSVCMsg_GameEventList_t sendmsg;
  505. sendmsg.CopyFrom( msg );
  506. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  507. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  508. }
  509. bool CHLTVClientState::SVCMsg_UserMessage( const CSVCMsg_UserMessage& msg )
  510. {
  511. CSVCMsg_UserMessage_t sendmsg;
  512. sendmsg.CopyFrom( msg );
  513. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  514. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  515. }
  516. bool CHLTVClientState::SVCMsg_EntityMsg( const CSVCMsg_EntityMsg& msg )
  517. {
  518. CSVCMsg_EntityMsg_t sendmsg;
  519. sendmsg.CopyFrom( msg );
  520. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  521. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  522. }
  523. bool CHLTVClientState::SVCMsg_Menu( const CSVCMsg_Menu& msg )
  524. {
  525. CSVCMsg_Menu_t sendmsg;
  526. sendmsg.CopyFrom( msg );
  527. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  528. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  529. }
  530. bool CHLTVClientState::SVCMsg_PacketEntities( const CSVCMsg_PacketEntities &msg )
  531. {
  532. CClientFrame *oldFrame = NULL;
  533. #ifdef _HLTVTEST
  534. if ( g_RecvDecoders.Count() == 0 )
  535. return false;
  536. #endif
  537. if ( msg.is_delta() )
  538. {
  539. if ( GetServerTickCount() == msg.delta_from() )
  540. {
  541. Host_Error( "Update self-referencing, connection dropped.\n" );
  542. return false;
  543. }
  544. // Otherwise, mark where we are valid to and point to the packet entities we'll be updating from.
  545. oldFrame = m_pHLTV->GetClientFrame( msg.delta_from() );
  546. }
  547. // create new empty snapshot
  548. CFrameSnapshot* pSnapshot = framesnapshotmanager->CreateEmptySnapshot(
  549. #ifdef DEBUG_SNAPSHOT_REFERENCES
  550. "CHLTVClientState::SVCMsg_PacketEntities",
  551. #endif
  552. GetServerTickCount(), msg.max_entries() );
  553. Assert( m_pNewClientFrame == NULL );
  554. m_pNewClientFrame = new CClientFrame( pSnapshot );
  555. Assert( msg.baseline() >= 0 && msg.baseline() < 2 );
  556. if ( msg.update_baseline() )
  557. {
  558. // server requested to use this snapshot as baseline update
  559. int nUpdateBaseline = (msg.baseline() == 0) ? 1 : 0;
  560. CopyEntityBaseline( msg.baseline(), nUpdateBaseline );
  561. // send new baseline acknowledgement(as reliable)
  562. CCLCMsg_BaselineAck_t baseline;
  563. baseline.set_baseline_tick( GetServerTickCount() );
  564. baseline.set_baseline_nr( msg.baseline() );
  565. m_NetChannel->SendNetMsg( baseline, true );
  566. }
  567. // copy classes and serial numbers from current frame
  568. if ( m_pCurrentClientFrame )
  569. {
  570. CFrameSnapshot* pLastSnapshot = m_pCurrentClientFrame->GetSnapshot();
  571. CFrameSnapshotEntry *pEntry = pSnapshot->m_pEntities;
  572. CFrameSnapshotEntry *pLastEntry = pLastSnapshot->m_pEntities;
  573. Assert( pLastSnapshot->m_nNumEntities <= pSnapshot->m_nNumEntities );
  574. for ( int i = 0; i<pLastSnapshot->m_nNumEntities; i++ )
  575. {
  576. pEntry->m_nSerialNumber = pLastEntry->m_nSerialNumber;
  577. pEntry->m_pClass = pLastEntry->m_pClass;
  578. pEntry++;
  579. pLastEntry++;
  580. }
  581. }
  582. CEntityReadInfo u;
  583. bf_read entityBuf( &msg.entity_data()[0], msg.entity_data().size() );
  584. u.m_pBuf = &entityBuf;
  585. u.m_pFrom = oldFrame;
  586. u.m_pTo = m_pNewClientFrame;
  587. u.m_bAsDelta = msg.is_delta();
  588. u.m_nHeaderCount = msg.updated_entries();
  589. u.m_nBaseline = msg.baseline();
  590. u.m_bUpdateBaselines = msg.update_baseline();
  591. ReadPacketEntities( u );
  592. // adjust reference count to be 1
  593. pSnapshot->ReleaseReference();
  594. return CBaseClientState::SVCMsg_PacketEntities( msg );
  595. }
  596. bool CHLTVClientState::SVCMsg_TempEntities( const CSVCMsg_TempEntities &msg )
  597. {
  598. CSVCMsg_TempEntities_t copy;
  599. copy.CopyFrom( msg );
  600. copy.SetReliable( m_NetChannel->WasLastMessageReliable() );
  601. return m_pHLTV->SendNetMsg( copy ); // relay to server
  602. }
  603. bool CHLTVClientState::SVCMsg_PaintmapData( const CSVCMsg_PaintmapData& msg )
  604. {
  605. CSVCMsg_PaintmapData_t sendmsg;
  606. sendmsg.CopyFrom( msg );
  607. sendmsg.SetReliable( m_NetChannel->WasLastMessageReliable() );
  608. return m_pHLTV->SendNetMsg( sendmsg ); // relay to server
  609. }
  610. void CHLTVClientState::ReadEnterPVS( CEntityReadInfo &u )
  611. {
  612. int iClass = u.m_pBuf->ReadUBitLong( m_nServerClassBits );
  613. int iSerialNum = u.m_pBuf->ReadUBitLong( NUM_NETWORKED_EHANDLE_SERIAL_NUMBER_BITS );
  614. CopyNewEntity( u, iClass, iSerialNum );
  615. if ( u.m_nNewEntity == u.m_nOldEntity ) // that was a recreate
  616. u.NextOldEntity();
  617. }
  618. void CHLTVClientState::ReadLeavePVS( CEntityReadInfo &u )
  619. {
  620. // do nothing, this entity was removed
  621. Assert( !u.m_pTo->transmit_entity.Get(u.m_nOldEntity) );
  622. if ( u.m_UpdateFlags & FHDR_DELETE )
  623. {
  624. CFrameSnapshot *pSnapshot = u.m_pTo->GetSnapshot();
  625. CFrameSnapshotEntry *pEntry = &pSnapshot->m_pEntities[u.m_nOldEntity];
  626. // clear entity references
  627. pEntry->m_nSerialNumber = -1;
  628. pEntry->m_pClass = NULL;
  629. Assert( pEntry->m_pPackedData == INVALID_PACKED_ENTITY_HANDLE );
  630. }
  631. u.NextOldEntity();
  632. }
  633. void CHLTVClientState::ReadDeltaEnt( CEntityReadInfo &u )
  634. {
  635. const int i = u.m_nNewEntity;
  636. CFrameSnapshot *pFromSnapshot = u.m_pFrom->GetSnapshot();
  637. CFrameSnapshot *pSnapshot = u.m_pTo->GetSnapshot();
  638. Assert( i < pFromSnapshot->m_nNumEntities );
  639. pSnapshot->m_pEntities[i] = pFromSnapshot->m_pEntities[i];
  640. PackedEntity *pToPackedEntity = framesnapshotmanager->CreatePackedEntity( pSnapshot, i );
  641. // WARNING! get pFromPackedEntity after new pPackedEntity has been created, otherwise pointer may be wrong
  642. PackedEntity *pFromPackedEntity = framesnapshotmanager->GetPackedEntity( *pFromSnapshot, i );
  643. pToPackedEntity->SetServerAndClientClass( pFromPackedEntity->m_pServerClass, pFromPackedEntity->m_pClientClass );
  644. // create a copy of the pFromSnapshot ChangeFrameList
  645. CChangeFrameList* pChangeFrame = pFromPackedEntity->GetChangeFrameList()->Copy();
  646. pToPackedEntity->SetChangeFrameList( pChangeFrame );
  647. // Make space for the baseline data.
  648. SerializedEntityHandle_t fromEntity = pFromPackedEntity->GetPackedData();
  649. SerializedEntityHandle_t outEntity = g_pSerializedEntities->AllocateSerializedEntity(__FILE__, __LINE__);
  650. CUtlVector< int > changedProps;
  651. RecvTable_ReadFieldList( pToPackedEntity->m_pClientClass->m_pRecvTable, *u.m_pBuf, u.m_DecodeEntity, -1, false );
  652. // decode baseline, is compressed against zero values
  653. RecvTable_MergeDeltas( pToPackedEntity->m_pClientClass->m_pRecvTable,
  654. fromEntity, u.m_DecodeEntity, outEntity, -1, &changedProps );
  655. // update change tick in ChangeFrameList
  656. if ( pChangeFrame )
  657. {
  658. pChangeFrame->SetChangeTick( changedProps.Base(), changedProps.Count(), pSnapshot->m_nTickCount );
  659. }
  660. // store as normal
  661. pToPackedEntity->SetPackedData( outEntity );
  662. u.m_pTo->last_entity = u.m_nNewEntity;
  663. u.m_pTo->transmit_entity.Set( u.m_nNewEntity );
  664. u.NextOldEntity();
  665. }
  666. void CHLTVClientState::ReadPreserveEnt( CEntityReadInfo &u )
  667. {
  668. // copy one of the old entities over to the new packet unchanged
  669. if ( u.m_nNewEntity < 0 || u.m_nNewEntity >= MAX_EDICTS )
  670. {
  671. Host_Error ("CL_ReadPreserveEnt: u.m_nNewEntity == MAX_EDICTS");
  672. }
  673. HLTV_CopyExitingEnt( u );
  674. u.NextOldEntity();
  675. }
  676. void CHLTVClientState::ReadDeletions( CEntityReadInfo &u )
  677. {
  678. int nBase = -1;
  679. int nCount = u.m_pBuf->ReadUBitVar();
  680. for ( int i = 0; i < nCount; ++i )
  681. {
  682. int nDelta = u.m_pBuf->ReadUBitVar();
  683. int nSlot = nBase + nDelta;
  684. Assert( !u.m_pTo->transmit_entity.Get( nSlot ) );
  685. CFrameSnapshot *pSnapshot = u.m_pTo->GetSnapshot();
  686. CFrameSnapshotEntry *pEntry = &pSnapshot->m_pEntities[nSlot];
  687. // clear entity references
  688. pEntry->m_nSerialNumber = -1;
  689. pEntry->m_pClass = NULL;
  690. Assert( pEntry->m_pPackedData == INVALID_PACKED_ENTITY_HANDLE );
  691. nBase = nSlot;
  692. }
  693. }
  694. // Returns false if you should stop reading entities.
  695. inline static bool CL_DetermineUpdateType( CEntityReadInfo &u )
  696. {
  697. if ( !u.m_bIsEntity || ( u.m_nNewEntity > u.m_nOldEntity ) )
  698. {
  699. // If we're at the last entity, preserve whatever entities followed it in the old packet.
  700. // If newnum > oldnum, then the server skipped sending entities that it wants to leave the state alone for.
  701. if ( !u.m_pFrom || ( u.m_nOldEntity > u.m_pFrom->last_entity ) )
  702. {
  703. Assert( !u.m_bIsEntity );
  704. u.m_UpdateType = Finished;
  705. return false;
  706. }
  707. // Preserve entities until we reach newnum (ie: the server didn't send certain entities because
  708. // they haven't changed).
  709. u.m_UpdateType = PreserveEnt;
  710. }
  711. else
  712. {
  713. if( u.m_UpdateFlags & FHDR_ENTERPVS )
  714. {
  715. u.m_UpdateType = EnterPVS;
  716. }
  717. else if( u.m_UpdateFlags & FHDR_LEAVEPVS )
  718. {
  719. u.m_UpdateType = LeavePVS;
  720. }
  721. else
  722. {
  723. u.m_UpdateType = DeltaEnt;
  724. }
  725. }
  726. return true;
  727. }
  728. static inline void CL_ParseDeltaHeader( CEntityReadInfo &u )
  729. {
  730. u.m_UpdateFlags = FHDR_ZERO;
  731. #ifdef DEBUG_NETWORKING
  732. int startbit = u.m_pBuf->GetNumBitsRead();
  733. #endif
  734. u.m_nNewEntity = u.m_nHeaderBase + 1 + u.m_pBuf->ReadUBitVar();
  735. u.m_nHeaderBase = u.m_nNewEntity;
  736. // leave pvs flag
  737. if ( u.m_pBuf->ReadOneBit() == 0 )
  738. {
  739. // enter pvs flag
  740. if ( u.m_pBuf->ReadOneBit() != 0 )
  741. {
  742. u.m_UpdateFlags |= FHDR_ENTERPVS;
  743. }
  744. }
  745. else
  746. {
  747. u.m_UpdateFlags |= FHDR_LEAVEPVS;
  748. // Force delete flag
  749. if ( u.m_pBuf->ReadOneBit() != 0 )
  750. {
  751. u.m_UpdateFlags |= FHDR_DELETE;
  752. }
  753. }
  754. // Output the bitstream...
  755. #ifdef DEBUG_NETWORKING
  756. int lastbit = u.m_pBuf->GetNumBitsRead();
  757. {
  758. void SpewBitStream( unsigned char* pMem, int bit, int lastbit );
  759. SpewBitStream( (byte *)u.m_pBuf->m_pData, startbit, lastbit );
  760. }
  761. #endif
  762. }
  763. void CHLTVClientState::ReadPacketEntities( CEntityReadInfo &u )
  764. {
  765. // Loop until there are no more entities to read
  766. u.NextOldEntity();
  767. while ( u.m_UpdateType < Finished )
  768. {
  769. u.m_nHeaderCount--;
  770. u.m_bIsEntity = ( u.m_nHeaderCount >= 0 ) ? true : false;
  771. if ( u.m_bIsEntity )
  772. {
  773. CL_ParseDeltaHeader( u );
  774. }
  775. u.m_UpdateType = PreserveEnt;
  776. while( u.m_UpdateType == PreserveEnt )
  777. {
  778. // Figure out what kind of an update this is.
  779. if( CL_DetermineUpdateType( u ) )
  780. {
  781. switch( u.m_UpdateType )
  782. {
  783. case EnterPVS: ReadEnterPVS( u );
  784. break;
  785. case LeavePVS: ReadLeavePVS( u );
  786. break;
  787. case DeltaEnt: ReadDeltaEnt( u );
  788. break;
  789. case PreserveEnt: ReadPreserveEnt( u );
  790. break;
  791. default: DevMsg(1, "ReadPacketEntities: unknown updatetype %i\n", u.m_UpdateType );
  792. break;
  793. }
  794. }
  795. }
  796. }
  797. // Now process explicit deletes
  798. if ( u.m_bAsDelta && u.m_UpdateType == Finished )
  799. {
  800. ReadDeletions( u );
  801. }
  802. // Something didn't parse...
  803. if ( u.m_pBuf->IsOverflowed() )
  804. {
  805. Host_Error ( "CL_ParsePacketEntities: buffer read overflow\n" );
  806. }
  807. // If we get an uncompressed packet, then the server is waiting for us to ack the validsequence
  808. // that we got the uncompressed packet on. So we stop reading packets here and force ourselves to
  809. // send the clc_move on the next frame.
  810. if ( !u.m_bAsDelta )
  811. {
  812. m_flNextCmdTime = 0.0; // answer ASAP to confirm full update tick
  813. }
  814. }
  815. int CHLTVClientState::GetConnectionRetryNumber() const
  816. {
  817. if ( tv_autoretry.GetBool() )
  818. {
  819. // in autoretry mode try extra long
  820. return CL_CONNECTION_RETRIES * 4;
  821. }
  822. return CBaseClientState::GetConnectionRetryNumber();
  823. }
  824. void CHLTVClientState::ConnectionCrashed(const char *reason)
  825. {
  826. CBaseClientState::ConnectionCrashed( reason );
  827. if ( tv_autoretry.GetBool() && m_Remote.Count() > 0 )
  828. {
  829. Cbuf_AddText( Cbuf_GetCurrentPlayer(), va( "tv_relay %s\n", m_Remote.Get( 0 ).m_szRetryAddress.String() ) );
  830. }
  831. }
  832. void CHLTVClientState::ConnectionClosing( const char *reason )
  833. {
  834. CBaseClientState::ConnectionClosing( reason );
  835. if ( tv_autoretry.GetBool() && m_Remote.Count() > 0 )
  836. {
  837. Cbuf_AddText( Cbuf_GetCurrentPlayer(), va( "tv_relay %s\n", m_Remote.Get( 0 ).m_szRetryAddress.String() ) );
  838. }
  839. }
  840. void CHLTVClientState::Disconnect( bool bShowMainMenu /* = true */ )
  841. {
  842. CBaseClientState::Disconnect( bShowMainMenu );
  843. // Update hibernation state on the main server which controls hibernation and shutdown criteria
  844. sv.UpdateHibernationState();
  845. // Shutdown if we are an official relay
  846. if ( serverGameDLL && serverGameDLL->IsValveDS() && !sv.IsActive() )
  847. {
  848. Msg( "Official relay disconnected and shutting down...\n" );
  849. Cbuf_AddText( CBUF_SERVER, "quit;\n" );
  850. }
  851. }
  852. void CHLTVClientState::RunFrame()
  853. {
  854. CBaseClientState::RunFrame();
  855. if ( m_NetChannel && m_NetChannel->IsTimedOut() && IsConnected() )
  856. {
  857. ConMsg ("\nGOTV connection timed out.\n");
  858. Disconnect();
  859. return;
  860. }
  861. UpdateStats();
  862. }
  863. void CHLTVClientState::SetLocalInfoConvarsForUpstreamConnection( CMsg_CVars &cvars, bool bMaxSlots )
  864. {
  865. int proxies, slots, clients;
  866. m_pHLTV->GetRelayStats( proxies, slots, clients );
  867. extern ConVar tv_maxclients_relayreserved;
  868. int numSlots = m_pHLTV->GetMaxClients();
  869. if ( !numSlots && bMaxSlots )
  870. {
  871. extern ConVar tv_maxclients;
  872. numSlots = tv_maxclients.GetInt();
  873. }
  874. if ( tv_maxclients_relayreserved.GetInt() > 0 )
  875. numSlots -= tv_maxclients_relayreserved.GetInt();
  876. numSlots = MAX( 0, numSlots );
  877. int numClients = m_pHLTV->GetNumClients();
  878. if ( numClients > numSlots )
  879. numSlots = numClients;
  880. proxies += 1; // add self to number of proxies
  881. slots += numSlots; // add own slots
  882. clients += numClients; // add own clients
  883. // let server know that we are a proxy server and all our stats
  884. NetMsgSetCVarUsingDictionary( cvars.add_cvars(), "tv_relay", "1" );
  885. NetMsgSetCVarUsingDictionary( cvars.add_cvars(), "hltv_proxies", va( "%d", proxies ) );
  886. NetMsgSetCVarUsingDictionary( cvars.add_cvars(), "hltv_clients", va( "%d", clients ) );
  887. NetMsgSetCVarUsingDictionary( cvars.add_cvars(), "hltv_slots", va( "%d", slots ) );
  888. static ConVarRef ipname_relay( "ip_relay" ); // Override relay IP for NAT hosts
  889. netadr_t netAdrHltvRelay( net_local_adr );
  890. if ( ipname_relay.IsValid() && ipname_relay.GetString()[0] )
  891. {
  892. netadr_t netAdrIpRelay;
  893. NET_StringToAdr( ipname_relay.GetString(), &netAdrIpRelay );
  894. if ( !netAdrIpRelay.IsLoopback() && !netAdrIpRelay.IsLocalhost() &&
  895. netAdrIpRelay.IsBaseAdrValid() )
  896. {
  897. // Good address specified in ipname_relay
  898. netAdrHltvRelay = netAdrIpRelay;
  899. }
  900. }
  901. NetMsgSetCVarUsingDictionary( cvars.add_cvars(), "hltv_addr", va( "%s:%u", netAdrHltvRelay.ToString( true ), m_pHLTV->GetUDPPort() ) );
  902. static ConVarRef sv_steamdatagramtransport_port( "sv_steamdatagramtransport_port" );
  903. if ( serverGameDLL->IsValveDS() && sv_steamdatagramtransport_port.GetInt() > 0 )
  904. {
  905. ns_address nsadrsdr;
  906. nsadrsdr.SetAddrType( NSAT_PROXIED_GAMESERVER );
  907. nsadrsdr.m_steamID.SetFromSteamID( Steam3Server().GetGSSteamID(), sv_steamdatagramtransport_port.GetInt() );
  908. NetMsgSetCVarUsingDictionary( cvars.add_cvars(), "hltv_sdr", ns_address_render( nsadrsdr ).String() );
  909. }
  910. }
  911. void CHLTVClientState::UpdateStats()
  912. {
  913. if ( m_nSignonState < SIGNONSTATE_FULL )
  914. {
  915. m_fNextSendUpdateTime = 0.0f;
  916. return;
  917. }
  918. if ( m_fNextSendUpdateTime > net_time )
  919. return;
  920. m_fNextSendUpdateTime = net_time + 8.0f;
  921. CNETMsg_SetConVar_t conVars;
  922. SetLocalInfoConvarsForUpstreamConnection( *conVars.mutable_convars() );
  923. m_NetChannel->SendNetMsg( conVars );
  924. }