Team Fortress 2 Source Code as on 22/4/2020
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.

2069 lines
52 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "netmessages.h"
  7. #include "bitbuf.h"
  8. #include "const.h"
  9. #include "../engine/net_chan.h"
  10. #include "mathlib/mathlib.h"
  11. #include "networkstringtabledefs.h"
  12. #include "../engine/event_system.h"
  13. #include "../engine/dt.h"
  14. #include "tier0/vprof.h"
  15. #include "convar.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. // XXX(JohnS): This is no longer used, but we're keeping it so we can check if old network streams set it to work around
  19. // missing information in the older SVC_VoiceInit packet. See SVC_VoiceInit::ReadFromBuffer
  20. ConVar sv_use_steam_voice( "sv_use_steam_voice", "0", FCVAR_HIDDEN | FCVAR_REPLICATED,
  21. "Deprecated - placeholder convar for handling old network streams that "
  22. "had an incomplete SVC_VoiceInit packet. Use \"sv_voicecodec steam\"" );
  23. static char s_text[1024];
  24. const char *CLC_VoiceData::ToString(void) const
  25. {
  26. Q_snprintf(s_text, sizeof(s_text), "%s: %i bytes", GetName(), Bits2Bytes(m_nLength) );
  27. return s_text;
  28. }
  29. bool CLC_VoiceData::WriteToBuffer( bf_write &buffer )
  30. {
  31. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  32. m_nLength = m_DataOut.GetNumBitsWritten();
  33. buffer.WriteWord( m_nLength ); // length in bits
  34. //Send this client's XUID (only needed on the 360)
  35. #if defined ( _X360 )
  36. buffer.WriteLongLong( m_xuid );
  37. #endif
  38. return buffer.WriteBits( m_DataOut.GetBasePointer(), m_nLength );
  39. }
  40. bool CLC_VoiceData::ReadFromBuffer( bf_read &buffer )
  41. {
  42. VPROF( "CLC_VoiceData::ReadFromBuffer" );
  43. m_nLength = buffer.ReadWord(); // length in bits
  44. #if defined ( _X360 )
  45. m_xuid = buffer.ReadLongLong();
  46. #endif
  47. m_DataIn = buffer;
  48. return buffer.SeekRelative( m_nLength );
  49. }
  50. const char *CLC_Move::ToString(void) const
  51. {
  52. Q_snprintf(s_text, sizeof(s_text), "%s: backup %i, new %i, bytes %i", GetName(),
  53. m_nNewCommands, m_nBackupCommands, Bits2Bytes(m_nLength) );
  54. return s_text;
  55. }
  56. bool CLC_Move::WriteToBuffer( bf_write &buffer )
  57. {
  58. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  59. m_nLength = m_DataOut.GetNumBitsWritten();
  60. buffer.WriteUBitLong( m_nNewCommands, NUM_NEW_COMMAND_BITS );
  61. buffer.WriteUBitLong( m_nBackupCommands, NUM_BACKUP_COMMAND_BITS );
  62. buffer.WriteWord( m_nLength );
  63. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  64. }
  65. bool CLC_Move::ReadFromBuffer( bf_read &buffer )
  66. {
  67. VPROF( "CLC_Move::ReadFromBuffer" );
  68. m_nNewCommands = buffer.ReadUBitLong( NUM_NEW_COMMAND_BITS );
  69. m_nBackupCommands = buffer.ReadUBitLong( NUM_BACKUP_COMMAND_BITS );
  70. m_nLength = buffer.ReadWord();
  71. m_DataIn = buffer;
  72. return buffer.SeekRelative( m_nLength );
  73. }
  74. const char *CLC_ClientInfo::ToString(void) const
  75. {
  76. Q_snprintf(s_text, sizeof(s_text), "%s: SendTableCRC %i", GetName(),
  77. m_nSendTableCRC );
  78. return s_text;
  79. }
  80. bool CLC_ClientInfo::WriteToBuffer( bf_write &buffer )
  81. {
  82. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  83. buffer.WriteLong( m_nServerCount );
  84. buffer.WriteLong( m_nSendTableCRC );
  85. buffer.WriteOneBit( m_bIsHLTV?1:0 );
  86. buffer.WriteLong( m_nFriendsID );
  87. buffer.WriteString( m_FriendsName );
  88. for ( int i=0; i<MAX_CUSTOM_FILES; i++ )
  89. {
  90. if ( m_nCustomFiles[i] != 0 )
  91. {
  92. buffer.WriteOneBit( 1 );
  93. buffer.WriteUBitLong( m_nCustomFiles[i], 32 );
  94. }
  95. else
  96. {
  97. buffer.WriteOneBit( 0 );
  98. }
  99. }
  100. #if defined( REPLAY_ENABLED )
  101. buffer.WriteOneBit( m_bIsReplay?1:0 );
  102. #endif
  103. return !buffer.IsOverflowed();
  104. }
  105. bool CLC_ClientInfo::ReadFromBuffer( bf_read &buffer )
  106. {
  107. VPROF( "CLC_ClientInfo::ReadFromBuffer" );
  108. m_nServerCount = buffer.ReadLong();
  109. m_nSendTableCRC = buffer.ReadLong();
  110. m_bIsHLTV = buffer.ReadOneBit()!=0;
  111. m_nFriendsID = buffer.ReadLong();
  112. buffer.ReadString( m_FriendsName, sizeof(m_FriendsName) );
  113. for ( int i=0; i<MAX_CUSTOM_FILES; i++ )
  114. {
  115. if ( buffer.ReadOneBit() != 0 )
  116. {
  117. m_nCustomFiles[i] = buffer.ReadUBitLong( 32 );
  118. }
  119. else
  120. {
  121. m_nCustomFiles[i] = 0;
  122. }
  123. }
  124. #if defined( REPLAY_ENABLED )
  125. m_bIsReplay = buffer.ReadOneBit()!=0;
  126. #endif
  127. return !buffer.IsOverflowed();
  128. }
  129. bool CLC_BaselineAck::WriteToBuffer( bf_write &buffer )
  130. {
  131. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  132. buffer.WriteLong( m_nBaselineTick );
  133. buffer.WriteUBitLong( m_nBaselineNr, 1 );
  134. return !buffer.IsOverflowed();
  135. }
  136. bool CLC_BaselineAck::ReadFromBuffer( bf_read &buffer )
  137. {
  138. VPROF( "CLC_BaselineAck::ReadFromBuffer" );
  139. m_nBaselineTick = buffer.ReadLong();
  140. m_nBaselineNr = buffer.ReadUBitLong( 1 );
  141. return !buffer.IsOverflowed();
  142. }
  143. const char *CLC_BaselineAck::ToString(void) const
  144. {
  145. Q_snprintf(s_text, sizeof(s_text), "%s: tick %i", GetName(), m_nBaselineTick );
  146. return s_text;
  147. }
  148. bool CLC_ListenEvents::WriteToBuffer( bf_write &buffer )
  149. {
  150. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  151. int count = MAX_EVENT_NUMBER / 32;
  152. for ( int i = 0; i < count; ++i )
  153. {
  154. buffer.WriteUBitLong( m_EventArray.GetDWord( i ), 32 );
  155. }
  156. return !buffer.IsOverflowed();
  157. }
  158. bool CLC_ListenEvents::ReadFromBuffer( bf_read &buffer )
  159. {
  160. VPROF( "CLC_ListenEvents::ReadFromBuffer" );
  161. int count = MAX_EVENT_NUMBER / 32;
  162. for ( int i = 0; i < count; ++i )
  163. {
  164. m_EventArray.SetDWord( i, buffer.ReadUBitLong( 32 ) );
  165. }
  166. return !buffer.IsOverflowed();
  167. }
  168. const char *CLC_ListenEvents::ToString(void) const
  169. {
  170. int count = 0;
  171. for ( int i = 0; i<MAX_EVENT_NUMBER; i++ )
  172. {
  173. if ( m_EventArray.Get( i ) )
  174. count++;
  175. }
  176. Q_snprintf(s_text, sizeof(s_text), "%s: registered events %i", GetName(), count );
  177. return s_text;
  178. }
  179. bool CLC_RespondCvarValue::WriteToBuffer( bf_write &buffer )
  180. {
  181. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  182. buffer.WriteSBitLong( m_iCookie, 32 );
  183. buffer.WriteSBitLong( m_eStatusCode, 4 );
  184. buffer.WriteString( m_szCvarName );
  185. buffer.WriteString( m_szCvarValue );
  186. return !buffer.IsOverflowed();
  187. }
  188. bool CLC_RespondCvarValue::ReadFromBuffer( bf_read &buffer )
  189. {
  190. VPROF( "CLC_RespondCvarValue::ReadFromBuffer" );
  191. m_iCookie = buffer.ReadSBitLong( 32 );
  192. m_eStatusCode = (EQueryCvarValueStatus)buffer.ReadSBitLong( 4 );
  193. // Read the name.
  194. buffer.ReadString( m_szCvarNameBuffer, sizeof( m_szCvarNameBuffer ) );
  195. m_szCvarName = m_szCvarNameBuffer;
  196. // Read the value.
  197. buffer.ReadString( m_szCvarValueBuffer, sizeof( m_szCvarValueBuffer ) );
  198. m_szCvarValue = m_szCvarValueBuffer;
  199. return !buffer.IsOverflowed();
  200. }
  201. const char *CLC_RespondCvarValue::ToString(void) const
  202. {
  203. Q_snprintf( s_text, sizeof(s_text), "%s: status: %d, value: %s, cookie: %d", GetName(), m_eStatusCode, m_szCvarValue, m_iCookie );
  204. return s_text;
  205. }
  206. const char *g_MostCommonPathIDs[] =
  207. {
  208. "GAME",
  209. "MOD"
  210. };
  211. const char *g_MostCommonPrefixes[] =
  212. {
  213. "materials",
  214. "models",
  215. "sounds",
  216. "scripts"
  217. };
  218. static int FindCommonPathID( const char *pPathID )
  219. {
  220. for ( int i=0; i < ARRAYSIZE( g_MostCommonPathIDs ); i++ )
  221. {
  222. if ( V_stricmp( pPathID, g_MostCommonPathIDs[i] ) == 0 )
  223. return i;
  224. }
  225. return -1;
  226. }
  227. static int FindCommonPrefix( const char *pStr )
  228. {
  229. for ( int i=0; i < ARRAYSIZE( g_MostCommonPrefixes ); i++ )
  230. {
  231. if ( V_stristr( pStr, g_MostCommonPrefixes[i] ) == pStr )
  232. {
  233. int iNextChar = V_strlen( g_MostCommonPrefixes[i] );
  234. if ( pStr[iNextChar] == '/' || pStr[iNextChar] == '\\' )
  235. return i;
  236. }
  237. }
  238. return -1;
  239. }
  240. bool CLC_FileCRCCheck::WriteToBuffer( bf_write &buffer )
  241. {
  242. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  243. // Reserved for future use.
  244. buffer.WriteOneBit( 0 );
  245. // Just write a couple bits for the path ID if it's one of the common ones.
  246. int iCode = FindCommonPathID( m_szPathID );
  247. if ( iCode == -1 )
  248. {
  249. buffer.WriteUBitLong( 0, 2 );
  250. buffer.WriteString( m_szPathID );
  251. }
  252. else
  253. {
  254. buffer.WriteUBitLong( iCode+1, 2 );
  255. }
  256. iCode = FindCommonPrefix( m_szFilename );
  257. if ( iCode == -1 )
  258. {
  259. buffer.WriteUBitLong( 0, 3 );
  260. buffer.WriteChar( 1 ); // so we can detect the new message version
  261. buffer.WriteString( m_szFilename );
  262. }
  263. else
  264. {
  265. buffer.WriteUBitLong( iCode+1, 3 );
  266. buffer.WriteChar( 1 ); // so we can detect the new message version
  267. buffer.WriteString( &m_szFilename[ V_strlen(g_MostCommonPrefixes[iCode])+1 ] );
  268. }
  269. buffer.WriteBits( &m_MD5.bits, sizeof(m_MD5.bits)*8 );
  270. buffer.WriteUBitLong( m_CRCIOs, 32 );
  271. buffer.WriteUBitLong( m_eFileHashType, 32 );
  272. buffer.WriteUBitLong( m_cbFileLen, 32 );
  273. buffer.WriteUBitLong( m_nPackFileNumber, 32 );
  274. buffer.WriteUBitLong( m_PackFileID, 32 );
  275. buffer.WriteUBitLong( m_nFileFraction, 32 );
  276. return !buffer.IsOverflowed();
  277. }
  278. bool CLC_FileCRCCheck::ReadFromBuffer( bf_read &buffer )
  279. {
  280. VPROF( "CLC_FileCRCCheck::ReadFromBuffer" );
  281. // Reserved for future use.
  282. buffer.ReadOneBit();
  283. // Read the path ID.
  284. int iCode = buffer.ReadUBitLong( 2 );
  285. if ( iCode == 0 )
  286. {
  287. buffer.ReadString( m_szPathID, sizeof( m_szPathID ) );
  288. }
  289. else if ( (iCode-1) < ARRAYSIZE( g_MostCommonPathIDs ) )
  290. {
  291. V_strncpy( m_szPathID, g_MostCommonPathIDs[iCode-1], sizeof( m_szPathID ) );
  292. }
  293. else
  294. {
  295. Assert( !"Invalid path ID code in CLC_FileCRCCheck" );
  296. return false;
  297. }
  298. // Prefix string
  299. iCode = buffer.ReadUBitLong( 3 );
  300. // Read filename, and check for the new message format version?
  301. char szTemp[ MAX_PATH ];
  302. int c = buffer.ReadChar();
  303. bool bNewVersion = false;
  304. if ( c == 1 )
  305. {
  306. bNewVersion = true;
  307. buffer.ReadString( szTemp, sizeof( szTemp ) );
  308. }
  309. else
  310. {
  311. szTemp[0] = (char)c;
  312. buffer.ReadString( szTemp+1, sizeof( szTemp)-1 );
  313. }
  314. if ( iCode == 0 )
  315. {
  316. V_strcpy_safe( m_szFilename, szTemp );
  317. }
  318. else if ( (iCode-1) < ARRAYSIZE( g_MostCommonPrefixes ) )
  319. {
  320. V_sprintf_safe( m_szFilename, "%s%c%s", g_MostCommonPrefixes[iCode-1], CORRECT_PATH_SEPARATOR, szTemp );
  321. }
  322. else
  323. {
  324. Assert( !"Invalid prefix code in CLC_FileCRCCheck." );
  325. return false;
  326. }
  327. if ( bNewVersion )
  328. {
  329. buffer.ReadBits( &m_MD5.bits, sizeof(m_MD5.bits)*8 );
  330. m_CRCIOs = buffer.ReadUBitLong( 32 );
  331. m_eFileHashType = buffer.ReadUBitLong( 32 );
  332. m_cbFileLen = buffer.ReadUBitLong( 32 );
  333. m_nPackFileNumber = buffer.ReadUBitLong( 32 );
  334. m_PackFileID = buffer.ReadUBitLong( 32 );
  335. m_nFileFraction = buffer.ReadUBitLong( 32 );
  336. }
  337. else
  338. {
  339. /* m_CRC */ buffer.ReadUBitLong( 32 );
  340. m_CRCIOs = buffer.ReadUBitLong( 32 );
  341. m_eFileHashType = buffer.ReadUBitLong( 32 );
  342. }
  343. return !buffer.IsOverflowed();
  344. }
  345. const char *CLC_FileCRCCheck::ToString(void) const
  346. {
  347. V_snprintf( s_text, sizeof(s_text), "%s: path: %s, file: %s", GetName(), m_szPathID, m_szFilename );
  348. return s_text;
  349. }
  350. bool CLC_FileMD5Check::WriteToBuffer( bf_write &buffer )
  351. {
  352. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  353. // Reserved for future use.
  354. buffer.WriteOneBit( 0 );
  355. // Just write a couple bits for the path ID if it's one of the common ones.
  356. int iCode = FindCommonPathID( m_szPathID );
  357. if ( iCode == -1 )
  358. {
  359. buffer.WriteUBitLong( 0, 2 );
  360. buffer.WriteString( m_szPathID );
  361. }
  362. else
  363. {
  364. buffer.WriteUBitLong( iCode+1, 2 );
  365. }
  366. iCode = FindCommonPrefix( m_szFilename );
  367. if ( iCode == -1 )
  368. {
  369. buffer.WriteUBitLong( 0, 3 );
  370. buffer.WriteString( m_szFilename );
  371. }
  372. else
  373. {
  374. buffer.WriteUBitLong( iCode+1, 3 );
  375. buffer.WriteString( &m_szFilename[ V_strlen(g_MostCommonPrefixes[iCode])+1 ] );
  376. }
  377. buffer.WriteBytes( m_MD5.bits, MD5_DIGEST_LENGTH );
  378. return !buffer.IsOverflowed();
  379. }
  380. bool CLC_FileMD5Check::ReadFromBuffer( bf_read &buffer )
  381. {
  382. VPROF( "CLC_FileMD5Check::ReadFromBuffer" );
  383. // Reserved for future use.
  384. buffer.ReadOneBit();
  385. // Read the path ID.
  386. int iCode = buffer.ReadUBitLong( 2 );
  387. if ( iCode == 0 )
  388. {
  389. buffer.ReadString( m_szPathID, sizeof( m_szPathID ) );
  390. }
  391. else if ( (iCode-1) < ARRAYSIZE( g_MostCommonPathIDs ) )
  392. {
  393. V_strncpy( m_szPathID, g_MostCommonPathIDs[iCode-1], sizeof( m_szPathID ) );
  394. }
  395. else
  396. {
  397. Assert( !"Invalid path ID code in CLC_FileMD5Check" );
  398. return false;
  399. }
  400. // Read the filename.
  401. iCode = buffer.ReadUBitLong( 3 );
  402. if ( iCode == 0 )
  403. {
  404. buffer.ReadString( m_szFilename, sizeof( m_szFilename ) );
  405. }
  406. else if ( (iCode-1) < ARRAYSIZE( g_MostCommonPrefixes ) )
  407. {
  408. char szTemp[MAX_PATH];
  409. buffer.ReadString( szTemp, sizeof( szTemp ) );
  410. V_snprintf( m_szFilename, sizeof( m_szFilename ), "%s%c%s", g_MostCommonPrefixes[iCode-1], CORRECT_PATH_SEPARATOR, szTemp );
  411. }
  412. else
  413. {
  414. Assert( !"Invalid prefix code in CLC_FileMD5Check." );
  415. return false;
  416. }
  417. buffer.ReadBytes( m_MD5.bits, MD5_DIGEST_LENGTH );
  418. return !buffer.IsOverflowed();
  419. }
  420. const char *CLC_FileMD5Check::ToString(void) const
  421. {
  422. V_snprintf( s_text, sizeof(s_text), "%s: path: %s, file: %s", GetName(), m_szPathID, m_szFilename );
  423. return s_text;
  424. }
  425. #if defined( REPLAY_ENABLED )
  426. bool CLC_SaveReplay::WriteToBuffer( bf_write &buffer )
  427. {
  428. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  429. buffer.WriteString( m_szFilename );
  430. buffer.WriteUBitLong( m_nStartSendByte, sizeof( m_nStartSendByte ) );
  431. buffer.WriteFloat( m_flPostDeathRecordTime );
  432. return !buffer.IsOverflowed();
  433. }
  434. bool CLC_SaveReplay::ReadFromBuffer( bf_read &buffer )
  435. {
  436. buffer.ReadString( m_szFilename, sizeof( m_szFilename ) );
  437. m_nStartSendByte = buffer.ReadUBitLong( sizeof( m_nStartSendByte ) );
  438. m_flPostDeathRecordTime = buffer.ReadFloat();
  439. return !buffer.IsOverflowed();
  440. }
  441. const char *CLC_SaveReplay::ToString() const
  442. {
  443. V_snprintf( s_text, sizeof( s_text ), "%s: filename: %s, start byte: %i, post death record time: %f", GetName(), m_szFilename, m_nStartSendByte, m_flPostDeathRecordTime );
  444. return s_text;
  445. }
  446. #endif
  447. //
  448. // CmdKeyValues message
  449. //
  450. Base_CmdKeyValues::Base_CmdKeyValues( KeyValues *pKeyValues /* = NULL */ ) :
  451. m_pKeyValues( pKeyValues )
  452. {
  453. }
  454. Base_CmdKeyValues::~Base_CmdKeyValues()
  455. {
  456. if ( m_pKeyValues )
  457. m_pKeyValues->deleteThis();
  458. m_pKeyValues = NULL;
  459. }
  460. bool Base_CmdKeyValues::WriteToBuffer( bf_write &buffer )
  461. {
  462. Assert( m_pKeyValues );
  463. if ( !m_pKeyValues )
  464. return false;
  465. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  466. CUtlBuffer bufData;
  467. if ( !m_pKeyValues->WriteAsBinary( bufData ) )
  468. {
  469. Assert( false );
  470. return false;
  471. }
  472. // Note how many we're sending
  473. int numBytes = bufData.TellMaxPut();
  474. buffer.WriteLong( numBytes );
  475. buffer.WriteBits( bufData.Base(), numBytes * 8 );
  476. return !buffer.IsOverflowed();
  477. }
  478. bool Base_CmdKeyValues::ReadFromBuffer( bf_read &buffer )
  479. {
  480. VPROF( "Base_CmdKeyValues::ReadFromBuffer" );
  481. if ( !m_pKeyValues )
  482. m_pKeyValues = new KeyValues( "" );
  483. m_pKeyValues->Clear();
  484. int numBytes = buffer.ReadLong();
  485. if ( numBytes <= 0 || numBytes > buffer.GetNumBytesLeft() )
  486. {
  487. return false; // don't read past the end of the buffer
  488. }
  489. void *pvBuffer = malloc( numBytes );
  490. if ( !pvBuffer )
  491. {
  492. return false;
  493. }
  494. buffer.ReadBits( pvBuffer, numBytes * 8 );
  495. CUtlBuffer bufRead( pvBuffer, numBytes, CUtlBuffer::READ_ONLY );
  496. if ( !m_pKeyValues->ReadAsBinary( bufRead ) )
  497. {
  498. Assert( false );
  499. free( pvBuffer );
  500. return false;
  501. }
  502. free( pvBuffer );
  503. return !buffer.IsOverflowed();
  504. }
  505. const char * Base_CmdKeyValues::ToString(void) const
  506. {
  507. Q_snprintf( s_text, sizeof(s_text), "%s: %s",
  508. GetName(), m_pKeyValues ? m_pKeyValues->GetName() : "<<null>>" );
  509. return s_text;
  510. }
  511. CLC_CmdKeyValues::CLC_CmdKeyValues( KeyValues *pKeyValues /* = NULL */ ) : Base_CmdKeyValues( pKeyValues )
  512. {
  513. }
  514. bool CLC_CmdKeyValues::WriteToBuffer( bf_write &buffer )
  515. {
  516. return Base_CmdKeyValues::WriteToBuffer( buffer );
  517. }
  518. bool CLC_CmdKeyValues::ReadFromBuffer( bf_read &buffer )
  519. {
  520. return Base_CmdKeyValues::ReadFromBuffer( buffer );
  521. }
  522. const char *CLC_CmdKeyValues::ToString(void) const
  523. {
  524. return Base_CmdKeyValues::ToString();
  525. }
  526. SVC_CmdKeyValues::SVC_CmdKeyValues( KeyValues *pKeyValues /* = NULL */ ) : Base_CmdKeyValues( pKeyValues )
  527. {
  528. }
  529. bool SVC_CmdKeyValues::WriteToBuffer( bf_write &buffer )
  530. {
  531. return Base_CmdKeyValues::WriteToBuffer( buffer );
  532. }
  533. bool SVC_CmdKeyValues::ReadFromBuffer( bf_read &buffer )
  534. {
  535. return Base_CmdKeyValues::ReadFromBuffer( buffer );
  536. }
  537. const char *SVC_CmdKeyValues::ToString(void) const
  538. {
  539. return Base_CmdKeyValues::ToString();
  540. }
  541. //
  542. // SVC_Print message
  543. //
  544. bool SVC_Print::WriteToBuffer( bf_write &buffer )
  545. {
  546. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  547. return buffer.WriteString( m_szText ? m_szText : " svc_print NULL" );
  548. }
  549. bool SVC_Print::ReadFromBuffer( bf_read &buffer )
  550. {
  551. VPROF( "SVC_Print::ReadFromBuffer" );
  552. m_szText = m_szTextBuffer;
  553. return buffer.ReadString(m_szTextBuffer, sizeof(m_szTextBuffer) );
  554. }
  555. const char *SVC_Print::ToString(void) const
  556. {
  557. Q_snprintf(s_text, sizeof(s_text), "%s: \"%s\"", GetName(), m_szText );
  558. return s_text;
  559. }
  560. bool NET_StringCmd::WriteToBuffer( bf_write &buffer )
  561. {
  562. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  563. return buffer.WriteString( m_szCommand ? m_szCommand : " NET_StringCmd NULL" );
  564. }
  565. bool NET_StringCmd::ReadFromBuffer( bf_read &buffer )
  566. {
  567. VPROF( "NET_StringCmd::ReadFromBuffer" );
  568. m_szCommand = m_szCommandBuffer;
  569. return buffer.ReadString(m_szCommandBuffer, sizeof(m_szCommandBuffer) );
  570. }
  571. const char *NET_StringCmd::ToString(void) const
  572. {
  573. Q_snprintf(s_text, sizeof(s_text), "%s: \"%s\"", GetName(), m_szCommand );
  574. return s_text;
  575. }
  576. bool SVC_ServerInfo::WriteToBuffer( bf_write &buffer )
  577. {
  578. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  579. buffer.WriteShort ( m_nProtocol );
  580. buffer.WriteLong ( m_nServerCount );
  581. buffer.WriteOneBit( m_bIsHLTV?1:0);
  582. buffer.WriteOneBit( m_bIsDedicated?1:0);
  583. buffer.WriteLong ( 0xffffffff ); // Used to be client.dll CRC. This was far before signed binaries, VAC, and cross-platform play
  584. buffer.WriteWord ( m_nMaxClasses );
  585. buffer.WriteBytes( m_nMapMD5.bits, MD5_DIGEST_LENGTH ); // To prevent cheating with hacked maps
  586. buffer.WriteByte ( m_nPlayerSlot );
  587. buffer.WriteByte ( m_nMaxClients );
  588. buffer.WriteFloat ( m_fTickInterval );
  589. buffer.WriteChar ( m_cOS );
  590. buffer.WriteString( m_szGameDir );
  591. buffer.WriteString( m_szMapName );
  592. buffer.WriteString( m_szSkyName );
  593. buffer.WriteString( m_szHostName );
  594. #if defined( REPLAY_ENABLED )
  595. buffer.WriteOneBit( m_bIsReplay?1:0);
  596. #endif
  597. return !buffer.IsOverflowed();
  598. }
  599. bool SVC_ServerInfo::ReadFromBuffer( bf_read &buffer )
  600. {
  601. VPROF( "SVC_ServerInfo::ReadFromBuffer" );
  602. m_szGameDir = m_szGameDirBuffer;
  603. m_szMapName = m_szMapNameBuffer;
  604. m_szSkyName = m_szSkyNameBuffer;
  605. m_szHostName = m_szHostNameBuffer;
  606. m_nProtocol = buffer.ReadShort();
  607. m_nServerCount = buffer.ReadLong();
  608. m_bIsHLTV = buffer.ReadOneBit()!=0;
  609. m_bIsDedicated = buffer.ReadOneBit()!=0;
  610. buffer.ReadLong(); // Legacy client CRC.
  611. m_nMaxClasses = buffer.ReadWord();
  612. // Prevent cheating with hacked maps
  613. if ( m_nProtocol > PROTOCOL_VERSION_17 )
  614. {
  615. buffer.ReadBytes( m_nMapMD5.bits, MD5_DIGEST_LENGTH );
  616. }
  617. else
  618. {
  619. m_nMapCRC = buffer.ReadLong();
  620. }
  621. m_nPlayerSlot = buffer.ReadByte();
  622. m_nMaxClients = buffer.ReadByte();
  623. m_fTickInterval = buffer.ReadFloat();
  624. m_cOS = buffer.ReadChar();
  625. buffer.ReadString( m_szGameDirBuffer, sizeof(m_szGameDirBuffer) );
  626. buffer.ReadString( m_szMapNameBuffer, sizeof(m_szMapNameBuffer) );
  627. buffer.ReadString( m_szSkyNameBuffer, sizeof(m_szSkyNameBuffer) );
  628. buffer.ReadString( m_szHostNameBuffer, sizeof(m_szHostNameBuffer) );
  629. #if defined( REPLAY_ENABLED )
  630. // Only attempt to read the 'replay' bit if the net channel's protocol
  631. // version is greater or equal than the protocol version for replay's release.
  632. // INetChannel::GetProtocolVersion() will return PROTOCOL_VERSION for
  633. // a regular net channel, or the network protocol version from the demo
  634. // file, if we're playing back a demo.
  635. if ( m_NetChannel->GetProtocolVersion() >= PROTOCOL_VERSION_REPLAY )
  636. {
  637. m_bIsReplay = buffer.ReadOneBit() != 0;
  638. }
  639. #endif
  640. return !buffer.IsOverflowed();
  641. }
  642. const char *SVC_ServerInfo::ToString(void) const
  643. {
  644. Q_snprintf(s_text, sizeof(s_text), "%s: game \"%s\", map \"%s\", max %i", GetName(), m_szGameDir, m_szMapName, m_nMaxClients );
  645. return s_text;
  646. }
  647. bool NET_SignonState::WriteToBuffer( bf_write &buffer )
  648. {
  649. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  650. buffer.WriteByte( m_nSignonState );
  651. buffer.WriteLong( m_nSpawnCount );
  652. return !buffer.IsOverflowed();
  653. }
  654. bool NET_SignonState::ReadFromBuffer( bf_read &buffer )
  655. {
  656. VPROF( "NET_SignonState::ReadFromBuffer" );
  657. m_nSignonState = buffer.ReadByte();
  658. m_nSpawnCount = buffer.ReadLong();
  659. return !buffer.IsOverflowed();
  660. }
  661. const char *NET_SignonState::ToString(void) const
  662. {
  663. Q_snprintf(s_text, sizeof(s_text), "%s: state %i, count %i", GetName(), m_nSignonState, m_nSpawnCount );
  664. return s_text;
  665. }
  666. bool SVC_BSPDecal::WriteToBuffer( bf_write &buffer )
  667. {
  668. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  669. buffer.WriteBitVec3Coord( m_Pos );
  670. buffer.WriteUBitLong( m_nDecalTextureIndex, MAX_DECAL_INDEX_BITS );
  671. if ( m_nEntityIndex != 0)
  672. {
  673. buffer.WriteOneBit( 1 );
  674. buffer.WriteUBitLong( m_nEntityIndex, MAX_EDICT_BITS );
  675. buffer.WriteUBitLong( m_nModelIndex, SP_MODEL_INDEX_BITS );
  676. }
  677. else
  678. {
  679. buffer.WriteOneBit( 0 );
  680. }
  681. buffer.WriteOneBit( m_bLowPriority ? 1 : 0 );
  682. return !buffer.IsOverflowed();
  683. }
  684. bool SVC_BSPDecal::ReadFromBuffer( bf_read &buffer )
  685. {
  686. VPROF( "SVC_BSPDecal::ReadFromBuffer" );
  687. buffer.ReadBitVec3Coord( m_Pos );
  688. m_nDecalTextureIndex = buffer.ReadUBitLong( MAX_DECAL_INDEX_BITS );
  689. if ( buffer.ReadOneBit() != 0 )
  690. {
  691. m_nEntityIndex = buffer.ReadUBitLong( MAX_EDICT_BITS );
  692. m_nModelIndex = buffer.ReadUBitLong( SP_MODEL_INDEX_BITS );
  693. }
  694. else
  695. {
  696. m_nEntityIndex = 0;
  697. m_nModelIndex = 0;
  698. }
  699. m_bLowPriority = buffer.ReadOneBit() ? true : false;
  700. return !buffer.IsOverflowed();
  701. }
  702. const char *SVC_BSPDecal::ToString(void) const
  703. {
  704. Q_snprintf(s_text, sizeof(s_text), "%s: tex %i, ent %i, mod %i lowpriority %i",
  705. GetName(), m_nDecalTextureIndex, m_nEntityIndex, m_nModelIndex, m_bLowPriority ? 1 : 0 );
  706. return s_text;
  707. }
  708. bool SVC_SetView::WriteToBuffer( bf_write &buffer )
  709. {
  710. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  711. buffer.WriteUBitLong( m_nEntityIndex, MAX_EDICT_BITS );
  712. return !buffer.IsOverflowed();
  713. }
  714. bool SVC_SetView::ReadFromBuffer( bf_read &buffer )
  715. {
  716. VPROF( "SVC_SetView::ReadFromBuffer" );
  717. m_nEntityIndex = buffer.ReadUBitLong( MAX_EDICT_BITS );
  718. return !buffer.IsOverflowed();
  719. }
  720. const char *SVC_SetView::ToString(void) const
  721. {
  722. Q_snprintf(s_text, sizeof(s_text), "%s: view entity %i", GetName(), m_nEntityIndex );
  723. return s_text;
  724. }
  725. bool SVC_FixAngle::WriteToBuffer( bf_write &buffer )
  726. {
  727. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  728. buffer.WriteOneBit( m_bRelative ? 1 : 0 );
  729. buffer.WriteBitAngle( m_Angle.x, 16 );
  730. buffer.WriteBitAngle( m_Angle.y, 16 );
  731. buffer.WriteBitAngle( m_Angle.z, 16 );
  732. return !buffer.IsOverflowed();
  733. }
  734. bool SVC_FixAngle::ReadFromBuffer( bf_read &buffer )
  735. {
  736. VPROF( "SVC_FixAngle::ReadFromBuffer" );
  737. m_bRelative = buffer.ReadOneBit() != 0;
  738. m_Angle.x = buffer.ReadBitAngle( 16 );
  739. m_Angle.y = buffer.ReadBitAngle( 16 );
  740. m_Angle.z = buffer.ReadBitAngle( 16 );
  741. return !buffer.IsOverflowed();
  742. }
  743. const char *SVC_FixAngle::ToString(void) const
  744. {
  745. Q_snprintf(s_text, sizeof(s_text), "%s: %s %.1f %.1f %.1f ", GetName(), m_bRelative?"relative":"absolute",
  746. m_Angle[0], m_Angle[1], m_Angle[2] );
  747. return s_text;
  748. }
  749. bool SVC_CrosshairAngle::WriteToBuffer( bf_write &buffer )
  750. {
  751. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  752. buffer.WriteBitAngle( m_Angle.x, 16 );
  753. buffer.WriteBitAngle( m_Angle.y, 16 );
  754. buffer.WriteBitAngle( m_Angle.z, 16 );
  755. return !buffer.IsOverflowed();
  756. }
  757. bool SVC_CrosshairAngle::ReadFromBuffer( bf_read &buffer )
  758. {
  759. VPROF( "SVC_CrosshairAngle::ReadFromBuffer" );
  760. m_Angle.x = buffer.ReadBitAngle( 16 );
  761. m_Angle.y = buffer.ReadBitAngle( 16 );
  762. m_Angle.z = buffer.ReadBitAngle( 16 );
  763. return !buffer.IsOverflowed();
  764. }
  765. const char *SVC_CrosshairAngle::ToString(void) const
  766. {
  767. Q_snprintf(s_text, sizeof(s_text), "%s: (%.1f %.1f %.1f)", GetName(), m_Angle[0], m_Angle[1], m_Angle[2] );
  768. return s_text;
  769. }
  770. bool SVC_VoiceInit::WriteToBuffer( bf_write &buffer )
  771. {
  772. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  773. buffer.WriteString( m_szVoiceCodec );
  774. buffer.WriteByte( /* Legacy Quality Field */ 255 );
  775. buffer.WriteShort( m_nSampleRate );
  776. return !buffer.IsOverflowed();
  777. }
  778. bool SVC_VoiceInit::ReadFromBuffer( bf_read &buffer )
  779. {
  780. VPROF( "SVC_VoiceInit::ReadFromBuffer" );
  781. buffer.ReadString( m_szVoiceCodec, sizeof(m_szVoiceCodec) );
  782. unsigned char nLegacyQuality = buffer.ReadByte();
  783. if ( nLegacyQuality == 255 )
  784. {
  785. // v2 packet
  786. m_nSampleRate = buffer.ReadShort();
  787. }
  788. else
  789. {
  790. // v1 packet
  791. //
  792. // Hacky workaround for v1 packets not actually indicating if we were using steam voice -- we've kept the steam
  793. // voice separate convar that was in use at the time as replicated&hidden, and if whatever network stream we're
  794. // interpreting sets it, lie about the subsequent voice init's codec & sample rate.
  795. if ( sv_use_steam_voice.GetBool() )
  796. {
  797. Msg( "Legacy SVC_VoiceInit - got a set for sv_use_steam_voice convar, assuming Steam voice\n" );
  798. V_strncpy( m_szVoiceCodec, "steam", sizeof( m_szVoiceCodec ) );
  799. // Legacy steam voice can always be parsed as auto sample rate.
  800. m_nSampleRate = 0;
  801. }
  802. else if ( V_strncasecmp( m_szVoiceCodec, "vaudio_celt", sizeof( m_szVoiceCodec ) ) == 0 )
  803. {
  804. // Legacy rate vaudio_celt always selected during v1 packet era
  805. m_nSampleRate = 22050;
  806. }
  807. else
  808. {
  809. // Legacy rate everything but CELT always selected during v1 packet era
  810. m_nSampleRate = 11025;
  811. }
  812. }
  813. return !buffer.IsOverflowed();
  814. }
  815. const char *SVC_VoiceInit::ToString(void) const
  816. {
  817. Q_snprintf( s_text, sizeof(s_text), "%s: codec \"%s\", sample rate %i", GetName(), m_szVoiceCodec, m_nSampleRate );
  818. return s_text;
  819. }
  820. bool SVC_VoiceData::WriteToBuffer( bf_write &buffer )
  821. {
  822. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  823. buffer.WriteByte( m_nFromClient );
  824. buffer.WriteByte( m_bProximity );
  825. buffer.WriteWord( m_nLength );
  826. if ( IsX360() )
  827. {
  828. buffer.WriteLongLong( m_xuid );
  829. }
  830. return buffer.WriteBits( m_DataOut, m_nLength );
  831. }
  832. bool SVC_VoiceData::ReadFromBuffer( bf_read &buffer )
  833. {
  834. VPROF( "SVC_VoiceData::ReadFromBuffer" );
  835. m_nFromClient = buffer.ReadByte();
  836. m_bProximity = !!buffer.ReadByte();
  837. m_nLength = buffer.ReadWord();
  838. if ( IsX360() )
  839. {
  840. m_xuid = buffer.ReadLongLong();
  841. }
  842. m_DataIn = buffer;
  843. return buffer.SeekRelative( m_nLength );
  844. }
  845. const char *SVC_VoiceData::ToString(void) const
  846. {
  847. Q_snprintf(s_text, sizeof(s_text), "%s: client %i, bytes %i", GetName(), m_nFromClient, Bits2Bytes(m_nLength) );
  848. return s_text;
  849. }
  850. #define NET_TICK_SCALEUP 100000.0f
  851. bool NET_Tick::WriteToBuffer( bf_write &buffer )
  852. {
  853. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  854. buffer.WriteLong( m_nTick );
  855. #if PROTOCOL_VERSION > 10
  856. buffer.WriteUBitLong( clamp( (int)( NET_TICK_SCALEUP * m_flHostFrameTime ), 0, 65535 ), 16 );
  857. buffer.WriteUBitLong( clamp( (int)( NET_TICK_SCALEUP * m_flHostFrameTimeStdDeviation ), 0, 65535 ), 16 );
  858. #endif
  859. return !buffer.IsOverflowed();
  860. }
  861. bool NET_Tick::ReadFromBuffer( bf_read &buffer )
  862. {
  863. VPROF( "NET_Tick::ReadFromBuffer" );
  864. m_nTick = buffer.ReadLong();
  865. #if PROTOCOL_VERSION > 10
  866. m_flHostFrameTime = (float)buffer.ReadUBitLong( 16 ) / NET_TICK_SCALEUP;
  867. m_flHostFrameTimeStdDeviation = (float)buffer.ReadUBitLong( 16 ) / NET_TICK_SCALEUP;
  868. #endif
  869. return !buffer.IsOverflowed();
  870. }
  871. const char *NET_Tick::ToString(void) const
  872. {
  873. Q_snprintf(s_text, sizeof(s_text), "%s: tick %i", GetName(), m_nTick );
  874. return s_text;
  875. }
  876. bool SVC_UserMessage::WriteToBuffer( bf_write &buffer )
  877. {
  878. m_nLength = m_DataOut.GetNumBitsWritten();
  879. Assert( m_nLength < (1 << NETMSG_LENGTH_BITS) );
  880. if ( m_nLength >= (1 << NETMSG_LENGTH_BITS) )
  881. return false;
  882. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  883. buffer.WriteByte( m_nMsgType );
  884. buffer.WriteUBitLong( m_nLength, NETMSG_LENGTH_BITS ); // max 256 * 8 bits, see MAX_USER_MSG_DATA
  885. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  886. }
  887. bool SVC_UserMessage::ReadFromBuffer( bf_read &buffer )
  888. {
  889. VPROF( "SVC_UserMessage::ReadFromBuffer" );
  890. m_nMsgType = buffer.ReadByte();
  891. m_nLength = buffer.ReadUBitLong( NETMSG_LENGTH_BITS ); // max 256 * 8 bits, see MAX_USER_MSG_DATA
  892. m_DataIn = buffer;
  893. return buffer.SeekRelative( m_nLength );
  894. }
  895. const char *SVC_UserMessage::ToString(void) const
  896. {
  897. Q_snprintf(s_text, sizeof(s_text), "%s: type %i, bytes %i", GetName(), m_nMsgType, Bits2Bytes(m_nLength) );
  898. return s_text;
  899. }
  900. bool SVC_SetPause::WriteToBuffer( bf_write &buffer )
  901. {
  902. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  903. buffer.WriteOneBit( m_bPaused?1:0 );
  904. return !buffer.IsOverflowed();
  905. }
  906. bool SVC_SetPause::ReadFromBuffer( bf_read &buffer )
  907. {
  908. VPROF( "SVC_SetPause::ReadFromBuffer" );
  909. m_bPaused = buffer.ReadOneBit() != 0;
  910. return !buffer.IsOverflowed();
  911. }
  912. const char *SVC_SetPause::ToString(void) const
  913. {
  914. Q_snprintf(s_text, sizeof(s_text), "%s: %s", GetName(), m_bPaused?"paused":"unpaused" );
  915. return s_text;
  916. }
  917. bool SVC_SetPauseTimed::WriteToBuffer( bf_write &buffer )
  918. {
  919. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  920. buffer.WriteOneBit( m_bPaused ? 1 : 0 );
  921. buffer.WriteFloat( m_flExpireTime );
  922. return !buffer.IsOverflowed();
  923. }
  924. bool SVC_SetPauseTimed::ReadFromBuffer( bf_read &buffer )
  925. {
  926. VPROF( "SVC_SetPauseTimed::ReadFromBuffer" );
  927. m_bPaused = buffer.ReadOneBit() != 0;
  928. m_flExpireTime = buffer.ReadFloat();
  929. return !buffer.IsOverflowed();
  930. }
  931. const char *SVC_SetPauseTimed::ToString( void ) const
  932. {
  933. Q_snprintf( s_text, sizeof( s_text ), "%s: %s", GetName(), m_bPaused ? "paused" : "unpaused" );
  934. return s_text;
  935. }
  936. bool NET_SetConVar::WriteToBuffer( bf_write &buffer )
  937. {
  938. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  939. int numvars = m_ConVars.Count();
  940. // Note how many we're sending
  941. buffer.WriteByte( numvars );
  942. for (int i=0; i< numvars; i++ )
  943. {
  944. cvar_t * var = &m_ConVars[i];
  945. buffer.WriteString( var->name );
  946. buffer.WriteString( var->value );
  947. }
  948. return !buffer.IsOverflowed();
  949. }
  950. bool NET_SetConVar::ReadFromBuffer( bf_read &buffer )
  951. {
  952. VPROF( "NET_SetConVar::ReadFromBuffer" );
  953. int numvars = buffer.ReadByte();
  954. m_ConVars.RemoveAll();
  955. for (int i=0; i< numvars; i++ )
  956. {
  957. cvar_t var;
  958. buffer.ReadString( var.name, sizeof(var.name) );
  959. buffer.ReadString( var.value, sizeof(var.value) );
  960. m_ConVars.AddToTail( var );
  961. }
  962. return !buffer.IsOverflowed();
  963. }
  964. const char *NET_SetConVar::ToString(void) const
  965. {
  966. Q_snprintf(s_text, sizeof(s_text), "%s: %i cvars, \"%s\"=\"%s\"",
  967. GetName(), m_ConVars.Count(),
  968. m_ConVars[0].name, m_ConVars[0].value );
  969. return s_text;
  970. }
  971. bool SVC_UpdateStringTable::WriteToBuffer( bf_write &buffer )
  972. {
  973. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  974. m_nLength = m_DataOut.GetNumBitsWritten();
  975. buffer.WriteUBitLong( m_nTableID, Q_log2( MAX_TABLES ) ); // TODO check bounds
  976. if ( m_nChangedEntries == 1 )
  977. {
  978. buffer.WriteOneBit( 0 ); // only one entry changed
  979. }
  980. else
  981. {
  982. buffer.WriteOneBit( 1 );
  983. buffer.WriteWord( m_nChangedEntries ); // more entries changed
  984. }
  985. buffer.WriteUBitLong( m_nLength, 20 );
  986. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  987. }
  988. bool SVC_UpdateStringTable::ReadFromBuffer( bf_read &buffer )
  989. {
  990. VPROF( "SVC_UpdateStringTable::ReadFromBuffer" );
  991. m_nTableID = buffer.ReadUBitLong( Q_log2( MAX_TABLES ) );
  992. if ( buffer.ReadOneBit() != 0 )
  993. {
  994. m_nChangedEntries = buffer.ReadWord();
  995. }
  996. else
  997. {
  998. m_nChangedEntries = 1;
  999. }
  1000. m_nLength = buffer.ReadUBitLong( 20 );
  1001. m_DataIn = buffer;
  1002. return buffer.SeekRelative( m_nLength );
  1003. }
  1004. const char *SVC_UpdateStringTable::ToString(void) const
  1005. {
  1006. Q_snprintf(s_text, sizeof(s_text), "%s: table %i, changed %i, bytes %i", GetName(), m_nTableID, m_nChangedEntries, Bits2Bytes(m_nLength) );
  1007. return s_text;
  1008. }
  1009. SVC_CreateStringTable::SVC_CreateStringTable()
  1010. {
  1011. }
  1012. bool SVC_CreateStringTable::WriteToBuffer( bf_write &buffer )
  1013. {
  1014. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1015. m_nLength = m_DataOut.GetNumBitsWritten();
  1016. /*
  1017. JASON: this code is no longer needed; the ':' is prepended to the table name at table creation time.
  1018. if ( m_bIsFilenames )
  1019. {
  1020. // identifies a table that hosts filenames
  1021. buffer.WriteByte( ':' );
  1022. }
  1023. */
  1024. buffer.WriteString( m_szTableName );
  1025. buffer.WriteWord( m_nMaxEntries );
  1026. int encodeBits = Q_log2( m_nMaxEntries );
  1027. buffer.WriteUBitLong( m_nNumEntries, encodeBits+1 );
  1028. buffer.WriteVarInt32( m_nLength ); // length in bits
  1029. buffer.WriteOneBit( m_bUserDataFixedSize ? 1 : 0 );
  1030. if ( m_bUserDataFixedSize )
  1031. {
  1032. buffer.WriteUBitLong( m_nUserDataSize, 12 );
  1033. buffer.WriteUBitLong( m_nUserDataSizeBits, 4 );
  1034. }
  1035. buffer.WriteOneBit( m_bDataCompressed ? 1 : 0 );
  1036. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1037. }
  1038. bool SVC_CreateStringTable::ReadFromBuffer( bf_read &buffer )
  1039. {
  1040. VPROF( "SVC_CreateStringTable::ReadFromBuffer" );
  1041. char prefix = buffer.PeekUBitLong( 8 );
  1042. if ( prefix == ':' )
  1043. {
  1044. // table hosts filenames
  1045. m_bIsFilenames = true;
  1046. buffer.ReadByte();
  1047. }
  1048. else
  1049. {
  1050. m_bIsFilenames = false;
  1051. }
  1052. m_szTableName = m_szTableNameBuffer;
  1053. buffer.ReadString( m_szTableNameBuffer, sizeof(m_szTableNameBuffer) );
  1054. m_nMaxEntries = buffer.ReadWord();
  1055. int encodeBits = Q_log2( m_nMaxEntries );
  1056. m_nNumEntries = buffer.ReadUBitLong( encodeBits+1 );
  1057. if ( m_NetChannel->GetProtocolVersion() > PROTOCOL_VERSION_23 )
  1058. m_nLength = buffer.ReadVarInt32();
  1059. else
  1060. m_nLength = buffer.ReadUBitLong( NET_MAX_PAYLOAD_BITS_V23 + 3 );
  1061. m_bUserDataFixedSize = buffer.ReadOneBit() ? true : false;
  1062. if ( m_bUserDataFixedSize )
  1063. {
  1064. m_nUserDataSize = buffer.ReadUBitLong( 12 );
  1065. m_nUserDataSizeBits = buffer.ReadUBitLong( 4 );
  1066. }
  1067. else
  1068. {
  1069. m_nUserDataSize = 0;
  1070. m_nUserDataSizeBits = 0;
  1071. }
  1072. if ( m_pMessageHandler->GetDemoProtocolVersion() > PROTOCOL_VERSION_14 )
  1073. {
  1074. m_bDataCompressed = buffer.ReadOneBit() != 0;
  1075. }
  1076. else
  1077. {
  1078. m_bDataCompressed = false;
  1079. }
  1080. m_DataIn = buffer;
  1081. return buffer.SeekRelative( m_nLength );
  1082. }
  1083. const char *SVC_CreateStringTable::ToString(void) const
  1084. {
  1085. Q_snprintf(s_text, sizeof(s_text), "%s: table %s, entries %i, bytes %i userdatasize %i userdatabits %i",
  1086. GetName(), m_szTableName, m_nNumEntries, Bits2Bytes(m_nLength), m_nUserDataSize, m_nUserDataSizeBits );
  1087. return s_text;
  1088. }
  1089. bool SVC_Sounds::WriteToBuffer( bf_write &buffer )
  1090. {
  1091. m_nLength = m_DataOut.GetNumBitsWritten();
  1092. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1093. Assert( m_nNumSounds > 0 );
  1094. if ( m_bReliableSound )
  1095. {
  1096. // as single sound message is 32 bytes long maximum
  1097. buffer.WriteOneBit( 1 );
  1098. buffer.WriteUBitLong( m_nLength, 8 );
  1099. }
  1100. else
  1101. {
  1102. // a bunch of unreliable messages
  1103. buffer.WriteOneBit( 0 );
  1104. buffer.WriteUBitLong( m_nNumSounds, 8 );
  1105. buffer.WriteUBitLong( m_nLength, 16 );
  1106. }
  1107. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1108. }
  1109. bool SVC_Sounds::ReadFromBuffer( bf_read &buffer )
  1110. {
  1111. VPROF( "SVC_Sounds::ReadFromBuffer" );
  1112. m_bReliableSound = buffer.ReadOneBit() != 0;
  1113. if ( m_bReliableSound )
  1114. {
  1115. m_nNumSounds = 1;
  1116. m_nLength = buffer.ReadUBitLong( 8 );
  1117. }
  1118. else
  1119. {
  1120. m_nNumSounds = buffer.ReadUBitLong( 8 );
  1121. m_nLength = buffer.ReadUBitLong( 16 );
  1122. }
  1123. m_DataIn = buffer;
  1124. return buffer.SeekRelative( m_nLength );
  1125. }
  1126. const char *SVC_Sounds::ToString(void) const
  1127. {
  1128. Q_snprintf(s_text, sizeof(s_text), "%s: number %i,%s bytes %i",
  1129. GetName(), m_nNumSounds, m_bReliableSound?" reliable,":"", Bits2Bytes(m_nLength) );
  1130. return s_text;
  1131. }
  1132. bool SVC_Prefetch::WriteToBuffer( bf_write &buffer )
  1133. {
  1134. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1135. // Don't write type until we have more thanone
  1136. // buffer.WriteUBitLong( m_fType, 1 );
  1137. buffer.WriteUBitLong( m_nSoundIndex, MAX_SOUND_INDEX_BITS );
  1138. return !buffer.IsOverflowed();
  1139. }
  1140. bool SVC_Prefetch::ReadFromBuffer( bf_read &buffer )
  1141. {
  1142. VPROF( "SVC_Prefetch::ReadFromBuffer" );
  1143. m_fType = SOUND; // buffer.ReadUBitLong( 1 );
  1144. if( m_pMessageHandler->GetDemoProtocolVersion() > 22 )
  1145. {
  1146. m_nSoundIndex = buffer.ReadUBitLong( MAX_SOUND_INDEX_BITS );
  1147. }
  1148. else
  1149. {
  1150. m_nSoundIndex = buffer.ReadUBitLong( 13 );
  1151. }
  1152. return !buffer.IsOverflowed();
  1153. }
  1154. const char *SVC_Prefetch::ToString(void) const
  1155. {
  1156. Q_snprintf(s_text, sizeof(s_text), "%s: type %i index %i",
  1157. GetName(),
  1158. (int)m_fType,
  1159. (int)m_nSoundIndex );
  1160. return s_text;
  1161. }
  1162. bool SVC_TempEntities::WriteToBuffer( bf_write &buffer )
  1163. {
  1164. Assert( m_nNumEntries > 0 );
  1165. m_nLength = m_DataOut.GetNumBitsWritten();
  1166. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1167. buffer.WriteUBitLong( m_nNumEntries, CEventInfo::EVENT_INDEX_BITS );
  1168. buffer.WriteVarInt32( m_nLength );
  1169. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1170. }
  1171. bool SVC_TempEntities::ReadFromBuffer( bf_read &buffer )
  1172. {
  1173. VPROF( "SVC_TempEntities::ReadFromBuffer" );
  1174. m_nNumEntries = buffer.ReadUBitLong( CEventInfo::EVENT_INDEX_BITS );
  1175. if ( m_pMessageHandler->GetDemoProtocolVersion() > PROTOCOL_VERSION_23 )
  1176. m_nLength = buffer.ReadVarInt32();
  1177. else
  1178. m_nLength = buffer.ReadUBitLong( NET_MAX_PAYLOAD_BITS_V23 );
  1179. m_DataIn = buffer;
  1180. return buffer.SeekRelative( m_nLength );
  1181. }
  1182. const char *SVC_TempEntities::ToString(void) const
  1183. {
  1184. Q_snprintf(s_text, sizeof(s_text), "%s: number %i, bytes %i", GetName(), m_nNumEntries, Bits2Bytes(m_nLength) );
  1185. return s_text;
  1186. }
  1187. bool SVC_ClassInfo::WriteToBuffer( bf_write &buffer )
  1188. {
  1189. if ( !m_bCreateOnClient )
  1190. {
  1191. m_nNumServerClasses = m_Classes.Count(); // use number from list list
  1192. }
  1193. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1194. buffer.WriteShort( m_nNumServerClasses );
  1195. int serverClassBits = Q_log2( m_nNumServerClasses ) + 1;
  1196. buffer.WriteOneBit( m_bCreateOnClient?1:0 );
  1197. if ( m_bCreateOnClient )
  1198. return !buffer.IsOverflowed();
  1199. for ( int i=0; i< m_nNumServerClasses; i++ )
  1200. {
  1201. class_t * serverclass = &m_Classes[i];
  1202. buffer.WriteUBitLong( serverclass->classID, serverClassBits );
  1203. buffer.WriteString( serverclass->classname );
  1204. buffer.WriteString( serverclass->datatablename );
  1205. }
  1206. return !buffer.IsOverflowed();
  1207. }
  1208. bool SVC_ClassInfo::ReadFromBuffer( bf_read &buffer )
  1209. {
  1210. VPROF( "SVC_ClassInfo::ReadFromBuffer" );
  1211. m_Classes.RemoveAll();
  1212. m_nNumServerClasses = buffer.ReadShort();
  1213. int nServerClassBits = Q_log2( m_nNumServerClasses ) + 1;
  1214. m_bCreateOnClient = buffer.ReadOneBit() != 0;
  1215. if ( m_bCreateOnClient )
  1216. {
  1217. return !buffer.IsOverflowed(); // stop here
  1218. }
  1219. for ( int i=0; i<m_nNumServerClasses; i++ )
  1220. {
  1221. class_t serverclass;
  1222. serverclass.classID = buffer.ReadUBitLong( nServerClassBits );
  1223. buffer.ReadString( serverclass.classname, sizeof(serverclass.classname) );
  1224. buffer.ReadString( serverclass.datatablename, sizeof(serverclass.datatablename) );
  1225. m_Classes.AddToTail( serverclass );
  1226. }
  1227. return !buffer.IsOverflowed();
  1228. }
  1229. const char *SVC_ClassInfo::ToString(void) const
  1230. {
  1231. Q_snprintf(s_text, sizeof(s_text), "%s: num %i, %s", GetName(),
  1232. m_nNumServerClasses, m_bCreateOnClient?"use client classes":"full update" );
  1233. return s_text;
  1234. }
  1235. /*
  1236. bool SVC_SpawnBaseline::WriteToBuffer( bf_write &buffer )
  1237. {
  1238. m_nLength = m_DataOut.GetNumBitsWritten();
  1239. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1240. buffer.WriteUBitLong( m_nEntityIndex, MAX_EDICT_BITS );
  1241. buffer.WriteUBitLong( m_nClassID, MAX_SERVER_CLASS_BITS );
  1242. buffer.WriteUBitLong( m_nLength, Q_log2(MAX_PACKEDENTITY_DATA<<3) ); // TODO see below
  1243. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1244. }
  1245. bool SVC_SpawnBaseline::ReadFromBuffer( bf_read &buffer )
  1246. {
  1247. m_nEntityIndex = buffer.ReadUBitLong( MAX_EDICT_BITS );
  1248. m_nClassID = buffer.ReadUBitLong( MAX_SERVER_CLASS_BITS );
  1249. m_nLength = buffer.ReadUBitLong( Q_log2(MAX_PACKEDENTITY_DATA<<3) ); // TODO wrong, check bounds
  1250. m_DataIn = buffer;
  1251. return buffer.SeekRelative( m_nLength );
  1252. }
  1253. const char *SVC_SpawnBaseline::ToString(void) const
  1254. {
  1255. static char text[256];
  1256. Q_snprintf(text, sizeof(text), "%s: ent %i, class %i, bytes %i",
  1257. GetName(), m_nEntityIndex, m_nClassID, Bits2Bytes(m_nLength) );
  1258. return text;
  1259. } */
  1260. bool SVC_GameEvent::WriteToBuffer( bf_write &buffer )
  1261. {
  1262. m_nLength = m_DataOut.GetNumBitsWritten();
  1263. Assert( m_nLength < (1 << NETMSG_LENGTH_BITS) );
  1264. if ( m_nLength >= (1 << NETMSG_LENGTH_BITS) )
  1265. return false;
  1266. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1267. buffer.WriteUBitLong( m_nLength, NETMSG_LENGTH_BITS ); // max 8 * 256 bits
  1268. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1269. }
  1270. bool SVC_GameEvent::ReadFromBuffer( bf_read &buffer )
  1271. {
  1272. VPROF( "SVC_GameEvent::ReadFromBuffer" );
  1273. m_nLength = buffer.ReadUBitLong( NETMSG_LENGTH_BITS ); // max 8 * 256 bits
  1274. m_DataIn = buffer;
  1275. return buffer.SeekRelative( m_nLength );
  1276. }
  1277. const char *SVC_GameEvent::ToString(void) const
  1278. {
  1279. Q_snprintf(s_text, sizeof(s_text), "%s: bytes %i", GetName(), Bits2Bytes(m_nLength) );
  1280. return s_text;
  1281. }
  1282. bool SVC_SendTable::WriteToBuffer( bf_write &buffer )
  1283. {
  1284. m_nLength = m_DataOut.GetNumBitsWritten();
  1285. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1286. buffer.WriteOneBit( m_bNeedsDecoder?1:0 );
  1287. buffer.WriteShort( m_nLength );
  1288. buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1289. return !buffer.IsOverflowed();
  1290. }
  1291. bool SVC_SendTable::ReadFromBuffer( bf_read &buffer )
  1292. {
  1293. VPROF( "SVC_SendTable::ReadFromBuffer" );
  1294. m_bNeedsDecoder = buffer.ReadOneBit() != 0;
  1295. m_nLength = buffer.ReadShort(); // TODO do we have a maximum length ? check that
  1296. m_DataIn = buffer;
  1297. return buffer.SeekRelative( m_nLength );
  1298. }
  1299. const char *SVC_SendTable::ToString(void) const
  1300. {
  1301. Q_snprintf(s_text, sizeof(s_text), "%s: needs Decoder %s,bytes %i",
  1302. GetName(), m_bNeedsDecoder?"yes":"no", Bits2Bytes(m_nLength) );
  1303. return s_text;
  1304. }
  1305. bool SVC_EntityMessage::WriteToBuffer( bf_write &buffer )
  1306. {
  1307. m_nLength = m_DataOut.GetNumBitsWritten();
  1308. Assert( m_nLength < (1 << NETMSG_LENGTH_BITS) );
  1309. if ( m_nLength >= (1 << NETMSG_LENGTH_BITS) )
  1310. return false;
  1311. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1312. buffer.WriteUBitLong( m_nEntityIndex, MAX_EDICT_BITS );
  1313. buffer.WriteUBitLong( m_nClassID, MAX_SERVER_CLASS_BITS );
  1314. buffer.WriteUBitLong( m_nLength, NETMSG_LENGTH_BITS ); // max 8 * 256 bits
  1315. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1316. }
  1317. bool SVC_EntityMessage::ReadFromBuffer( bf_read &buffer )
  1318. {
  1319. VPROF( "SVC_EntityMessage::ReadFromBuffer" );
  1320. m_nEntityIndex = buffer.ReadUBitLong( MAX_EDICT_BITS );
  1321. m_nClassID = buffer.ReadUBitLong( MAX_SERVER_CLASS_BITS );
  1322. m_nLength = buffer.ReadUBitLong( NETMSG_LENGTH_BITS ); // max 8 * 256 bits
  1323. m_DataIn = buffer;
  1324. return buffer.SeekRelative( m_nLength );
  1325. }
  1326. const char *SVC_EntityMessage::ToString(void) const
  1327. {
  1328. Q_snprintf(s_text, sizeof(s_text), "%s: entity %i, class %i, bytes %i",
  1329. GetName(), m_nEntityIndex, m_nClassID, Bits2Bytes(m_nLength) );
  1330. return s_text;
  1331. }
  1332. bool SVC_PacketEntities::WriteToBuffer( bf_write &buffer )
  1333. {
  1334. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1335. buffer.WriteUBitLong( m_nMaxEntries, MAX_EDICT_BITS );
  1336. buffer.WriteOneBit( m_bIsDelta?1:0 );
  1337. if ( m_bIsDelta )
  1338. {
  1339. buffer.WriteLong( m_nDeltaFrom );
  1340. }
  1341. buffer.WriteUBitLong( m_nBaseline, 1 );
  1342. buffer.WriteUBitLong( m_nUpdatedEntries, MAX_EDICT_BITS );
  1343. buffer.WriteUBitLong( m_nLength, DELTASIZE_BITS );
  1344. buffer.WriteOneBit( m_bUpdateBaseline?1:0 );
  1345. buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1346. return !buffer.IsOverflowed();
  1347. }
  1348. bool SVC_PacketEntities::ReadFromBuffer( bf_read &buffer )
  1349. {
  1350. VPROF( "SVC_PacketEntities::ReadFromBuffer" );
  1351. m_nMaxEntries = buffer.ReadUBitLong( MAX_EDICT_BITS );
  1352. m_bIsDelta = buffer.ReadOneBit()!=0;
  1353. if ( m_bIsDelta )
  1354. {
  1355. m_nDeltaFrom = buffer.ReadLong();
  1356. }
  1357. else
  1358. {
  1359. m_nDeltaFrom = -1;
  1360. }
  1361. m_nBaseline = buffer.ReadUBitLong( 1 );
  1362. m_nUpdatedEntries = buffer.ReadUBitLong( MAX_EDICT_BITS );
  1363. m_nLength = buffer.ReadUBitLong( DELTASIZE_BITS );
  1364. m_bUpdateBaseline = buffer.ReadOneBit() != 0;
  1365. m_DataIn = buffer;
  1366. return buffer.SeekRelative( m_nLength );
  1367. }
  1368. const char *SVC_PacketEntities::ToString(void) const
  1369. {
  1370. Q_snprintf(s_text, sizeof(s_text), "%s: delta %i, max %i, changed %i,%s bytes %i",
  1371. GetName(), m_nDeltaFrom, m_nMaxEntries, m_nUpdatedEntries, m_bUpdateBaseline?" BL update,":"", Bits2Bytes(m_nLength) );
  1372. return s_text;
  1373. }
  1374. SVC_Menu::SVC_Menu( DIALOG_TYPE type, KeyValues *data )
  1375. {
  1376. m_bReliable = true;
  1377. m_Type = type;
  1378. m_MenuKeyValues = data->MakeCopy();
  1379. m_iLength = -1;
  1380. }
  1381. SVC_Menu::~SVC_Menu()
  1382. {
  1383. if ( m_MenuKeyValues )
  1384. {
  1385. m_MenuKeyValues->deleteThis();
  1386. }
  1387. }
  1388. bool SVC_Menu::WriteToBuffer( bf_write &buffer )
  1389. {
  1390. if ( !m_MenuKeyValues )
  1391. {
  1392. return false;
  1393. }
  1394. CUtlBuffer buf;
  1395. m_MenuKeyValues->WriteAsBinary( buf );
  1396. if ( buf.TellPut() > 4096 )
  1397. {
  1398. Msg( "Too much menu data (4096 bytes max)\n" );
  1399. return false;
  1400. }
  1401. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1402. buffer.WriteShort( m_Type );
  1403. buffer.WriteWord( buf.TellPut() );
  1404. buffer.WriteBytes( buf.Base(), buf.TellPut() );
  1405. return !buffer.IsOverflowed();
  1406. }
  1407. bool SVC_Menu::ReadFromBuffer( bf_read &buffer )
  1408. {
  1409. VPROF( "SVC_Menu::ReadFromBuffer" );
  1410. m_Type = (DIALOG_TYPE)buffer.ReadShort();
  1411. m_iLength = buffer.ReadWord();
  1412. CUtlBuffer buf( 0, m_iLength );
  1413. buffer.ReadBytes( buf.Base(), m_iLength );
  1414. buf.SeekPut( CUtlBuffer::SEEK_HEAD, m_iLength );
  1415. if ( m_MenuKeyValues )
  1416. {
  1417. m_MenuKeyValues->deleteThis();
  1418. }
  1419. m_MenuKeyValues = new KeyValues( "menu" );
  1420. Assert( m_MenuKeyValues );
  1421. m_MenuKeyValues->ReadAsBinary( buf );
  1422. return !buffer.IsOverflowed();
  1423. }
  1424. const char *SVC_Menu::ToString(void) const
  1425. {
  1426. Q_snprintf(s_text, sizeof(s_text), "%s: %i \"%s\" (len:%i)", GetName(),
  1427. m_Type, m_MenuKeyValues ? m_MenuKeyValues->GetName() : "No KeyValues", m_iLength );
  1428. return s_text;
  1429. }
  1430. bool SVC_GameEventList::WriteToBuffer( bf_write &buffer )
  1431. {
  1432. Assert( m_nNumEvents > 0 );
  1433. m_nLength = m_DataOut.GetNumBitsWritten();
  1434. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1435. buffer.WriteUBitLong( m_nNumEvents, MAX_EVENT_BITS );
  1436. buffer.WriteUBitLong( m_nLength, 20 );
  1437. return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
  1438. }
  1439. bool SVC_GameEventList::ReadFromBuffer( bf_read &buffer )
  1440. {
  1441. VPROF( "SVC_GameEventList::ReadFromBuffer" );
  1442. m_nNumEvents = buffer.ReadUBitLong( MAX_EVENT_BITS );
  1443. m_nLength = buffer.ReadUBitLong( 20 );
  1444. m_DataIn = buffer;
  1445. return buffer.SeekRelative( m_nLength );
  1446. }
  1447. const char *SVC_GameEventList::ToString(void) const
  1448. {
  1449. Q_snprintf(s_text, sizeof(s_text), "%s: number %i, bytes %i", GetName(), m_nNumEvents, Bits2Bytes(m_nLength) );
  1450. return s_text;
  1451. }
  1452. ///////////////////////////////////////////////////////////////////////////////////////
  1453. // Matchmaking messages:
  1454. ///////////////////////////////////////////////////////////////////////////////////////
  1455. bool MM_Heartbeat::WriteToBuffer( bf_write &buffer )
  1456. {
  1457. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1458. return !buffer.IsOverflowed();
  1459. }
  1460. bool MM_Heartbeat::ReadFromBuffer( bf_read &buffer )
  1461. {
  1462. return true;
  1463. }
  1464. const char *MM_Heartbeat::ToString( void ) const
  1465. {
  1466. Q_snprintf( s_text, sizeof( s_text ), "Heartbeat" );
  1467. return s_text;
  1468. }
  1469. bool MM_ClientInfo::WriteToBuffer( bf_write &buffer )
  1470. {
  1471. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1472. buffer.WriteBytes( &m_xnaddr, sizeof( m_xnaddr ) );
  1473. buffer.WriteLongLong( m_id ); // 64 bit
  1474. buffer.WriteByte( m_cPlayers );
  1475. buffer.WriteByte( m_bInvited );
  1476. for ( int i = 0; i < m_cPlayers; ++i )
  1477. {
  1478. buffer.WriteLongLong( m_xuids[i] ); // 64 bit
  1479. buffer.WriteBytes( &m_cVoiceState, sizeof( m_cVoiceState ) );
  1480. buffer.WriteLong( m_iTeam[i] );
  1481. buffer.WriteByte( m_iControllers[i] );
  1482. buffer.WriteString( m_szGamertags[i] );
  1483. }
  1484. return !buffer.IsOverflowed();
  1485. }
  1486. bool MM_ClientInfo::ReadFromBuffer( bf_read &buffer )
  1487. {
  1488. buffer.ReadBytes( &m_xnaddr, sizeof( m_xnaddr ) );
  1489. m_id = buffer.ReadLongLong(); // 64 bit
  1490. m_cPlayers = buffer.ReadByte();
  1491. m_bInvited = (buffer.ReadByte() != 0);
  1492. for ( int i = 0; i < m_cPlayers; ++i )
  1493. {
  1494. m_xuids[i] = buffer.ReadLongLong(); // 64 bit
  1495. buffer.ReadBytes( &m_cVoiceState, sizeof( m_cVoiceState ) );
  1496. m_iTeam[i] = buffer.ReadLong();
  1497. m_iControllers[i] = buffer.ReadByte();
  1498. buffer.ReadString( m_szGamertags[i], sizeof( m_szGamertags[i] ), true );
  1499. }
  1500. return !buffer.IsOverflowed();
  1501. }
  1502. const char *MM_ClientInfo::ToString( void ) const
  1503. {
  1504. Q_snprintf( s_text, sizeof( s_text ), "Client Info: ID: %llu, Players: %d", m_id, m_cPlayers );
  1505. return s_text;
  1506. }
  1507. bool MM_RegisterResponse::WriteToBuffer( bf_write &buffer )
  1508. {
  1509. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1510. return !buffer.IsOverflowed();
  1511. }
  1512. bool MM_RegisterResponse::ReadFromBuffer( bf_read &buffer )
  1513. {
  1514. return true;
  1515. }
  1516. const char *MM_RegisterResponse::ToString( void ) const
  1517. {
  1518. Q_snprintf( s_text, sizeof( s_text ), "Register Response" );
  1519. return s_text;
  1520. }
  1521. bool MM_Mutelist::WriteToBuffer( bf_write &buffer )
  1522. {
  1523. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1524. buffer.WriteLongLong( m_id );
  1525. buffer.WriteByte( m_cPlayers );
  1526. for ( int i = 0; i < m_cPlayers; ++i )
  1527. {
  1528. buffer.WriteByte( m_cRemoteTalkers[i] );
  1529. buffer.WriteLongLong( m_xuid[i] ); // 64 bit
  1530. buffer.WriteByte( m_cMuted[i] );
  1531. for ( int j = 0; j < m_cMuted[i]; ++j )
  1532. {
  1533. buffer.WriteLongLong( m_Muted[i][j] );
  1534. }
  1535. }
  1536. return !buffer.IsOverflowed();
  1537. }
  1538. bool MM_Mutelist::ReadFromBuffer( bf_read &buffer )
  1539. {
  1540. m_id = buffer.ReadLongLong();
  1541. m_cPlayers = buffer.ReadByte();
  1542. for ( int i = 0; i < m_cPlayers; ++i )
  1543. {
  1544. m_cRemoteTalkers[i] = buffer.ReadByte();
  1545. m_xuid[i] = buffer.ReadLongLong(); // 64 bit
  1546. m_cMuted[i] = buffer.ReadByte();
  1547. for ( int j = 0; j < m_cMuted[i]; ++j )
  1548. {
  1549. m_Muted[i].AddToTail( buffer.ReadLongLong() );
  1550. }
  1551. }
  1552. return !buffer.IsOverflowed();
  1553. }
  1554. const char *MM_Mutelist::ToString( void ) const
  1555. {
  1556. Q_snprintf( s_text, sizeof( s_text ), "Mutelist" );
  1557. return s_text;
  1558. }
  1559. bool MM_Checkpoint::WriteToBuffer( bf_write &buffer )
  1560. {
  1561. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1562. buffer.WriteByte( m_Checkpoint );
  1563. return !buffer.IsOverflowed();
  1564. }
  1565. bool MM_Checkpoint::ReadFromBuffer( bf_read &buffer )
  1566. {
  1567. m_Checkpoint = buffer.ReadByte();
  1568. return !buffer.IsOverflowed();
  1569. }
  1570. const char *MM_Checkpoint::ToString( void ) const
  1571. {
  1572. Q_snprintf( s_text, sizeof( s_text ), "Checkpoint: %d", m_Checkpoint );
  1573. return s_text;
  1574. }
  1575. // NOTE: This message is not network-endian compliant, due to the
  1576. // transmission of structures instead of their component parts
  1577. bool MM_JoinResponse::WriteToBuffer( bf_write &buffer )
  1578. {
  1579. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1580. buffer.WriteLong( m_ResponseType );
  1581. buffer.WriteLongLong( m_id ); // 64 bit
  1582. buffer.WriteLongLong( m_Nonce ); // 64 bit
  1583. buffer.WriteLong( m_SessionFlags );
  1584. buffer.WriteLong( m_nOwnerId );
  1585. buffer.WriteLong( m_iTeam );
  1586. buffer.WriteLong( m_nTotalTeams );
  1587. buffer.WriteByte( m_PropertyCount );
  1588. buffer.WriteByte( m_ContextCount );
  1589. for ( int i = 0; i < m_PropertyCount; ++i )
  1590. {
  1591. buffer.WriteBytes( &m_SessionProperties[i], sizeof( XUSER_PROPERTY ) );
  1592. }
  1593. for ( int i = 0; i < m_ContextCount; ++i )
  1594. {
  1595. buffer.WriteBytes( &m_SessionContexts[i], sizeof( XUSER_CONTEXT ) );
  1596. }
  1597. return !buffer.IsOverflowed();
  1598. }
  1599. bool MM_JoinResponse::ReadFromBuffer( bf_read &buffer )
  1600. {
  1601. m_ResponseType = buffer.ReadLong();
  1602. m_id = buffer.ReadLongLong(); // 64 bit
  1603. m_Nonce = buffer.ReadLongLong(); // 64 bit
  1604. m_SessionFlags = buffer.ReadLong();
  1605. m_nOwnerId = buffer.ReadLong();
  1606. m_iTeam = buffer.ReadLong();
  1607. m_nTotalTeams = buffer.ReadLong();
  1608. m_PropertyCount = buffer.ReadByte();
  1609. m_ContextCount = buffer.ReadByte();
  1610. XUSER_PROPERTY prop;
  1611. m_SessionProperties.RemoveAll();
  1612. for ( int i = 0; i < m_PropertyCount; ++i )
  1613. {
  1614. buffer.ReadBytes( &prop, sizeof( XUSER_PROPERTY ) );
  1615. m_SessionProperties.AddToTail( prop );
  1616. }
  1617. XUSER_CONTEXT ctx;
  1618. m_SessionContexts.RemoveAll();
  1619. for ( int i = 0; i < m_ContextCount; ++i )
  1620. {
  1621. buffer.ReadBytes( &ctx, sizeof( XUSER_CONTEXT ) );
  1622. m_SessionContexts.AddToTail( ctx );
  1623. }
  1624. return !buffer.IsOverflowed();
  1625. }
  1626. const char *MM_JoinResponse::ToString( void ) const
  1627. {
  1628. Q_snprintf( s_text, sizeof( s_text ), "ID: %llu, Nonce: %llu, Flags: %u", m_id, m_Nonce, m_SessionFlags );
  1629. return s_text;
  1630. }
  1631. // NOTE: This message is not network-endian compliant, due to the
  1632. // transmission of structures instead of their component parts
  1633. bool MM_Migrate::WriteToBuffer( bf_write &buffer )
  1634. {
  1635. Assert( IsX360() );
  1636. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1637. buffer.WriteByte( m_MsgType );
  1638. buffer.WriteLongLong( m_Id );
  1639. buffer.WriteBytes( &m_sessionId, sizeof( m_sessionId ) );
  1640. buffer.WriteBytes( &m_xnaddr, sizeof( m_xnaddr ) );
  1641. buffer.WriteBytes( &m_key, sizeof( m_key ) );
  1642. return !buffer.IsOverflowed();
  1643. }
  1644. bool MM_Migrate::ReadFromBuffer( bf_read &buffer )
  1645. {
  1646. Assert( IsX360() );
  1647. m_MsgType = buffer.ReadByte();
  1648. m_Id = buffer.ReadLongLong();
  1649. buffer.ReadBytes( &m_sessionId, sizeof( m_sessionId ) );
  1650. buffer.ReadBytes( &m_xnaddr, sizeof( m_xnaddr ) );
  1651. buffer.ReadBytes( &m_key, sizeof( m_key ) );
  1652. return !buffer.IsOverflowed();
  1653. }
  1654. const char *MM_Migrate::ToString( void ) const
  1655. {
  1656. Q_snprintf( s_text, sizeof( s_text ), "Migrate Message" );
  1657. return s_text;
  1658. }
  1659. bool SVC_GetCvarValue::WriteToBuffer( bf_write &buffer )
  1660. {
  1661. buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
  1662. buffer.WriteSBitLong( m_iCookie, 32 );
  1663. buffer.WriteString( m_szCvarName );
  1664. return !buffer.IsOverflowed();
  1665. }
  1666. bool SVC_GetCvarValue::ReadFromBuffer( bf_read &buffer )
  1667. {
  1668. VPROF( "SVC_GetCvarValue::ReadFromBuffer" );
  1669. m_iCookie = buffer.ReadSBitLong( 32 );
  1670. buffer.ReadString( m_szCvarNameBuffer, sizeof( m_szCvarNameBuffer ) );
  1671. m_szCvarName = m_szCvarNameBuffer;
  1672. return !buffer.IsOverflowed();
  1673. }
  1674. const char *SVC_GetCvarValue::ToString(void) const
  1675. {
  1676. Q_snprintf( s_text, sizeof(s_text), "%s: cvar: %s, cookie: %d", GetName(), m_szCvarName, m_iCookie );
  1677. return s_text;
  1678. }