diff --git a/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs b/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs index 743323e2..6576ae01 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs @@ -127,7 +127,7 @@ public class RagfairController( } // Update trader offers' values, Lock quest-linked offers + adjust offer buy limits - foreach (var traderOffer in result.Offers.Where(ragfairOfferHelper.OfferIsFromTrader)) + foreach (var traderOffer in result.Offers.Where(x => x.IsTraderOffer())) { // For the items, check the barter schemes. The method getDisplayableAssorts sets a flag sptQuestLocked // to true if the quest is not completed yet @@ -427,7 +427,7 @@ public class RagfairController( continue; } - if (ignoreTraderOffers && ragfairOfferHelper.OfferIsFromTrader(offer)) + if (ignoreTraderOffers && offer.IsTraderOffer()) { continue; } @@ -1020,8 +1020,8 @@ public class RagfairController( formattedRequirements.ToList(), loyalLevel, (int?)items.FirstOrDefault()?.Upd?.StackObjectsCount ?? 1, - sellInOnePiece, - true + OfferCreator.Player, + sellInOnePiece ); } diff --git a/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs b/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs index 37857228..ba653692 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs @@ -123,7 +123,7 @@ public class TradeController( ); } - if (ragfairOfferHelper.OfferIsFromTrader(fleaOffer)) + if (fleaOffer.IsTraderOffer()) { BuyTraderItemFromRagfair(sessionID, pmcData, fleaOffer, offer, output); } @@ -244,7 +244,7 @@ public class TradeController( var offerOwnerId = fleaOffer.User.Id; var offerBuyCount = requestOffer.Count; - if (IsPlayerOffer(fleaOffer.Id, fleaOffer.User?.Id)) + if (fleaOffer.IsPlayerOffer()) { // Complete selling the offer now it has been purchased ragfairOfferHelper.CompleteOffer(offerOwnerId, fleaOffer, offerBuyCount ?? 0); @@ -256,31 +256,6 @@ public class TradeController( ragfairServer.ReduceOfferQuantity(fleaOffer.Id, requestOffer.Count ?? 0); } - /// - /// Is the provided offerId and ownerId from a player made offer - /// - /// id of the offer - /// Owner id - /// true if offer was made by a player - protected bool IsPlayerOffer(string offerId, MongoId? offerOwnerId) - { - // No ownerId, not player offer - if (offerOwnerId is null) - { - return false; - } - - var offerCreatorProfile = profileHelper.GetPmcProfile(offerOwnerId.Value); - if (offerCreatorProfile is null || offerCreatorProfile.RagfairInfo.Offers?.Count == 0) - // No profile or no offers - { - return false; - } - - // Does offer id exist in profile - return offerCreatorProfile.RagfairInfo.Offers.Any(offer => offer.Id == offerId); - } - /// /// Does Player have necessary trader loyalty to purchase flea offer /// diff --git a/Libraries/SPTarkov.Server.Core/Extensions/RagfairOfferExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/RagfairOfferExtensions.cs index 4fa100b0..4384d421 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/RagfairOfferExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/RagfairOfferExtensions.cs @@ -1,4 +1,5 @@ using SPTarkov.Server.Core.Models.Eft.Ragfair; +using SPTarkov.Server.Core.Models.Enums; namespace SPTarkov.Server.Core.Extensions { @@ -14,5 +15,35 @@ namespace SPTarkov.Server.Core.Extensions { return offer.EndTime < time || (offer.Quantity) < 1; } + + /// + /// Does this offer come from a trader + /// + /// Offer to check + /// True = from trader + public static bool IsTraderOffer(this RagfairOffer offer) + { + if (offer.CreatedBy is not null) + { + return offer.CreatedBy == OfferCreator.Trader; + } + + return offer.User.MemberType == MemberCategory.Trader; + } + + /// + /// Was this offer created by a human player + /// + /// + /// + public static bool IsPlayerOffer(this RagfairOffer offer) + { + if (offer.CreatedBy is not null) + { + return offer.CreatedBy == OfferCreator.Player; + } + + return false; + } } } diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs index b76a2334..98517995 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs @@ -57,8 +57,8 @@ public class RagfairOfferGenerator( /// Cost of item (currency or barter) /// Loyalty level needed to buy item /// Amount of item being listed + /// Who created this offer /// Flags sellInOnePiece to be true - /// Offer to create is for a player /// RagfairOffer public RagfairOffer CreateAndAddFleaOffer( MongoId userId, @@ -67,8 +67,8 @@ public class RagfairOfferGenerator( List barterScheme, int loyalLevel, int quantity, - bool sellInOnePiece = false, - bool isPlayerOffer = false + OfferCreator creator, + bool sellInOnePiece = false ) { var offer = CreateOffer( @@ -78,12 +78,11 @@ public class RagfairOfferGenerator( barterScheme, loyalLevel, quantity, - sellInOnePiece, - isPlayerOffer + creator, + sellInOnePiece ); - offer.ExtensionData ??= new Dictionary(); - offer.ExtensionData.Add("isPlayerOffer", isPlayerOffer); + offer.CreatedBy = creator; ragfairOfferService.AddOffer(offer); @@ -109,8 +108,8 @@ public class RagfairOfferGenerator( List barterScheme, int loyalLevel, int quantity, - bool isPackOffer = false, - bool isPlayerOffer = false + OfferCreator creator, + bool isPackOffer = false ) { var offerRequirements = barterScheme @@ -160,9 +159,10 @@ public class RagfairOfferGenerator( { Id = new MongoId(), InternalId = offerCounter, - User = isPlayerOffer - ? CreatePlayerUserDataForFleaOffer(userId) - : CreateUserDataForFleaOffer(userId, ragfairServerHelper.IsTrader(userId)), + User = + creator == OfferCreator.Player + ? CreatePlayerUserDataForFleaOffer(userId) + : CreateUserDataForFleaOffer(userId, ragfairServerHelper.IsTrader(userId)), Root = rootItem.Id, Items = itemsClone, ItemsCost = Math.Round(handbookHelper.GetTemplatePrice(rootItem.Template)), // Handbook price @@ -170,7 +170,7 @@ public class RagfairOfferGenerator( RequirementsCost = Math.Round(singleItemListingPrice), SummaryCost = roubleListingPrice, StartTime = time, - EndTime = GetOfferEndTime(userId, time), + EndTime = GetOfferEndTime(creator, userId, time), LoyaltyLevel = loyalLevel, SellInOnePiece = isPackOffer, Locked = false, @@ -286,21 +286,6 @@ public class RagfairOfferGenerator( return handbookHelper.InRUB(currencyCount, currencyType); } - /// - /// Check userId, if it's a player, return their pmc _id, otherwise return userId parameter - /// - /// Users ID to check - /// Users ID - protected string GetTraderId(MongoId userId) - { - if (profileHelper.IsPlayer(userId)) - { - return saveServer.GetProfile(userId).CharacterData.PmcData.Id; - } - - return userId; - } - /// /// Get a flea trading rating for the passed in user /// @@ -356,12 +341,13 @@ public class RagfairOfferGenerator( /// /// Get number of section until offer should expire /// + /// /// ID of the offer owner /// Time the offer is posted in seconds /// Number of seconds until offer expires - protected long GetOfferEndTime(MongoId userID, long time) + protected long GetOfferEndTime(OfferCreator creatorType, MongoId userID, long time) { - if (profileHelper.IsPlayer(userID)) + if (creatorType == OfferCreator.Player) { // Player offer = current time + offerDurationTimeInHour; var offerDurationTimeHours = databaseService @@ -373,7 +359,7 @@ public class RagfairOfferGenerator( ); } - if (ragfairServerHelper.IsTrader(userID)) + if (creatorType == OfferCreator.Trader) // Trader offer { return (long)databaseService.GetTrader(userID).Base.NextResupply; @@ -384,7 +370,7 @@ public class RagfairOfferGenerator( ragfairConfig.Dynamic.EndTimeSeconds.Max ); - // Generated fake-player offer + // Fake-player offer return (long)Math.Round(time + randomSpread); } @@ -628,6 +614,7 @@ public class RagfairOfferGenerator( barterScheme, 1, desiredStackSize, + OfferCreator.FakePlayer, isPackOffer // sellAsOnePiece - pack offer ); } @@ -751,7 +738,8 @@ public class RagfairOfferGenerator( items, barterSchemeItems, loyalLevel, - (int?)item.Upd.StackObjectsCount ?? 1 + (int?)item.Upd.StackObjectsCount ?? 1, + OfferCreator.Trader ); // Refresh complete, reset flag to false diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs index 525f6548..6ce1798a 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs @@ -87,7 +87,7 @@ public class RagfairOfferHelper( } // Not trader offer + tiered flea enabled - if (tieredFlea.Enabled && !OfferIsFromTrader(offer)) + if (tieredFlea.Enabled && !offer.IsTraderOffer()) { CheckAndLockOfferFromPlayerTieredFlea( tieredFlea, @@ -194,7 +194,7 @@ public class RagfairOfferHelper( .Where(offer => PassesSearchFilterCriteria(searchRequest, offer, pmcData)) ) { - if (tieredFlea.Enabled && !OfferIsFromTrader(offer)) + if (tieredFlea.Enabled && !offer.IsTraderOffer()) { CheckAndLockOfferFromPlayerTieredFlea( tieredFlea, @@ -267,7 +267,7 @@ public class RagfairOfferHelper( continue; } - if (OfferIsFromTrader(offer)) + if (offer.IsTraderOffer()) { if (TraderBuyRestrictionReached(offer)) { @@ -291,7 +291,7 @@ public class RagfairOfferHelper( } // Tiered flea and not trader offer - if (tieredFlea.Enabled && !OfferIsFromTrader(offer)) + if (tieredFlea.Enabled && !offer.IsTraderOffer()) { CheckAndLockOfferFromPlayerTieredFlea( tieredFlea, @@ -374,7 +374,7 @@ public class RagfairOfferHelper( // Currency offer is sold for var moneyTypeTpl = offer.Requirements.FirstOrDefault().TemplateId; - var isTraderOffer = databaseService.GetTraders().ContainsKey(offer.User.Id); + var isTraderOffer = offer.IsTraderOffer(); if (!isTraderOffer && playerIsFleaBanned) { @@ -463,7 +463,7 @@ public class RagfairOfferHelper( { if ( offer.BuyRestrictionMax is null - && OfferIsFromTrader(offer) + && offer.IsTraderOffer() && offer.BuyRestrictionCurrent >= offer.BuyRestrictionMax ) { @@ -473,7 +473,7 @@ public class RagfairOfferHelper( } } - // Doesnt have buy limits, retrun offer + // Doesn't have buy limits, return offer return true; }) .ToList(); @@ -615,7 +615,7 @@ public class RagfairOfferHelper( protected HashSet GetLoyaltyLockedOffers(List offers, PmcData pmcProfile) { var loyaltyLockedOffers = new HashSet(); - foreach (var offer in offers.Where(OfferIsFromTrader)) + foreach (var offer in offers.Where(x => x.IsTraderOffer())) { if ( pmcProfile.TradersInfo.TryGetValue(offer.User.Id, out var traderDetails) @@ -945,7 +945,7 @@ public class RagfairOfferHelper( return false; } - var isTraderOffer = OfferIsFromTrader(offer); + var isTraderOffer = offer.IsTraderOffer(); if (searchRequest.OfferOwnerType == OfferOwnerType.TRADEROWNERTYPE && !isTraderOffer) // don't include player offers { @@ -1128,14 +1128,4 @@ public class RagfairOfferHelper( return true; } - - /// - /// Does this offer come from a trader - /// - /// Offer to check - /// True = from trader - public bool OfferIsFromTrader(RagfairOffer offer) - { - return offer.User.MemberType == MemberCategory.Trader; - } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Ragfair/RagfairOffer.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Ragfair/RagfairOffer.cs index 2e674366..18d12bd3 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Ragfair/RagfairOffer.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Ragfair/RagfairOffer.cs @@ -89,6 +89,12 @@ public record RagfairOffer /// [JsonPropertyName("quantity")] public int Quantity { get; set; } + + /// + /// SPT property - offer made by player + /// + [JsonIgnore] + public OfferCreator? CreatedBy { get; set; } } public record OfferRequirement diff --git a/Libraries/SPTarkov.Server.Core/Models/Enums/OfferCreator.cs b/Libraries/SPTarkov.Server.Core/Models/Enums/OfferCreator.cs new file mode 100644 index 00000000..58c05643 --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Models/Enums/OfferCreator.cs @@ -0,0 +1,8 @@ +namespace SPTarkov.Server.Core.Models.Enums; + +public enum OfferCreator +{ + Player, + Trader, + FakePlayer, +} diff --git a/Libraries/SPTarkov.Server.Core/Servers/RagfairServer.cs b/Libraries/SPTarkov.Server.Core/Servers/RagfairServer.cs index e1957bd0..e061a913 100644 --- a/Libraries/SPTarkov.Server.Core/Servers/RagfairServer.cs +++ b/Libraries/SPTarkov.Server.Core/Servers/RagfairServer.cs @@ -129,12 +129,12 @@ public class RagfairServer( return _ragfairOfferService.GetOffers(); } - public void ReduceOfferQuantity(string offerId, int amount) + public void ReduceOfferQuantity(MongoId offerId, int amount) { _ragfairOfferService.ReduceOfferQuantity(offerId, amount); } - public bool DoesOfferExist(string offerId) + public bool DoesOfferExist(MongoId offerId) { return _ragfairOfferService.DoesOfferExist(offerId); } diff --git a/Libraries/SPTarkov.Server.Core/Services/RagfairCategoriesService.cs b/Libraries/SPTarkov.Server.Core/Services/RagfairCategoriesService.cs index ac217c8e..9bef33b6 100644 --- a/Libraries/SPTarkov.Server.Core/Services/RagfairCategoriesService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/RagfairCategoriesService.cs @@ -1,8 +1,8 @@ using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Helpers; using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Ragfair; -using SPTarkov.Server.Core.Models.Enums; using SPTarkov.Server.Core.Models.Utils; namespace SPTarkov.Server.Core.Services; @@ -30,7 +30,7 @@ public class RagfairCategoriesService( return offers .Where(offer => { - var isTraderOffer = offer.User.MemberType == MemberCategory.Trader; + var isTraderOffer = offer.IsTraderOffer(); // Not level 15 and offer is from player, skip if (!fleaUnlocked && !isTraderOffer) diff --git a/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs b/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs index a72a0733..cdab915c 100644 --- a/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs @@ -63,7 +63,7 @@ public class RagfairOfferService( /// /// Offer id to check for /// True when offer exists - public bool DoesOfferExist(string offerId) + public bool DoesOfferExist(MongoId offerId) { return ragfairOfferHolder.GetOfferById(offerId) != null; } @@ -72,7 +72,7 @@ public class RagfairOfferService( /// Remove an offer from ragfair by offer id /// /// Offer id to remove - public void RemoveOfferById(string offerId) + public void RemoveOfferById(MongoId offerId) { ragfairOfferHolder.RemoveOffer(offerId); } @@ -82,7 +82,7 @@ public class RagfairOfferService( /// /// Offer to adjust stack size of /// How much to deduct from offers stack size - public void ReduceOfferQuantity(string offerId, int amount) + public void ReduceOfferQuantity(MongoId offerId, int amount) { var offer = ragfairOfferHolder.GetOfferById(offerId); if (offer == null) diff --git a/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs b/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs index 158c15f1..643b032d 100644 --- a/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs +++ b/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs @@ -142,14 +142,11 @@ public class RagfairOfferHolder( var itemTpl = offer.Items?.FirstOrDefault()?.Template ?? new MongoId(null); var sellerId = offer.User.Id; - var sellerIsTrader = _ragfairServerHelper.IsTrader(sellerId); + var sellerIsTrader = offer.IsTraderOffer(); var itemSoldTemplate = _itemHelper.GetItem(itemTpl); if ( - !itemTpl.IsEmpty() - && !( - sellerIsTrader - || (bool)offer.ExtensionData.GetValueOrDefault("isPlayerOffer", false) - ) + !itemTpl.IsEmpty() // Has tpl + && !(sellerIsTrader || offer.IsPlayerOffer()) && _offersByTemplate.TryGetValue(itemTpl, out var offers) && offers?.Count >= _ragfairServerHelper.GetOfferCountByBaseType(itemSoldTemplate.Value.Parent) @@ -179,7 +176,7 @@ public class RagfairOfferHolder( /// /// Offer id to remove /// OPTIONAL - Should trader offers be checked for offer id - public void RemoveOffer(string offerId, bool checkTraderOffers = true) + public void RemoveOffer(MongoId offerId, bool checkTraderOffers = true) { if (!_offersById.TryGetValue(offerId, out var offer)) { @@ -277,7 +274,7 @@ public class RagfairOfferHolder( /// Trader id to store offer against /// Offer to store against /// True - offer was added - protected bool AddOfferByTrader(string trader, string offerId) + protected bool AddOfferByTrader(MongoId trader, MongoId offerId) { // Look for hashset for trader first if (_offersByTrader.TryGetValue(trader, out var traderOfferIds))