From b0ce98d8477c44cb38f6a6fa854c71f193e28b4f Mon Sep 17 00:00:00 2001 From: Chomp Date: Thu, 6 Feb 2025 16:54:43 +0000 Subject: [PATCH] Store expired offer id inside `RagfairOfferService` instead of the offer itself --- .../Core/Services/RagfairOfferService.cs | 40 ++++++--------- Libraries/Core/Utils/RagfairOfferHolder.cs | 49 +++++++++++-------- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/Libraries/Core/Services/RagfairOfferService.cs b/Libraries/Core/Services/RagfairOfferService.cs index 1aec18a5..8b1f5d1a 100644 --- a/Libraries/Core/Services/RagfairOfferService.cs +++ b/Libraries/Core/Services/RagfairOfferService.cs @@ -22,17 +22,12 @@ public class RagfairOfferService( ItemHelper itemHelper, ProfileHelper profileHelper, LocalisationService localisationService, - ConfigServer configServer, ICloner cloner, RagfairOfferHolder ragfairOfferHolder ) { - protected bool playerOffersLoaded; - - /** Offer id + offer object */ - protected Dictionary expiredOffers = new(); - - protected RagfairConfig ragfairConfig = configServer.GetConfig(); + protected bool _playerOffersLoaded; + protected HashSet _expiredOfferIds = new(); /** * Get all offers @@ -60,7 +55,7 @@ public class RagfairOfferService( public void AddOfferToExpired(RagfairOffer staleOffer) { - expiredOffers[staleOffer.Id] = staleOffer; + _expiredOfferIds.Add(staleOffer.Id); } /** @@ -69,7 +64,7 @@ public class RagfairOfferService( */ public int GetExpiredOfferCount() { - return expiredOffers.Keys.Count; + return _expiredOfferIds.Count; } /** @@ -81,16 +76,17 @@ public class RagfairOfferService( // list of lists of item+children var expiredItems = new List>(); - foreach (var expiredOfferKvP in expiredOffers) + foreach (var expiredOfferId in _expiredOfferIds) { - if (expiredOfferKvP.Value?.Items is null) + var offer = ragfairOfferHolder.GetOfferById(expiredOfferId); + if (offer?.Items is null) { - logger.Error($"Unable to process expired offer: {expiredOfferKvP.Key}, it has no items"); + logger.Error($"Unable to process expired offer: {expiredOfferId}, it has no items"); continue; } - expiredItems.Add(expiredOfferKvP.Value.Items); + expiredItems.Add(offer.Items); } return expiredItems; @@ -101,7 +97,7 @@ public class RagfairOfferService( */ public void ResetExpiredOffers() { - expiredOffers.Clear(); + _expiredOfferIds.Clear(); } /** @@ -120,15 +116,7 @@ public class RagfairOfferService( */ public void RemoveOfferById(string offerId) { - var offer = ragfairOfferHolder.GetOfferById(offerId); - if (offer is null) - { - logger.Warning(localisationService.GetText("ragfair-unable_to_remove_offer_doesnt_exist", offerId)); - - return; - } - - ragfairOfferHolder.RemoveOffer(offer); + ragfairOfferHolder.RemoveOffer(offerId); } /** @@ -173,7 +161,7 @@ public class RagfairOfferService( public void AddPlayerOffers() { - if (!playerOffersLoaded) + if (!_playerOffersLoaded) { foreach (var sessionID in saveServer.GetProfiles().Keys) { @@ -186,7 +174,7 @@ public class RagfairOfferService( ragfairOfferHolder.AddOffers(pmcData.RagfairInfo.Offers); } - playerOffersLoaded = true; + _playerOffersLoaded = true; } } @@ -256,7 +244,7 @@ public class RagfairOfferService( playerOffer.Items[0].Upd.OriginalStackObjectsCount = null; // Remove player offer from flea - ragfairOfferHolder.RemoveOffer(playerOffer); + ragfairOfferHolder.RemoveOffer(playerOffer.Id); // Send failed offer items to player in mail var unstackedItems = UnstackOfferItems(playerOffer.Items); diff --git a/Libraries/Core/Utils/RagfairOfferHolder.cs b/Libraries/Core/Utils/RagfairOfferHolder.cs index 5445c4bb..164223b0 100644 --- a/Libraries/Core/Utils/RagfairOfferHolder.cs +++ b/Libraries/Core/Utils/RagfairOfferHolder.cs @@ -1,16 +1,20 @@ using Core.Helpers; using Core.Models.Eft.Ragfair; using Core.Models.Spt.Config; +using Core.Models.Utils; using Core.Servers; +using Core.Services; using SptCommon.Annotations; namespace Core.Utils; [Injectable(InjectionType.Singleton)] public class RagfairOfferHolder( + ISptLogger _logger, RagfairServerHelper ragfairServerHelper, ProfileHelper profileHelper, HashUtil hashUtil, + LocalisationService _localisationService, ConfigServer configServer) { protected Dictionary _offersById = new(); @@ -112,33 +116,36 @@ public class RagfairOfferHolder( * Purge offer from offer cache * @param offer Offer to remove */ - public void RemoveOffer(RagfairOffer offer) + public void RemoveOffer(string offerId) { lock (_offersByIdLock) { - if (_offersById.ContainsKey(offer.Id)) + if (!_offersById.TryGetValue(offerId, out var offer)) { - _offersById.Remove(offer.Id); - lock (_offersByTraderLock) - { - if (_offersByTrader.ContainsKey(offer.User.Id)) - { - _offersByTrader[offer.User.Id].Remove(offer.Id); - // This was causing a memory leak, we need to make sure that we remove - // the user ID from the cached offers after they dont have anything else - // on the flea placed. We regenerate the ID for the NPC users, making it - // continuously grow otherwise - if (_offersByTrader[offer.User.Id].Count == 0) _offersByTrader.Remove(offer.User.Id); - } - } + _logger.Warning(_localisationService.GetText("ragfair-unable_to_remove_offer_doesnt_exist", offerId)); + return; + } - lock (_offersByTemplateLock) + _offersById.Remove(offer.Id); + lock (_offersByTraderLock) + { + if (_offersByTrader.ContainsKey(offer.User.Id)) { - var firstItem = offer.Items.FirstOrDefault(); - if (_offersByTemplate.ContainsKey(firstItem.Template)) - { - _offersByTemplate[firstItem.Template].Remove(offer.Id); - } + _offersByTrader[offer.User.Id].Remove(offer.Id); + // This was causing a memory leak, we need to make sure that we remove + // the user ID from the cached offers after they dont have anything else + // on the flea placed. We regenerate the ID for the NPC users, making it + // continuously grow otherwise + if (_offersByTrader[offer.User.Id].Count == 0) _offersByTrader.Remove(offer.User.Id); + } + } + + lock (_offersByTemplateLock) + { + var firstItem = offer.Items.FirstOrDefault(); + if (_offersByTemplate.ContainsKey(firstItem.Template)) + { + _offersByTemplate[firstItem.Template].Remove(offer.Id); } } }