Improved how ragfair offer creator status is checked - store creator type in offer

Converted `IsTraderOffer` into extension method
string to mongoid conversions
This commit is contained in:
Chomp
2025-07-21 13:36:51 +01:00
parent 5eaedccdfa
commit 3901a91f45
11 changed files with 93 additions and 98 deletions
@@ -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
);
}
@@ -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);
}
/// <summary>
/// Is the provided offerId and ownerId from a player made offer
/// </summary>
/// <param name="offerId">id of the offer</param>
/// <param name="offerOwnerId">Owner id</param>
/// <returns>true if offer was made by a player</returns>
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);
}
/// <summary>
/// Does Player have necessary trader loyalty to purchase flea offer
/// </summary>
@@ -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;
}
/// <summary>
/// Does this offer come from a trader
/// </summary>
/// <param name="offer">Offer to check</param>
/// <returns>True = from trader</returns>
public static bool IsTraderOffer(this RagfairOffer offer)
{
if (offer.CreatedBy is not null)
{
return offer.CreatedBy == OfferCreator.Trader;
}
return offer.User.MemberType == MemberCategory.Trader;
}
/// <summary>
/// Was this offer created by a human player
/// </summary>
/// <param name="offer"></param>
/// <returns></returns>
public static bool IsPlayerOffer(this RagfairOffer offer)
{
if (offer.CreatedBy is not null)
{
return offer.CreatedBy == OfferCreator.Player;
}
return false;
}
}
}
@@ -57,8 +57,8 @@ public class RagfairOfferGenerator(
/// <param name="barterScheme">Cost of item (currency or barter)</param>
/// <param name="loyalLevel">Loyalty level needed to buy item</param>
/// <param name="quantity">Amount of item being listed</param>
/// <param name="creator">Who created this offer</param>
/// <param name="sellInOnePiece">Flags sellInOnePiece to be true</param>
/// <param name="isPlayerOffer">Offer to create is for a player</param>
/// <returns>RagfairOffer</returns>
public RagfairOffer CreateAndAddFleaOffer(
MongoId userId,
@@ -67,8 +67,8 @@ public class RagfairOfferGenerator(
List<BarterScheme> 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<string, object>();
offer.ExtensionData.Add("isPlayerOffer", isPlayerOffer);
offer.CreatedBy = creator;
ragfairOfferService.AddOffer(offer);
@@ -109,8 +108,8 @@ public class RagfairOfferGenerator(
List<BarterScheme> 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);
}
/// <summary>
/// Check userId, if it's a player, return their pmc _id, otherwise return userId parameter
/// </summary>
/// <param name="userId"> Users ID to check </param>
/// <returns> Users ID </returns>
protected string GetTraderId(MongoId userId)
{
if (profileHelper.IsPlayer(userId))
{
return saveServer.GetProfile(userId).CharacterData.PmcData.Id;
}
return userId;
}
/// <summary>
/// Get a flea trading rating for the passed in user
/// </summary>
@@ -356,12 +341,13 @@ public class RagfairOfferGenerator(
/// <summary>
/// Get number of section until offer should expire
/// </summary>
/// <param name="creatorType"></param>
/// <param name="userID"> ID of the offer owner </param>
/// <param name="time"> Time the offer is posted in seconds </param>
/// <returns> Number of seconds until offer expires </returns>
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
@@ -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<string> GetLoyaltyLockedOffers(List<RagfairOffer> offers, PmcData pmcProfile)
{
var loyaltyLockedOffers = new HashSet<string>();
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;
}
/// <summary>
/// Does this offer come from a trader
/// </summary>
/// <param name="offer">Offer to check</param>
/// <returns>True = from trader</returns>
public bool OfferIsFromTrader(RagfairOffer offer)
{
return offer.User.MemberType == MemberCategory.Trader;
}
}
@@ -89,6 +89,12 @@ public record RagfairOffer
/// </summary>
[JsonPropertyName("quantity")]
public int Quantity { get; set; }
/// <summary>
/// SPT property - offer made by player
/// </summary>
[JsonIgnore]
public OfferCreator? CreatedBy { get; set; }
}
public record OfferRequirement
@@ -0,0 +1,8 @@
namespace SPTarkov.Server.Core.Models.Enums;
public enum OfferCreator
{
Player,
Trader,
FakePlayer,
}
@@ -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);
}
@@ -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)
@@ -63,7 +63,7 @@ public class RagfairOfferService(
/// </summary>
/// <param name="offerId"> Offer id to check for </param>
/// <returns> True when offer exists </returns>
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
/// </summary>
/// <param name="offerId"> Offer id to remove </param>
public void RemoveOfferById(string offerId)
public void RemoveOfferById(MongoId offerId)
{
ragfairOfferHolder.RemoveOffer(offerId);
}
@@ -82,7 +82,7 @@ public class RagfairOfferService(
/// </summary>
/// <param name="offerId"> Offer to adjust stack size of </param>
/// <param name="amount"> How much to deduct from offers stack size </param>
public void ReduceOfferQuantity(string offerId, int amount)
public void ReduceOfferQuantity(MongoId offerId, int amount)
{
var offer = ragfairOfferHolder.GetOfferById(offerId);
if (offer == null)
@@ -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(
/// </summary>
/// <param name="offerId">Offer id to remove</param>
/// <param name="checkTraderOffers">OPTIONAL - Should trader offers be checked for offer id</param>
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(
/// <param name="trader">Trader id to store offer against</param>
/// <param name="offerId">Offer to store against</param>
/// <returns>True - offer was added</returns>
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))