using SptCommon.Annotations; using Core.Models.Eft.Common; using Core.Models.Eft.Common.Tables; using Core.Models.Eft.ItemEvent; using Core.Models.Eft.Profile; using Core.Models.Eft.Ragfair; using Core.Models.Enums; using Core.Models.Spt.Config; using Core.Models.Utils; using Core.Utils; using SptCommon.Extensions; using Core.Models.Spt.Services; using Core.Services; namespace Core.Helpers; [Injectable] public class RagfairOfferHelper( ISptLogger _logger, TimeUtil _timeUtil, DatabaseService _databaseService, ProfileHelper _profileHelper) { /// /// Passthrough to ragfairOfferService.getOffers(), get flea offers a player should see /// /// Data from client /// ragfairHelper.filterCategories() /// Trader assorts /// Player profile /// Offers the player should see public List GetValidOffers( SearchRequestData searchRequest, List itemsToAdd, Dictionary traderAssorts, PmcData pmcData) { throw new NotImplementedException(); } /// /// Disable offer if item is flagged by tiered flea config /// /// Tiered flea settings from ragfair config /// Ragfair offer to check /// Dict of item types with player level to be viewable /// Level of player viewing offer protected void CheckAndLockOfferFromPlayerTieredFlea( TieredFlea tieredFlea, RagfairOffer offer, string[] tieredFleaLimitTypes, int playerLevel) { throw new NotImplementedException(); } /// /// Get matching offers that require the desired item and filter out offers from non traders if player is below ragfair unlock level /// /// Search request from client /// Player profile /// Matching RagfairOffer objects public List GetOffersThatRequireItem(SearchRequestData searchRequest, PmcData pmcData) { throw new NotImplementedException(); } /// /// Get offers from flea/traders specifically when building weapon preset /// /// Search request data /// string array of item tpls to search for /// All trader assorts player can access/buy /// Player profile /// RagfairOffer array public List GetOffersForBuild( SearchRequestData searchRequest, List itemsToAdd, Dictionary traderAssorts, PmcData pmcData) { throw new NotImplementedException(); } /// /// Get offers that have not exceeded buy limits /// /// offers to process /// Offers protected List GetOffersInsideBuyRestrictionLimits(List possibleOffers) { throw new NotImplementedException(); } /// /// Check if offer is from trader standing the player does not have /// /// Offer to check /// Player profile /// True if item is locked, false if item is purchaseable protected bool TraderOfferLockedBehindLoyaltyLevel(RagfairOffer offer, PmcData pmcProfile) { throw new NotImplementedException(); } /// /// Check if offer item is quest locked for current player by looking at sptQuestLocked property in traders barter_scheme /// /// Offer to check is quest locked /// all trader assorts for player /// true if quest locked public bool TraderOfferItemQuestLocked(RagfairOffer offer, Dictionary traderAssorts) { throw new NotImplementedException(); } /// /// Has trader offer ran out of stock to sell to player /// /// Offer to check stock of /// true if out of stock protected bool TraderOutOfStock(RagfairOffer offer) { throw new NotImplementedException(); } /// /// Check if trader offers' BuyRestrictionMax value has been reached /// /// Offer to check restriction properties of /// true if restriction reached, false if no restrictions/not reached protected bool TraderBuyRestrictionReached(RagfairOffer offer) { throw new NotImplementedException(); } protected List GetLoyaltyLockedOffers(List offers, PmcData pmcProfile) { throw new NotImplementedException(); } /** * Process all player-listed flea offers for a desired profile * @param sessionId Session id to process offers for * @returns true = complete */ public bool ProcessOffersOnProfile(string sessionId) { var timestamp = _timeUtil.GetTimeStamp(); var profileOffers = GetProfileOffers(sessionId); // No offers, don't do anything if (profileOffers?.Count == 0) { return true; } foreach (var offer in profileOffers) { if (offer.SellResults?.Count > 0 && timestamp >= offer.SellResults[0].SellTime) { // Checks first item, first is spliced out of array after being processed // Item sold var totalItemsCount = 1d; var boughtAmount = 1; if (!offer.SellInOnePiece.GetValueOrDefault(false)) { // offer.items.reduce((sum, item) => sum + item.upd?.StackObjectsCount ?? 0, 0); totalItemsCount = GetTotalStackCountSize([offer.Items]); boughtAmount = offer.SellResults[0].Amount.Value; } var ratingToAdd = (offer.SummaryCost / totalItemsCount) * boughtAmount; IncreaseProfileRagfairRating(_profileHelper.GetFullProfile(sessionId), ratingToAdd.Value); CompleteOffer(sessionId, offer, boughtAmount); offer.SellResults.Splice(0, 1); // Remove the sell result object now its been processed } } return true; } /** * Count up all rootitem StackObjectsCount properties of an array of items * @param itemsInInventoryToList items to sum up * @returns Total stack count */ public double GetTotalStackCountSize(List> itemsInInventoryToList) { var total = 0d; foreach (var itemAndChildren in itemsInInventoryToList) { // Only count the root items stack count in total total += itemAndChildren[0]?.Upd?.StackObjectsCount.GetValueOrDefault(1) ?? 1; } return total; } /** * Add amount to players ragfair rating * @param sessionId Profile to update * @param amountToIncrementBy Raw amount to add to players ragfair rating (excluding the reputation gain multiplier) */ public void IncreaseProfileRagfairRating(SptProfile profile, double? amountToIncrementBy) { var ragfairGlobalsConfig = _databaseService.GetGlobals().Configuration.RagFair; profile.CharacterData.PmcData.RagfairInfo.IsRatingGrowing = true; if (amountToIncrementBy is null) { _logger.Warning($"Unable to increment ragfair rating, value was not a number: { amountToIncrementBy}"); return; } profile.CharacterData.PmcData.RagfairInfo.Rating += (ragfairGlobalsConfig.RatingIncreaseCount / ragfairGlobalsConfig.RatingSumForIncrease) * amountToIncrementBy; } /** * Return all offers a player has listed on a desired profile * @param sessionId Session id * @returns List of ragfair offers */ protected List GetProfileOffers(string sessionId) { var profile = _profileHelper.GetPmcProfile(sessionId); if (profile.RagfairInfo?.Offers is null) { return []; } return profile.RagfairInfo.Offers; } /** * Delete an offer from a desired profile and from ragfair offers * @param sessionID Session id of profile to delete offer from * @param offerId Id of offer to delete */ protected void DeleteOfferById(string sessionID, string offerId) { throw new NotImplementedException(); } /** * Complete the selling of players' offer * @param sessionID Session id * @param offer Sold offer details * @param boughtAmount Amount item was purchased for * @returns ItemEventRouterResponse */ public ItemEventRouterResponse CompleteOffer(string sessionID, RagfairOffer offer, int boughtAmount) { throw new NotImplementedException(); } /** * Get a localised message for when players offer has sold on flea * @param itemTpl Item sold * @param boughtAmount How many were purchased * @returns Localised message text */ protected string GetLocalisedOfferSoldMessage(string itemTpl, int boughtAmount) { throw new NotImplementedException(); } /** * Check an offer passes the various search criteria the player requested * @param searchRequest Client search request * @param offer Offer to check * @param pmcData Player profile * @returns True if offer passes criteria */ protected bool PassesSearchFilterCriteria(SearchRequestData searchRequest, RagfairOffer offer, PmcData pmcData) { throw new NotImplementedException(); } /** * Check that the passed in offer item is functional * @param offerRootItem The root item of the offer * @param offer Flea offer to check * @returns True if the given item is functional */ public bool IsItemFunctional(Item offerRootItem, RagfairOffer offer) { throw new NotImplementedException(); } /// /// Should a ragfair offer be visible to the player /// /// Search request /// ? /// Trader assort items - used for filtering out locked trader items /// The flea offer /// Player profile /// Optional parameter /// True = should be shown to player public bool DisplayableOffer( SearchRequestData searchRequest, List itemsToAdd, Dictionary traderAssorts, RagfairOffer offer, PmcData pmcProfile, bool? playerIsFleaBanned = null ) { throw new NotImplementedException(); } public bool DisplayableOfferThatNeedsItem(SearchRequestData searchRequest, RagfairOffer offer) { throw new NotImplementedException(); } /// /// Does the passed in item have a condition property /// /// Item to check /// True if has condition protected bool ConditionItem(Item item) { throw new NotImplementedException(); } /// /// Is items quality value within desired range /// /// Item to check quality of /// Desired minimum quality /// Desired maximum quality /// True if in range protected bool ItemQualityInRange(Item item, int min, int max) { throw new NotImplementedException(); } /// /// Does this offer come from a trader /// /// Offer to check /// True = from trader public bool OfferIsFromTrader(RagfairOffer offer) { return offer.User.MemberType == MemberCategory.TRADER; } }