File tree Expand file tree Collapse file tree 1 file changed +33
-0
lines changed
Expand file tree Collapse file tree 1 file changed +33
-0
lines changed Original file line number Diff line number Diff line change @@ -205,6 +205,39 @@ edict_t *ED_Alloc( int iForceEdictIndex )
205205 // Allocate a new edict.
206206 if ( sv.num_edicts >= sv.max_edicts )
207207 {
208+ if ( sv.max_edicts != 0 )
209+ {
210+ // We don't have any available edicts that are newer than
211+ // EDICT_FREETIME. Rather than crash/restart try to find an edict that
212+ // was deleted less than EDICT_FREETIME ago. This will protect us
213+ // against potential server hacks like those used to crash
214+ // dota2 servers.
215+ iBit = -1 ;
216+ for ( ;; )
217+ {
218+ iBit = g_FreeEdicts.FindNextSetBit ( iBit + 1 );
219+ if ( iBit < 0 )
220+ break ;
221+
222+ edict_t *pEdict = &sv.edicts [ iBit ];
223+
224+ // If this assert goes off, someone most likely called pedict->ClearFree() and not ED_ClearFreeFlag()?
225+ Assert ( pEdict->IsFree () );
226+ Assert ( iBit == pEdict->m_EdictIndex );
227+ // If we have no freetime, we've had AllowImmediateReuse() called. We need
228+ // to explicitly delete this old entity.
229+ if ( pEdict->freetime == 0 && sv_useexplicitdelete.GetBool () )
230+ {
231+ // Warning("ADDING SLOT to snapshot: %d\n", i );
232+ framesnapshotmanager->AddExplicitDelete ( iBit );
233+ }
234+ --sv.free_edicts ;
235+ g_FreeEdicts.Clear ( pEdict->m_EdictIndex );
236+ ED_ClearEdict ( pEdict );
237+ return pEdict;
238+ }
239+ }
240+
208241 AssertMsg ( 0 , " Can't allocate edict" );
209242
210243 SpewEdicts (); // Log the entities we have before we die
You can’t perform that action at this time.
0 commit comments