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.

582 lines
14 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "usercmd.h"
  9. #include "bitbuf.h"
  10. #include "checksum_md5.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. // TF2 specific, need enough space for OBJ_LAST items from tf_shareddefs.h
  14. #define WEAPON_SUBTYPE_BITS 6
  15. //-----------------------------------------------------------------------------
  16. #ifdef CLIENT_DLL
  17. ConVar net_showusercmd( "net_showusercmd", "0", 0, "Show user command encoding" );
  18. #define LogUserCmd( msg, ... ) if ( net_showusercmd.GetInt() ) { ConDMsg( msg, __VA_ARGS__ ); }
  19. #else
  20. #define LogUserCmd( msg, ... ) NULL;
  21. #endif
  22. //-----------------------------------------------------------------------------
  23. static bool WriteUserCmdDeltaInt( bf_write *buf, char *what, int from, int to, int bits = 32 )
  24. {
  25. if ( from != to )
  26. {
  27. LogUserCmd( "\t%s %d -> %d\n", what, from, to );
  28. buf->WriteOneBit( 1 );
  29. buf->WriteUBitLong( to, bits );
  30. return true;
  31. }
  32. buf->WriteOneBit( 0 );
  33. return false;
  34. }
  35. static bool WriteUserCmdDeltaShort( bf_write *buf, char *what, int from, int to )
  36. {
  37. if ( from != to )
  38. {
  39. LogUserCmd( "\t%s %d -> %d\n", what, from, to );
  40. buf->WriteOneBit( 1 );
  41. buf->WriteShort( to );
  42. return true;
  43. }
  44. buf->WriteOneBit( 0 );
  45. return false;
  46. }
  47. static bool WriteUserCmdDeltaFloat( bf_write *buf, char *what, float from, float to )
  48. {
  49. if ( from != to )
  50. {
  51. LogUserCmd( "\t%s %2.2f -> %2.2f\n", what, from, to );
  52. buf->WriteOneBit( 1 );
  53. buf->WriteFloat( to );
  54. return true;
  55. }
  56. buf->WriteOneBit( 0 );
  57. return false;
  58. }
  59. static bool WriteUserCmdDeltaCoord( bf_write *buf, char *what, float from, float to )
  60. {
  61. if ( from != to )
  62. {
  63. LogUserCmd( "\t%s %2.2f -> %2.2f\n", what, from, to );
  64. buf->WriteOneBit( 1 );
  65. buf->WriteBitCoord( to );
  66. return true;
  67. }
  68. buf->WriteOneBit( 0 );
  69. return false;
  70. }
  71. static bool WriteUserCmdDeltaAngle( bf_write *buf, char *what, float from, float to, int bits )
  72. {
  73. if ( from != to )
  74. {
  75. LogUserCmd( "\t%s %2.2f -> %2.2f\n", what, from, to );
  76. buf->WriteOneBit( 1 );
  77. buf->WriteBitAngle( to, bits );
  78. return true;
  79. }
  80. buf->WriteOneBit( 0 );
  81. return false;
  82. }
  83. static bool WriteUserCmdDeltaVec3Coord( bf_write *buf, char *what, const Vector &from, const Vector &to )
  84. {
  85. if ( from != to )
  86. {
  87. LogUserCmd( "\t%s %2.2f -> %2.2f\n", what, from.x, to.x );
  88. buf->WriteOneBit( 1 );
  89. buf->WriteBitVec3Coord( to );
  90. return true;
  91. }
  92. buf->WriteOneBit( 0 );
  93. return false;
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Purpose: Write a delta compressed user command.
  97. // Input : *buf -
  98. // *to -
  99. // *from -
  100. // Output : static
  101. //-----------------------------------------------------------------------------
  102. void WriteUsercmd( bf_write *buf, const CUserCmd *to, const CUserCmd *from )
  103. {
  104. LogUserCmd("WriteUsercmd: from=%d to=%d\n", from->command_number, to->command_number );
  105. WriteUserCmdDeltaInt( buf, "command_number", from->command_number + 1, to->command_number, 32 );
  106. WriteUserCmdDeltaInt( buf, "tick_count", from->tick_count + 1, to->tick_count, 32 );
  107. WriteUserCmdDeltaFloat( buf, "viewangles[0]", from->viewangles[0], to->viewangles[0] );
  108. WriteUserCmdDeltaFloat( buf, "viewangles[1]", from->viewangles[1], to->viewangles[1] );
  109. WriteUserCmdDeltaFloat( buf, "viewangles[2]", from->viewangles[2], to->viewangles[2] );
  110. // aim direction for motion controllers
  111. WriteUserCmdDeltaFloat( buf, "aimdirection[0]", from->aimdirection[0], to->aimdirection[0] );
  112. WriteUserCmdDeltaFloat( buf, "aimdirection[1]", from->aimdirection[1], to->aimdirection[1] );
  113. WriteUserCmdDeltaFloat( buf, "aimdirection[2]", from->aimdirection[2], to->aimdirection[2] );
  114. WriteUserCmdDeltaFloat( buf, "forwardmove", from->forwardmove, to->forwardmove );
  115. WriteUserCmdDeltaFloat( buf, "sidemove", from->sidemove, to->sidemove );
  116. WriteUserCmdDeltaFloat( buf, "upmove", from->upmove, to->upmove );
  117. WriteUserCmdDeltaInt( buf, "buttons", from->buttons, to->buttons, 32 );
  118. WriteUserCmdDeltaInt( buf, "impulse", from->impulse, to->impulse, 8 );
  119. #if defined( INFESTED_DLL ) || defined( DOTA_DLL )
  120. if ( to->crosshairtrace != from->crosshairtrace )
  121. {
  122. buf->WriteOneBit( 1 );
  123. buf->WriteBitVec3Coord( to->crosshairtrace );
  124. }
  125. else
  126. {
  127. buf->WriteOneBit( 0 );
  128. }
  129. if ( to->weaponselect != from->weaponselect )
  130. {
  131. buf->WriteOneBit( 1 );
  132. buf->WriteUBitLong( to->weaponselect, MAX_EDICT_BITS );
  133. }
  134. else
  135. {
  136. buf->WriteOneBit( 0 );
  137. }
  138. if ( to->weaponsubtype != from->weaponsubtype )
  139. {
  140. buf->WriteOneBit( 1 );
  141. buf->WriteUBitLong( to->weaponsubtype, WEAPON_SUBTYPE_BITS );
  142. }
  143. else
  144. {
  145. buf->WriteOneBit( 0 );
  146. }
  147. #endif
  148. #ifdef INFESTED_DLL // asw - check weapon subtype seperately, since we use it to say which marine we're controlling
  149. if ( to->crosshair_entity != from->crosshair_entity )
  150. {
  151. buf->WriteOneBit( 1 );
  152. buf->WriteShort( to->crosshair_entity );
  153. }
  154. else
  155. {
  156. buf->WriteOneBit( 0 );
  157. }
  158. if ( to->forced_action != from->forced_action )
  159. {
  160. buf->WriteOneBit( 1 );
  161. buf->WriteShort( to->forced_action );
  162. }
  163. else
  164. {
  165. buf->WriteOneBit( 0 );
  166. }
  167. if ( to->sync_kill_ent != from->sync_kill_ent )
  168. {
  169. buf->WriteOneBit( 1 );
  170. buf->WriteShort( to->sync_kill_ent );
  171. }
  172. else
  173. {
  174. buf->WriteOneBit( 0 );
  175. }
  176. WriteUserCmdDeltaVec3Coord( buf, "skill_dest", from->skill_dest, to->skill_dest );
  177. if ( to->skill_dest_ent != from->skill_dest_ent )
  178. {
  179. buf->WriteOneBit( 1 );
  180. buf->WriteShort( to->skill_dest_ent );
  181. }
  182. else
  183. {
  184. buf->WriteOneBit( 0 );
  185. }
  186. #else
  187. if ( WriteUserCmdDeltaInt( buf, "weaponselect", from->weaponselect, to->weaponselect, MAX_EDICT_BITS ) )
  188. {
  189. WriteUserCmdDeltaInt( buf, "weaponsubtype", from->weaponsubtype, to->weaponsubtype, WEAPON_SUBTYPE_BITS );
  190. }
  191. #endif
  192. // TODO: Can probably get away with fewer bits.
  193. WriteUserCmdDeltaShort( buf, "mousedx", from->mousedx, to->mousedx );
  194. WriteUserCmdDeltaShort( buf, "mousedy", from->mousedy, to->mousedy );
  195. #if defined( HL2_CLIENT_DLL )
  196. if ( to->entitygroundcontact.Count() != 0 )
  197. {
  198. LogUserCmd( "\t%s %d\n", "entitygroundcontact", to->entitygroundcontact.Count() );
  199. buf->WriteOneBit( 1 );
  200. buf->WriteShort( to->entitygroundcontact.Count() );
  201. int i;
  202. for (i = 0; i < to->entitygroundcontact.Count(); i++)
  203. {
  204. LogUserCmd( "\t\t%s %d\n", "entitygroundcontact[%d].entindex", i, to->entitygroundcontact[i].entindex );
  205. buf->WriteUBitLong( to->entitygroundcontact[i].entindex, MAX_EDICT_BITS );
  206. LogUserCmd( "\t\t%s %2.2f\n", "entitygroundcontact[%d].minheight", i, to->entitygroundcontact[i].minheight );
  207. buf->WriteBitCoord( to->entitygroundcontact[i].minheight );
  208. LogUserCmd( "\t\t%s %2.2f\n", "entitygroundcontact[%d].maxheight", i, to->entitygroundcontact[i].maxheight );
  209. buf->WriteBitCoord( to->entitygroundcontact[i].maxheight );
  210. }
  211. }
  212. else
  213. {
  214. buf->WriteOneBit( 0 );
  215. }
  216. #endif
  217. #if defined ( PORTAL2 )
  218. if ( to->player_held_entity != from->player_held_entity )
  219. {
  220. buf->WriteOneBit( 1 );
  221. buf->WriteShort( to->player_held_entity );
  222. }
  223. else
  224. {
  225. buf->WriteOneBit( 0 );
  226. }
  227. if ( to->held_entity_was_grabbed_through_portal != from->held_entity_was_grabbed_through_portal )
  228. {
  229. buf->WriteOneBit( 1 );
  230. buf->WriteShort( to->held_entity_was_grabbed_through_portal );
  231. }
  232. else
  233. {
  234. buf->WriteOneBit( 0 );
  235. }
  236. if( to->command_acknowledgements_pending != from->command_acknowledgements_pending )
  237. {
  238. buf->WriteOneBit( 1 );
  239. buf->WriteShort( to->command_acknowledgements_pending );
  240. }
  241. else
  242. {
  243. buf->WriteOneBit( 0 );
  244. }
  245. if( to->predictedPortalTeleportations != from->predictedPortalTeleportations )
  246. {
  247. buf->WriteOneBit( 1 );
  248. buf->WriteByte( to->predictedPortalTeleportations );
  249. }
  250. else
  251. {
  252. buf->WriteOneBit( 0 );
  253. }
  254. #endif
  255. #ifdef DOTA_DLL
  256. if ( to->dota_unitorders.m_nOrderSequenceNumber != from->dota_unitorders.m_nOrderSequenceNumber )
  257. {
  258. buf->WriteOneBit( 1 );
  259. buf->WriteShort( to->dota_unitorders.m_nOrderSequenceNumber );
  260. buf->WriteShort( to->dota_unitorders.m_nUnits.Count() );
  261. int i;
  262. for ( i = 0; i < to->dota_unitorders.m_nUnits.Count(); i++)
  263. {
  264. buf->WriteUBitLong( to->dota_unitorders.m_nUnits[i], MAX_EDICT_BITS );
  265. }
  266. buf->WriteShort( to->dota_unitorders.m_nOrderType );
  267. buf->WriteShort( to->dota_unitorders.m_nTargetIndex );
  268. buf->WriteBitVec3Coord( to->dota_unitorders.m_vPosition );
  269. buf->WriteUBitLong( to->dota_unitorders.m_nAbilityIndex, MAX_EDICT_BITS );
  270. }
  271. else
  272. {
  273. buf->WriteOneBit( 0 );
  274. }
  275. #endif
  276. if ( IsHeadTrackingEnabled() )
  277. {
  278. // TrackIR head angles
  279. WriteUserCmdDeltaAngle( buf, "headangles[0]", from->headangles[ 0 ], to->headangles[ 0 ], 16 );
  280. WriteUserCmdDeltaAngle( buf, "headangles[1]", from->headangles[ 1 ], to->headangles[ 1 ], 16 );
  281. WriteUserCmdDeltaAngle( buf, "headangles[2]", from->headangles[ 2 ], to->headangles[ 2 ], 8 );
  282. // TrackIR head offset
  283. WriteUserCmdDeltaVec3Coord( buf, "headoffset", from->headoffset, to->headoffset );
  284. // TrackIR
  285. }
  286. }
  287. //-----------------------------------------------------------------------------
  288. // Purpose: Read in a delta compressed usercommand.
  289. // Input : *buf -
  290. // *move -
  291. // *from -
  292. // Output : static void ReadUsercmd
  293. //-----------------------------------------------------------------------------
  294. void ReadUsercmd( bf_read *buf, CUserCmd *move, CUserCmd *from )
  295. {
  296. // Assume no change
  297. *move = *from;
  298. if ( buf->ReadOneBit() )
  299. {
  300. move->command_number = buf->ReadUBitLong( 32 );
  301. }
  302. else
  303. {
  304. // Assume steady increment
  305. move->command_number = from->command_number + 1;
  306. }
  307. if ( buf->ReadOneBit() )
  308. {
  309. move->tick_count = buf->ReadUBitLong( 32 );
  310. }
  311. else
  312. {
  313. // Assume steady increment
  314. move->tick_count = from->tick_count + 1;
  315. }
  316. // Read direction
  317. if ( buf->ReadOneBit() )
  318. {
  319. move->viewangles[0] = buf->ReadFloat();
  320. }
  321. if ( buf->ReadOneBit() )
  322. {
  323. move->viewangles[1] = buf->ReadFloat();
  324. }
  325. if ( buf->ReadOneBit() )
  326. {
  327. move->viewangles[2] = buf->ReadFloat();
  328. }
  329. // Read aim direction
  330. if ( buf->ReadOneBit() )
  331. {
  332. move->aimdirection[0] = buf->ReadFloat();
  333. }
  334. if ( buf->ReadOneBit() )
  335. {
  336. move->aimdirection[1] = buf->ReadFloat();
  337. }
  338. if ( buf->ReadOneBit() )
  339. {
  340. move->aimdirection[2] = buf->ReadFloat();
  341. }
  342. // Read movement
  343. if ( buf->ReadOneBit() )
  344. {
  345. float flMove = buf->ReadFloat();
  346. move->forwardmove = IsFinite( flMove ) && IsEntityCoordinateReasonable( flMove ) ? flMove : 0;
  347. }
  348. if ( buf->ReadOneBit() )
  349. {
  350. float flMove = buf->ReadFloat();
  351. move->sidemove = IsFinite( flMove ) && IsEntityCoordinateReasonable( flMove ) ? flMove : 0;
  352. }
  353. if ( buf->ReadOneBit() )
  354. {
  355. float flMove = buf->ReadFloat();
  356. move->upmove = IsFinite( flMove ) && IsEntityCoordinateReasonable( flMove ) ? flMove : 0;
  357. }
  358. // read buttons
  359. if ( buf->ReadOneBit() )
  360. {
  361. move->buttons = buf->ReadUBitLong( 32 );
  362. }
  363. if ( buf->ReadOneBit() )
  364. {
  365. move->impulse = buf->ReadUBitLong( 8 );
  366. }
  367. #if defined( INFESTED_DLL ) || defined( DOTA_DLL )
  368. if ( buf->ReadOneBit() )
  369. {
  370. buf->ReadBitVec3Coord( move->crosshairtrace );
  371. }
  372. if ( buf->ReadOneBit() )
  373. {
  374. move->weaponselect = buf->ReadUBitLong( MAX_EDICT_BITS );
  375. }
  376. if ( buf->ReadOneBit() )
  377. {
  378. move->weaponsubtype = buf->ReadUBitLong( WEAPON_SUBTYPE_BITS );
  379. }
  380. #endif
  381. #ifdef INFESTED_DLL // asw - check weapon subtype seperately, since we use it to say which marine we're controlling
  382. if ( buf->ReadOneBit() )
  383. {
  384. move->crosshair_entity = buf->ReadShort();
  385. }
  386. if ( buf->ReadOneBit() )
  387. {
  388. move->forced_action = buf->ReadShort();
  389. }
  390. if ( buf->ReadOneBit() )
  391. {
  392. move->sync_kill_ent = buf->ReadShort();
  393. }
  394. if ( buf->ReadOneBit() )
  395. {
  396. buf->ReadBitVec3Coord(move->skill_dest);
  397. }
  398. if ( buf->ReadOneBit() )
  399. {
  400. move->skill_dest_ent = buf->ReadShort();
  401. }
  402. #else
  403. if ( buf->ReadOneBit() )
  404. {
  405. move->weaponselect = buf->ReadUBitLong( MAX_EDICT_BITS );
  406. if ( buf->ReadOneBit() )
  407. {
  408. move->weaponsubtype = buf->ReadUBitLong( WEAPON_SUBTYPE_BITS );
  409. }
  410. }
  411. #endif
  412. move->random_seed = MD5_PseudoRandom( move->command_number ) & 0x7fffffff;
  413. if ( buf->ReadOneBit() )
  414. {
  415. move->mousedx = buf->ReadShort();
  416. }
  417. if ( buf->ReadOneBit() )
  418. {
  419. move->mousedy = buf->ReadShort();
  420. }
  421. #if defined( HL2_DLL )
  422. if ( buf->ReadOneBit() )
  423. {
  424. move->entitygroundcontact.SetCount( buf->ReadShort() );
  425. int i;
  426. for (i = 0; i < move->entitygroundcontact.Count(); i++)
  427. {
  428. move->entitygroundcontact[i].entindex = buf->ReadUBitLong( MAX_EDICT_BITS );
  429. move->entitygroundcontact[i].minheight = buf->ReadBitCoord( );
  430. move->entitygroundcontact[i].maxheight = buf->ReadBitCoord( );
  431. }
  432. }
  433. #endif
  434. #if defined ( PORTAL2 )
  435. if ( buf->ReadOneBit() )
  436. {
  437. move->player_held_entity = buf->ReadShort();
  438. }
  439. if ( buf->ReadOneBit() )
  440. {
  441. move->held_entity_was_grabbed_through_portal = buf->ReadShort();
  442. }
  443. if ( buf->ReadOneBit() )
  444. {
  445. move->command_acknowledgements_pending = buf->ReadShort();
  446. }
  447. if ( buf->ReadOneBit() )
  448. {
  449. move->predictedPortalTeleportations = buf->ReadByte();
  450. }
  451. #endif
  452. #ifdef DOTA_DLL
  453. if ( buf->ReadOneBit() )
  454. {
  455. move->dota_unitorders.m_nOrderSequenceNumber = buf->ReadShort();
  456. move->dota_unitorders.m_nUnits.SetCount( buf->ReadShort() );
  457. int i;
  458. for (i = 0; i < move->dota_unitorders.m_nUnits.Count(); i++)
  459. {
  460. move->dota_unitorders.m_nUnits[i] = buf->ReadUBitLong( MAX_EDICT_BITS );
  461. }
  462. move->dota_unitorders.m_nOrderType = buf->ReadShort();
  463. move->dota_unitorders.m_nTargetIndex = buf->ReadShort();
  464. buf->ReadBitVec3Coord( move->dota_unitorders.m_vPosition );
  465. move->dota_unitorders.m_nAbilityIndex = buf->ReadUBitLong( MAX_EDICT_BITS );
  466. }
  467. #endif
  468. if ( IsHeadTrackingEnabled() )
  469. {
  470. // TrackIR head angles
  471. if ( buf->ReadOneBit() )
  472. {
  473. move->headangles[0] = buf->ReadBitAngle( 16 );
  474. }
  475. if ( buf->ReadOneBit() )
  476. {
  477. move->headangles[1] = buf->ReadBitAngle( 16 );
  478. }
  479. if ( buf->ReadOneBit() )
  480. {
  481. move->headangles[2] = buf->ReadBitAngle( 8 );
  482. }
  483. // TrackIR head offset
  484. if ( buf->ReadOneBit() )
  485. {
  486. buf->ReadBitVec3Coord(move->headoffset);
  487. }
  488. // TrackIR
  489. }
  490. }