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.

325 lines
8.7 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "checksum_crc.h"
  9. #include "tier1/strtools.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. #if !defined( NO_ENTITY_PREDICTION ) && defined( USE_PREDICTABLEID )
  13. //-----------------------------------------------------------------------------
  14. // Purpose: Helper class for resetting instance numbers, etc.
  15. //-----------------------------------------------------------------------------
  16. class CPredictableIdHelper
  17. {
  18. public:
  19. CPredictableIdHelper()
  20. {
  21. memset( m_Entries, 0, sizeof( m_Entries ) );
  22. Reset( -1 );
  23. }
  24. void Reset( int command )
  25. {
  26. m_nCurrentCommand = command;
  27. m_nCount = 0;
  28. }
  29. int AddEntry( int command, int hash )
  30. {
  31. // Clear list if command number changes
  32. if ( command != m_nCurrentCommand )
  33. {
  34. Reset( command );
  35. }
  36. entry *e = FindOrAddEntry( hash );
  37. if ( !e )
  38. return 0;
  39. e->count++;
  40. return e->count-1;
  41. }
  42. private:
  43. enum
  44. {
  45. MAX_ENTRIES = 256,
  46. };
  47. struct entry
  48. {
  49. int hash;
  50. int count;
  51. };
  52. entry *FindOrAddEntry( int hash )
  53. {
  54. int i;
  55. for ( i = 0; i < m_nCount; i++ )
  56. {
  57. entry *e = &m_Entries[ i ];
  58. if ( e->hash == hash )
  59. return e;
  60. }
  61. if ( m_nCount >= MAX_ENTRIES )
  62. {
  63. // assert( 0 );
  64. return NULL;
  65. }
  66. entry *e = &m_Entries[ m_nCount++ ];
  67. e->hash = hash;
  68. e->count = 0;
  69. return e;
  70. }
  71. int m_nCurrentCommand;
  72. int m_nCount;
  73. entry m_Entries[ MAX_ENTRIES ];
  74. };
  75. static CPredictableIdHelper g_Helper;
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. //-----------------------------------------------------------------------------
  79. CPredictableId::CPredictableId( void )
  80. {
  81. memset( &m_PredictableID, 0, sizeof( m_PredictableID ) );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose:
  85. //-----------------------------------------------------------------------------
  86. void CPredictableId::ResetInstanceCounters( void )
  87. {
  88. g_Helper.Reset( -1 );
  89. }
  90. //-----------------------------------------------------------------------------
  91. // Purpose: Is the Id being used
  92. // Output : Returns true on success, false on failure.
  93. //-----------------------------------------------------------------------------
  94. bool CPredictableId::IsActive( void ) const
  95. {
  96. if ( *(const int *)&m_PredictableID == 0 )
  97. return false;
  98. return true;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose:
  102. // Input : playerIndex -
  103. //-----------------------------------------------------------------------------
  104. void CPredictableId::SetPlayer( int playerIndex )
  105. {
  106. m_PredictableID.player = (unsigned int)playerIndex;
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Purpose:
  110. // Output : int
  111. //-----------------------------------------------------------------------------
  112. int CPredictableId::GetPlayer( void ) const
  113. {
  114. return (int)m_PredictableID.player;
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. // Output : int
  119. //-----------------------------------------------------------------------------
  120. int CPredictableId::GetCommandNumber( void ) const
  121. {
  122. return (int)m_PredictableID.command;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose:
  126. // Input : commandNumber -
  127. //-----------------------------------------------------------------------------
  128. void CPredictableId::SetCommandNumber( int commandNumber )
  129. {
  130. m_PredictableID.command = (unsigned int)commandNumber;
  131. }
  132. /*
  133. bool CPredictableId::IsCommandNumberEqual( int testNumber ) const
  134. {
  135. if ( ( testNumber & ((1<<10) - 1) ) == m_PredictableID.command )
  136. return true;
  137. return false;
  138. }
  139. */
  140. //-----------------------------------------------------------------------------
  141. // Purpose:
  142. // Input : *classname -
  143. // *module -
  144. // line -
  145. // Output : static int
  146. //-----------------------------------------------------------------------------
  147. static int ClassFileLineHash( const char *classname, const char *module, int line )
  148. {
  149. CRC32_t retval;
  150. CRC32_Init( &retval );
  151. char tempbuffer[ 512 ];
  152. // ACK, have to go lower case due to issues with .dsp having different cases of drive
  153. // letters, etc.!!!
  154. Q_strncpy( tempbuffer, classname, sizeof( tempbuffer ) );
  155. Q_strlower( tempbuffer );
  156. CRC32_ProcessBuffer( &retval, (void *)tempbuffer, Q_strlen( tempbuffer ) );
  157. Q_strncpy( tempbuffer, module, sizeof( tempbuffer ) );
  158. Q_strlower( tempbuffer );
  159. CRC32_ProcessBuffer( &retval, (void *)tempbuffer, Q_strlen( tempbuffer ) );
  160. CRC32_ProcessBuffer( &retval, (void *)&line, sizeof( int ) );
  161. CRC32_Final( &retval );
  162. return (int)retval;
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Purpose: Create a predictable id of the specified parameter set
  166. // Input : player -
  167. // command -
  168. // *classname -
  169. // *module -
  170. // line -
  171. //-----------------------------------------------------------------------------
  172. void CPredictableId::Init( int player, int command, const char *classname, const char *module, int line )
  173. {
  174. SetPlayer( player );
  175. SetCommandNumber( command );
  176. m_PredictableID.hash = ClassFileLineHash( classname, module, line );
  177. // Use helper to determine instance number this command
  178. int instance = g_Helper.AddEntry( command, m_PredictableID.hash );
  179. // Set appropriate instance number
  180. SetInstanceNumber( instance );
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose:
  184. // Output : int
  185. //-----------------------------------------------------------------------------
  186. int CPredictableId::GetHash( void ) const
  187. {
  188. return (int)m_PredictableID.hash;
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Purpose:
  192. // Input : counter -
  193. //-----------------------------------------------------------------------------
  194. void CPredictableId::SetInstanceNumber( int counter )
  195. {
  196. m_PredictableID.instance = (unsigned int)counter;
  197. }
  198. //-----------------------------------------------------------------------------
  199. // Purpose:
  200. // Output : int
  201. //-----------------------------------------------------------------------------
  202. int CPredictableId::GetInstanceNumber( void ) const
  203. {
  204. return (int)m_PredictableID.instance;
  205. }
  206. // Client only
  207. //-----------------------------------------------------------------------------
  208. // Purpose:
  209. // Input : ack -
  210. //-----------------------------------------------------------------------------
  211. void CPredictableId::SetAcknowledged( bool ack )
  212. {
  213. m_PredictableID.ack = ack ? 1 : 0;
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Purpose:
  217. // Output : Returns true on success, false on failure.
  218. //-----------------------------------------------------------------------------
  219. bool CPredictableId::GetAcknowledged( void ) const
  220. {
  221. return m_PredictableID.ack ? true : false;
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose:
  225. // Output : int
  226. //-----------------------------------------------------------------------------
  227. int CPredictableId::GetRaw( void ) const
  228. {
  229. return *(int *)&m_PredictableID;
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose:
  233. // Input : raw -
  234. //-----------------------------------------------------------------------------
  235. void CPredictableId::SetRaw( int raw )
  236. {
  237. *(int *)&m_PredictableID = raw;
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose: Determine if one id is == another, ignores Acknowledged state
  241. // Input : other -
  242. // Output : bool CPredictableId::operator
  243. //-----------------------------------------------------------------------------
  244. bool CPredictableId::operator ==( const CPredictableId& other ) const
  245. {
  246. if ( this == &other )
  247. return true;
  248. if ( GetPlayer() != other.GetPlayer() )
  249. return false;
  250. if ( GetCommandNumber() != other.GetCommandNumber() )
  251. return false;
  252. if ( GetHash() != other.GetHash() )
  253. return false;
  254. if ( GetInstanceNumber() != other.GetInstanceNumber() )
  255. return false;
  256. return true;
  257. }
  258. bool CPredictableId::operator !=( const CPredictableId& other ) const
  259. {
  260. return !(*this == other);
  261. }
  262. //-----------------------------------------------------------------------------
  263. // Purpose:
  264. // Output : char const
  265. //-----------------------------------------------------------------------------
  266. const char *CPredictableId::Describe( void ) const
  267. {
  268. static char desc[ 128 ];
  269. Q_snprintf( desc, sizeof( desc ), "pl(%i) cmd(%i) hash(%i) inst(%i) ack(%s)",
  270. GetPlayer(),
  271. GetCommandNumber(),
  272. GetHash(),
  273. GetInstanceNumber() ,
  274. GetAcknowledged() ? "true" : "false" );
  275. return desc;
  276. }
  277. #endif