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.

368 lines
9.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include "quakedef.h"
  14. #include <stddef.h>
  15. #include "vengineserver_impl.h"
  16. #include "server.h"
  17. #include "pr_edict.h"
  18. #include "world.h"
  19. #include "ispatialpartition.h"
  20. #include "utllinkedlist.h"
  21. #include "framesnapshot.h"
  22. #include "sv_log.h"
  23. #include "tier1/utlmap.h"
  24. #include "tier1/utlvector.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. // Edicts won't get reallocated for this many seconds after being freed.
  28. #define EDICT_FREETIME 1.0
  29. #ifdef _DEBUG
  30. #include <malloc.h>
  31. #endif // _DEBUG
  32. static ConVar sv_useexplicitdelete( "sv_useexplicitdelete", "1", FCVAR_DEVELOPMENTONLY, "Explicitly delete dormant client entities caused by AllowImmediateReuse()." );
  33. static ConVar sv_lowedict_threshold( "sv_lowedict_threshold", "8", FCVAR_NONE, "When only this many edicts are free, take the action specified by sv_lowedict_action.", true, 0, true, MAX_EDICTS );
  34. static ConVar sv_lowedict_action( "sv_lowedict_action", "0", FCVAR_NONE, "0 - no action, 1 - warn to log file, 2 - attempt to restart the game, if applicable, 3 - restart the map, 4 - go to the next map in the map cycle, 5 - spew all edicts.", true, 0, true, 5 );
  35. // Bitmask of free edicts.
  36. static CBitVec< MAX_EDICTS > g_FreeEdicts;
  37. /*
  38. =================
  39. ED_ClearEdict
  40. Sets everything to NULL, done when new entity is allocated for game.dll
  41. =================
  42. */
  43. static void ED_ClearEdict( edict_t *e )
  44. {
  45. e->ClearFree();
  46. e->ClearStateChanged();
  47. e->SetChangeInfoSerialNumber( 0 );
  48. serverGameEnts->FreeContainingEntity(e);
  49. InitializeEntityDLLFields(e);
  50. e->m_NetworkSerialNumber = -1; // must be filled by game.dll
  51. Assert( (int) e->m_EdictIndex == (e - sv.edicts) );
  52. }
  53. void ED_ClearFreeFlag( edict_t *e )
  54. {
  55. e->ClearFree();
  56. g_FreeEdicts.Clear( e->m_EdictIndex );
  57. }
  58. void ED_ClearFreeEdictList()
  59. {
  60. // Clear the free edicts bitfield.
  61. g_FreeEdicts.ClearAll();
  62. }
  63. static void SpewEdicts()
  64. {
  65. CUtlMap< const char*, int > mapEnts;
  66. mapEnts.SetLessFunc( StringLessThan );
  67. // Tally up each class
  68. int nEdictNum = 1;
  69. for( int i=0; i<sv.num_edicts; ++i )
  70. {
  71. edict_t *e = &sv.edicts[i];
  72. ++nEdictNum;
  73. unsigned short nIndex = mapEnts.Find( e->GetClassName() );
  74. if ( nIndex == mapEnts.InvalidIndex() )
  75. {
  76. nIndex = mapEnts.Insert( e->GetClassName() );
  77. mapEnts[ nIndex ] = 0;
  78. }
  79. mapEnts[ nIndex ] = mapEnts[ nIndex ] + 1;
  80. }
  81. struct EdictCount_t
  82. {
  83. EdictCount_t( const char *pszClassName, int nCount )
  84. :
  85. m_pszClassName( pszClassName ),
  86. m_nCount( nCount )
  87. {}
  88. const char *m_pszClassName;
  89. int m_nCount;
  90. };
  91. CUtlVector<EdictCount_t*> vecEnts;
  92. FOR_EACH_MAP_FAST( mapEnts, i )
  93. {
  94. vecEnts.AddToTail( new EdictCount_t( mapEnts.Key( i ), mapEnts[ i ] ) );
  95. }
  96. struct EdictSorter_t
  97. {
  98. static int SortEdicts( EdictCount_t* const *p1, EdictCount_t* const *p2 )
  99. {
  100. return (*p1)->m_nCount - (*p2)->m_nCount;
  101. }
  102. };
  103. vecEnts.Sort( &EdictSorter_t::SortEdicts );
  104. g_Log.Printf( "Spewing edict counts:\n" );
  105. FOR_EACH_VEC( vecEnts, i )
  106. {
  107. g_Log.Printf( "(%3.2f%%) %d\t%s\n", vecEnts[i]->m_nCount/(float)nEdictNum * 100.f, vecEnts[i]->m_nCount, vecEnts[i]->m_pszClassName );
  108. }
  109. g_Log.Printf( "Total edicts: %d\n", nEdictNum );
  110. vecEnts.PurgeAndDeleteElements();
  111. }
  112. /*
  113. =================
  114. ED_Alloc
  115. Either finds a free edict, or allocates a new one.
  116. Try to avoid reusing an entity that was recently freed, because it
  117. can cause the client to think the entity morphed into something else
  118. instead of being removed and recreated, which can cause interpolated
  119. angles and bad trails.
  120. =================
  121. */
  122. edict_t *ED_Alloc( int iForceEdictIndex )
  123. {
  124. if ( iForceEdictIndex >= 0 )
  125. {
  126. if ( iForceEdictIndex >= sv.num_edicts )
  127. {
  128. Warning( "ED_Alloc( %d ) - invalid edict index specified.", iForceEdictIndex );
  129. return NULL;
  130. }
  131. edict_t *e = &sv.edicts[ iForceEdictIndex ];
  132. if ( e->IsFree() )
  133. {
  134. Assert( iForceEdictIndex == e->m_EdictIndex );
  135. --sv.free_edicts;
  136. Assert( g_FreeEdicts.IsBitSet( iForceEdictIndex ) );
  137. g_FreeEdicts.Clear( iForceEdictIndex );
  138. ED_ClearEdict( e );
  139. return e;
  140. }
  141. else
  142. {
  143. return NULL;
  144. }
  145. }
  146. // Check the free list first.
  147. int iBit = -1;
  148. for ( ;; )
  149. {
  150. iBit = g_FreeEdicts.FindNextSetBit( iBit + 1 );
  151. if ( iBit < 0 )
  152. break;
  153. edict_t *pEdict = &sv.edicts[ iBit ];
  154. // If this assert goes off, someone most likely called pedict->ClearFree() and not ED_ClearFreeFlag()?
  155. Assert( pEdict->IsFree() );
  156. Assert( iBit == pEdict->m_EdictIndex );
  157. if ( ( pEdict->freetime < 2 ) || ( sv.GetTime() - pEdict->freetime >= EDICT_FREETIME ) )
  158. {
  159. // If we have no freetime, we've had AllowImmediateReuse() called. We need
  160. // to explicitly delete this old entity.
  161. if ( pEdict->freetime == 0 && sv_useexplicitdelete.GetBool() )
  162. {
  163. //Warning("ADDING SLOT to snapshot: %d\n", i );
  164. framesnapshotmanager->AddExplicitDelete( iBit );
  165. }
  166. --sv.free_edicts;
  167. g_FreeEdicts.Clear( pEdict->m_EdictIndex );
  168. ED_ClearEdict( pEdict );
  169. return pEdict;
  170. }
  171. }
  172. // Allocate a new edict.
  173. if ( sv.num_edicts >= sv.max_edicts )
  174. {
  175. AssertMsg( 0, "Can't allocate edict" );
  176. SpewEdicts(); // Log the entities we have before we die
  177. if ( sv.max_edicts == 0 )
  178. Sys_Error( "ED_Alloc: No edicts yet" );
  179. Sys_Error ("ED_Alloc: no free edicts");
  180. }
  181. // Do this before clearing since clear now needs to call back into the edict to deduce the index so can get the changeinfo data in the parallel structure
  182. edict_t *pEdict = sv.edicts + sv.num_edicts++;
  183. // We should not be in the free list...
  184. Assert( !g_FreeEdicts.IsBitSet( pEdict->m_EdictIndex ) );
  185. ED_ClearEdict( pEdict );
  186. if ( sv_lowedict_action.GetInt() > 0 && sv.num_edicts >= sv.max_edicts - sv_lowedict_threshold.GetInt() )
  187. {
  188. int nEdictsRemaining = sv.max_edicts - sv.num_edicts;
  189. g_Log.Printf( "Warning: free edicts below threshold. %i free edict%s remaining.\n", nEdictsRemaining, nEdictsRemaining == 1 ? "" : "s" );
  190. switch ( sv_lowedict_action.GetInt() )
  191. {
  192. case 2:
  193. // restart the game
  194. {
  195. ConVarRef mp_restartgame_immediate( "mp_restartgame_immediate" );
  196. if ( mp_restartgame_immediate.IsValid() )
  197. {
  198. mp_restartgame_immediate.SetValue( 1 );
  199. }
  200. else
  201. {
  202. ConVarRef mp_restartgame( "mp_restartgame" );
  203. if ( mp_restartgame.IsValid() )
  204. {
  205. mp_restartgame.SetValue( 1 );
  206. }
  207. }
  208. }
  209. break;
  210. case 3:
  211. // restart the map
  212. g_pVEngineServer->ChangeLevel( sv.GetMapName(), NULL );
  213. break;
  214. case 4:
  215. // go to the next map
  216. g_pVEngineServer->ServerCommand( "changelevel_next\n" );
  217. break;
  218. case 5:
  219. // spew all edicts
  220. SpewEdicts();
  221. break;
  222. }
  223. }
  224. return pEdict;
  225. }
  226. void ED_AllowImmediateReuse()
  227. {
  228. edict_t *pEdict = sv.edicts + sv.GetMaxClients() + 1;
  229. for ( int i=sv.GetMaxClients()+1; i < sv.num_edicts; i++ )
  230. {
  231. if ( pEdict->IsFree() )
  232. {
  233. pEdict->freetime = 0;
  234. }
  235. pEdict++;
  236. }
  237. }
  238. /*
  239. =================
  240. ED_Free
  241. Marks the edict as free
  242. FIXME: walk all entities and NULL out references to this entity
  243. =================
  244. */
  245. void ED_Free (edict_t *ed)
  246. {
  247. if (ed->IsFree())
  248. {
  249. #ifdef _DEBUG
  250. // ConDMsg("duplicate free on '%s'\n", pr_strings + ed->classname );
  251. #endif
  252. return;
  253. }
  254. // don't free player edicts
  255. if ( (ed - sv.edicts) >= 1 && (ed - sv.edicts) <= sv.GetMaxClients() )
  256. return;
  257. // release the DLL entity that's attached to this edict, if any
  258. serverGameEnts->FreeContainingEntity( ed );
  259. ed->SetFree();
  260. ed->freetime = sv.GetTime();
  261. ++sv.free_edicts;
  262. Assert( !g_FreeEdicts.IsBitSet( ed->m_EdictIndex ) );
  263. g_FreeEdicts.Set( ed->m_EdictIndex );
  264. // Increment the serial number so it knows to send explicit deletes the clients.
  265. ed->m_NetworkSerialNumber++;
  266. }
  267. //
  268. // serverGameEnts->FreeContainingEntity( pEdict ) frees up memory associated with a DLL entity.
  269. // InitializeEntityDLLFields clears out fields to NULL or UNKNOWN.
  270. // Release is for terminating a DLL entity. Initialize is for initializing one.
  271. //
  272. void InitializeEntityDLLFields( edict_t *pEdict )
  273. {
  274. // clear all the game variables
  275. size_t sz = offsetof( edict_t, m_pUnk ) + sizeof( void* );
  276. memset( ((byte*)pEdict) + sz, 0, sizeof(edict_t) - sz );
  277. }
  278. int NUM_FOR_EDICT(const edict_t *e)
  279. {
  280. if ( &sv.edicts[e->m_EdictIndex] == e ) // NOTE: old server.dll may stomp m_EdictIndex
  281. return e->m_EdictIndex;
  282. int index = e - sv.edicts;
  283. if ( (unsigned int) index >= (unsigned int) sv.num_edicts )
  284. Sys_Error ("NUM_FOR_EDICT: bad pointer");
  285. return index;
  286. }
  287. edict_t *EDICT_NUM(int n)
  288. {
  289. if ((unsigned int) n >= (unsigned int) sv.max_edicts)
  290. Sys_Error ("EDICT_NUM: bad number %i", n);
  291. return &sv.edicts[n];
  292. }
  293. static inline int NUM_FOR_EDICTINFO(const edict_t *e)
  294. {
  295. if ( &sv.edicts[e->m_EdictIndex] == e ) // NOTE: old server.dll may stomp m_EdictIndex
  296. return e->m_EdictIndex;
  297. int index = e - sv.edicts;
  298. if ( (unsigned int) index >= (unsigned int) sv.max_edicts )
  299. Sys_Error ("NUM_FOR_EDICTINFO: bad pointer");
  300. return index;
  301. }
  302. IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
  303. {
  304. return &sv.edictchangeinfo[ NUM_FOR_EDICTINFO( (const edict_t*)this ) ];
  305. }
  306. const IChangeInfoAccessor *CBaseEdict::GetChangeAccessor() const
  307. {
  308. return &sv.edictchangeinfo[ NUM_FOR_EDICTINFO( (const edict_t*)this ) ];
  309. }