diff --git a/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs b/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs index b62db5f8..c2812a6c 100644 --- a/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs @@ -27,7 +27,7 @@ public class RagfairOfferService( ConfigServer configServer ) { - protected bool _playerOffersLoaded; + private bool _playerOffersLoaded; protected RagfairConfig _ragfairConfig = configServer.GetConfig(); /// @@ -89,11 +89,15 @@ public class RagfairOfferService( offer.Quantity -= amount; if (offer.Quantity <= 0) { - // Reducing Quantity has made it 0 or below, offer is now 'stale' and needs to be flagged as expired so it can be removed/regenerated on the next ragfair update() - ragfairOfferHolder.FlagOfferAsExpired(offer.Id); + // Offer is gone and now 'stale', need to be flagged as stale or removed if PMC offer + ProcessStaleOffer(offerId); } } + /// + /// Remove all offers from ragfair made by trader + /// + /// Trader to remove offers for public void RemoveAllOffersByTrader(string traderId) { ragfairOfferHolder.RemoveAllOffersByTrader(traderId); @@ -119,6 +123,9 @@ public class RagfairOfferService( return trader.Base.RefreshTraderRagfairOffers.Value; } + /// + /// Iterate over player profiles and add offers to flea market offer cache + /// public void AddPlayerOffers() { if (_playerOffersLoaded) @@ -129,9 +136,8 @@ public class RagfairOfferService( foreach (var sessionId in saveServer.GetProfiles().Keys) { var pmcData = saveServer.GetProfile(sessionId)?.CharacterData?.PmcData; - if (pmcData?.RagfairInfo?.Offers == null) - // Profile is wiped + // Profile has been wiped, ignore { continue; } @@ -143,7 +149,7 @@ public class RagfairOfferService( } /// - /// Process the expired ids and remove offers + /// Process stored offer ids and remove expired /// public void RemoveExpiredOffers() { @@ -156,63 +162,71 @@ public class RagfairOfferService( /// /// Remove stale offer from flea /// - /// Stale offer to process - protected void ProcessStaleOffer(RagfairOffer staleOffer) + /// Stale offer id to process + protected void ProcessStaleOffer(string staleOfferId) { - var staleOfferId = staleOffer.Id; - var staleOfferUserId = staleOffer.User.Id; + var staleOffer = ragfairOfferHolder.GetOfferById(staleOfferId); + var isTrader = ragfairServerHelper.IsTrader(staleOffer.User.Id); + var isPlayer = profileHelper.IsPlayer(staleOffer.User.Id.RegexReplace("^pmc", "")); - var isTrader = ragfairServerHelper.IsTrader(staleOfferUserId); - var isPlayer = profileHelper.IsPlayer(staleOfferUserId.RegexReplace("^pmc", "")); - - // Skip trader offers, managed by RagfairServer.update() + // Skip trader offers, managed by RagfairServer.Update() + should remain on flea as 'expired' if (isTrader) { return; } - // Handle dynamic offer - if (!(isTrader || isPlayer)) + // Handle dynamic offer from PMCs + if (!isPlayer) { // Not trader/player offer ragfairOfferHolder.FlagOfferAsExpired(staleOfferId); } - // Handle player offer - items need returning/XP adjusting. Checking if offer has actually expired or not. + // Handle player offer - item(s) need returning/XP/rep adjusting. Checking if offer has actually expired or not. if (isPlayer && staleOffer.EndTime <= timeUtil.GetTimeStamp()) { - ReturnPlayerOffer(staleOffer); + ReturnUnsoldPlayerOffer(staleOffer); + return; } - // Remove expired existing offer from global offers + // Remove expired offer from global flea pool RemoveOfferById(staleOfferId); } - protected void ReturnPlayerOffer(RagfairOffer playerOffer) + /// + /// Process a player offer that didn't sell + /// Reduce rep + /// Send items back in mail + /// Increment `notSellSum` value + /// + /// Offer to process + protected void ReturnUnsoldPlayerOffer(RagfairOffer playerOffer) { - var pmcId = playerOffer.User.Id; - var profile = profileHelper.GetProfileByPmcId(pmcId); - if (profile == null) + var offerCreatorId = playerOffer.User.Id; + var offerCreatorProfile = profileHelper.GetProfileByPmcId(offerCreatorId); + if (offerCreatorProfile == null) { - logger.Error($"Unable to return flea offer {playerOffer.Id} as the profile: {pmcId} could not be found"); + logger.Error($"Unable to return flea offer: {playerOffer.Id} as the profile: {offerCreatorId} could not be found"); + return; } - var offerinProfileIndex = profile.RagfairInfo.Offers.FindIndex(o => o.Id == playerOffer.Id); - if (offerinProfileIndex == -1) + var indexOfOfferInProfile = offerCreatorProfile.RagfairInfo.Offers.FindIndex(o => o.Id == playerOffer.Id); + if (indexOfOfferInProfile == -1) { logger.Warning(localisationService.GetText("ragfair-unable_to_find_offer_to_remove", playerOffer.Id)); + return; } // Reduce player ragfair rep - profile.RagfairInfo.Rating -= databaseService.GetGlobals().Configuration.RagFair.RatingDecreaseCount; - profile.RagfairInfo.IsRatingGrowing = false; + offerCreatorProfile.RagfairInfo.Rating -= databaseService.GetGlobals().Configuration.RagFair.RatingDecreaseCount; + offerCreatorProfile.RagfairInfo.IsRatingGrowing = false; // Increment players 'notSellSum' value - profile.RagfairInfo.NotSellSum ??= 0; - profile.RagfairInfo.NotSellSum += playerOffer.SummaryCost; + offerCreatorProfile.RagfairInfo.NotSellSum ??= 0; + offerCreatorProfile.RagfairInfo.NotSellSum += playerOffer.SummaryCost; var firstOfferItem = playerOffer.Items[0]; if (firstOfferItem.Upd.StackObjectsCount > firstOfferItem.Upd.OriginalStackObjectsCount) @@ -221,6 +235,7 @@ public class RagfairOfferService( } playerOffer.Items[0].Upd.OriginalStackObjectsCount = null; + // Remove player offer from flea ragfairOfferHolder.RemoveOffer(playerOffer.Id, false); @@ -238,8 +253,8 @@ public class RagfairOfferService( } } - ragfairServerHelper.ReturnItems(profile.SessionId, unstackedItems); - profile.RagfairInfo.Offers.Splice(offerinProfileIndex, 1); + ragfairServerHelper.ReturnItems(offerCreatorProfile.SessionId, unstackedItems); + offerCreatorProfile.RagfairInfo.Offers.Splice(indexOfOfferInProfile, 1); } /// @@ -301,6 +316,10 @@ public class RagfairOfferService( return result; } + /// + /// Have enough offers expired their sell time beyond the `ExpiredOfferThreshold` config property + /// + /// True if enough offers have expired public bool EnoughExpiredOffersExistToProcess() { return ragfairOfferHolder.GetExpiredOfferCount() >= _ragfairConfig.Dynamic.ExpiredOfferThreshold;