From 584073cc5755fb6b4c638e24b1701fb8baf72c26 Mon Sep 17 00:00:00 2001 From: Xekep Date: Thu, 26 Feb 2026 15:32:45 +0300 Subject: [PATCH] Make projectile cleanup deterministic in OnSecondUpdate Run cleanup on the second-update path directly and remove stale entries in place with RemoveAll. This avoids spawning a background task each second and avoids replacing the list reference while other code may lock it. --- TShockAPI/Bouncer.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 6628a67b2..ffe718149 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -3056,20 +3056,17 @@ internal void OnQuickStack(object sender, OTAPI.Hooks.Chest.QuickStackEventArgs internal void OnSecondUpdate() { - Task.Run(() => + var threshold = DateTime.UtcNow.AddSeconds(-5); + foreach (var player in TShock.Players) { - foreach (var player in TShock.Players) + if (player != null && player.TPlayer.whoAmI >= 0) { - if (player != null && player.TPlayer.whoAmI >= 0) + lock (player.RecentlyCreatedProjectiles) { - var threshold = DateTime.Now.AddSeconds(-5); - lock (player.RecentlyCreatedProjectiles) - { - player.RecentlyCreatedProjectiles = player.RecentlyCreatedProjectiles.Where(s => s.CreatedAt > threshold).ToList(); - } + player.RecentlyCreatedProjectiles.RemoveAll(s => s.CreatedAt <= threshold); } } - }); + } } ///