Various micro-optimisations
This commit is contained in:
@@ -292,7 +292,7 @@ public class BotController(
|
||||
);
|
||||
}
|
||||
|
||||
var maxThreads = botGenerationDetails.BotCountToGenerate.Value;
|
||||
var maxThreads = botGenerationDetails.BotCountToGenerate;
|
||||
|
||||
#if DEBUG
|
||||
// Make debugging bot gen easier
|
||||
|
||||
@@ -250,9 +250,12 @@ public class InventoryController(
|
||||
}
|
||||
case "ExamineAllItems":
|
||||
{
|
||||
var itemsToInspect = itemHelper.GetItems().Where(x => x.Type != "Node");
|
||||
FlagItemsAsInspectedAndRewardXp(itemsToInspect.Select(x => x.Id), fullProfile);
|
||||
logger.Success($"Flagged {itemsToInspect.Count()} items as examined");
|
||||
var itemIds = databaseService
|
||||
.GetItems()
|
||||
.Where(x => x.Value.Type != "Node")
|
||||
.Select(x => x.Key);
|
||||
FlagItemsAsInspectedAndRewardXp(itemIds, fullProfile);
|
||||
logger.Success($"Flagged {itemIds.Count()} items as examined");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1020,7 +1020,8 @@ public class RagfairController(
|
||||
formattedRequirements.ToList(),
|
||||
loyalLevel,
|
||||
(int?)items.FirstOrDefault()?.Upd?.StackObjectsCount ?? 1,
|
||||
sellInOnePiece
|
||||
sellInOnePiece,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -207,13 +207,7 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
|
||||
foreach (var childItem in items)
|
||||
{
|
||||
if (
|
||||
string.Equals(
|
||||
childItem.ParentId,
|
||||
baseItemId,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
)
|
||||
if (childItem.ParentId == baseItemId.ToString())
|
||||
{
|
||||
list.AddRange(FindAndReturnChildrenByItems(items, childItem.Id));
|
||||
}
|
||||
@@ -292,8 +286,9 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
)
|
||||
{
|
||||
// Use dictionary to make key lookup faster, convert to list before being returned
|
||||
var itemList = items.ToList();
|
||||
OrderedDictionary<MongoId, Item> result = [];
|
||||
foreach (var childItem in items)
|
||||
foreach (var childItem in itemList)
|
||||
{
|
||||
// Include itself
|
||||
if (childItem.Id == baseItemId)
|
||||
@@ -403,9 +398,7 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
item.Id = newId;
|
||||
|
||||
// Find all children of item and update their parent ids to match
|
||||
var childItems = items.Where(x =>
|
||||
string.Equals(x.ParentId, originalId, StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
var childItems = items.Where(item => item.ParentId == originalId.ToString());
|
||||
foreach (var childItem in childItems)
|
||||
{
|
||||
childItem.ParentId = newId;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
/// <returns>True - offer is stale</returns>
|
||||
public static bool IsStale(this RagfairOffer offer, long time)
|
||||
{
|
||||
return offer.EndTime < time || (offer.Quantity ?? 0) < 1;
|
||||
return offer.EndTime < time || (offer.Quantity) < 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
/// <param name="armorItem">Item to look up default plate</param>
|
||||
/// <param name="modSlot">front/back</param>
|
||||
/// <returns>Tpl of plate</returns>
|
||||
public static string? GetDefaultPlateTpl(this TemplateItem armorItem, string modSlot)
|
||||
public static MongoId? GetDefaultPlateTpl(this TemplateItem armorItem, string modSlot)
|
||||
{
|
||||
var relatedItemDbModSlot = armorItem.Properties.Slots?.FirstOrDefault(slot =>
|
||||
string.Equals(slot.Name, modSlot, StringComparison.OrdinalIgnoreCase)
|
||||
|
||||
@@ -197,7 +197,8 @@ public class BotEquipmentModGenerator(
|
||||
);
|
||||
switch (plateSlotFilteringOutcome.Result)
|
||||
{
|
||||
case Result.UNKNOWN_FAILURE or Result.NO_DEFAULT_FILTER:
|
||||
case Result.UNKNOWN_FAILURE
|
||||
or Result.NO_DEFAULT_FILTER:
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
@@ -421,9 +422,9 @@ public class BotEquipmentModGenerator(
|
||||
var defaultPlate = armorItem.GetDefaultPlateTpl(modSlot);
|
||||
if (defaultPlate is not null)
|
||||
{
|
||||
// Return Default Plates cause couldn't get lowest level available from original selection
|
||||
// Return Default Plates cause couldn't get the lowest level available from original selection
|
||||
result.Result = Result.SUCCESS;
|
||||
result.PlateModTemplates = [defaultPlate];
|
||||
result.PlateModTemplates = [defaultPlate.Value];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -37,22 +37,27 @@ public class FenceBaseAssortGenerator(
|
||||
var blockedSeasonalItems = seasonalEventService.GetInactiveSeasonalEventItems();
|
||||
var baseFenceAssort = databaseService.GetTrader(Traders.FENCE).Assort;
|
||||
|
||||
foreach (var rootItemDb in itemHelper.GetItems().Where(IsValidFenceItem))
|
||||
foreach (var (itemId, rootItemDb) in databaseService.GetItems())
|
||||
{
|
||||
if (!string.Equals(rootItemDb.Type, "Item", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip blacklisted items
|
||||
if (itemFilterService.IsItemBlacklisted(rootItemDb.Id))
|
||||
if (itemFilterService.IsItemBlacklisted(itemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip reward item blacklist
|
||||
if (itemFilterService.IsItemRewardBlacklisted(rootItemDb.Id))
|
||||
if (itemFilterService.IsItemRewardBlacklisted(itemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Invalid
|
||||
if (!itemHelper.IsValidItem(rootItemDb.Id))
|
||||
if (!itemHelper.IsValidItem(itemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -61,8 +66,8 @@ public class FenceBaseAssortGenerator(
|
||||
if (traderConfig.Fence.Blacklist.Count > 0)
|
||||
{
|
||||
if (
|
||||
traderConfig.Fence.Blacklist.Contains(rootItemDb.Id)
|
||||
|| itemHelper.IsOfBaseclasses(rootItemDb.Id, traderConfig.Fence.Blacklist)
|
||||
traderConfig.Fence.Blacklist.Contains(itemId)
|
||||
|| itemHelper.IsOfBaseclasses(itemId, traderConfig.Fence.Blacklist)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
@@ -71,7 +76,7 @@ public class FenceBaseAssortGenerator(
|
||||
|
||||
// Only allow rigs with no slots (carrier rigs)
|
||||
if (
|
||||
itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.VEST)
|
||||
itemHelper.IsOfBaseclass(itemId, BaseClasses.VEST)
|
||||
&& (rootItemDb.Properties?.Slots?.Count ?? 0) > 0
|
||||
)
|
||||
{
|
||||
@@ -79,10 +84,7 @@ public class FenceBaseAssortGenerator(
|
||||
}
|
||||
|
||||
// Skip seasonal event items when not in seasonal event
|
||||
if (
|
||||
traderConfig.Fence.BlacklistSeasonalItems
|
||||
&& blockedSeasonalItems.Contains(rootItemDb.Id)
|
||||
)
|
||||
if (traderConfig.Fence.BlacklistSeasonalItems && blockedSeasonalItems.Contains(itemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -93,7 +95,7 @@ public class FenceBaseAssortGenerator(
|
||||
new()
|
||||
{
|
||||
Id = new MongoId(),
|
||||
Template = rootItemDb.Id,
|
||||
Template = itemId,
|
||||
ParentId = "hideout",
|
||||
SlotId = "hideout",
|
||||
Upd = new Upd { StackObjectsCount = 9999999 },
|
||||
@@ -101,7 +103,7 @@ public class FenceBaseAssortGenerator(
|
||||
};
|
||||
|
||||
// Ensure ammo is not above penetration limit value
|
||||
if (itemHelper.IsOfBaseclasses(rootItemDb.Id, [BaseClasses.AMMO_BOX, BaseClasses.AMMO]))
|
||||
if (itemHelper.IsOfBaseclasses(itemId, [BaseClasses.AMMO_BOX, BaseClasses.AMMO]))
|
||||
{
|
||||
if (IsAmmoAbovePenetrationLimit(rootItemDb))
|
||||
{
|
||||
@@ -109,7 +111,7 @@ public class FenceBaseAssortGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
if (itemHelper.IsOfBaseclass(rootItemDb.Id, BaseClasses.AMMO_BOX))
|
||||
if (itemHelper.IsOfBaseclass(itemId, BaseClasses.AMMO_BOX))
|
||||
// Only add cartridges to box if box has no children
|
||||
{
|
||||
if (itemWithChildrenToAdd.Count == 1)
|
||||
@@ -130,7 +132,7 @@ public class FenceBaseAssortGenerator(
|
||||
var barterSchemeToAdd = new BarterScheme
|
||||
{
|
||||
Count = Math.Round(
|
||||
(double)fenceService.GetItemPrice(rootItemDb.Id, itemWithChildrenToAdd)
|
||||
(double)fenceService.GetItemPrice(itemId, itemWithChildrenToAdd)
|
||||
),
|
||||
Template = Money.ROUBLES,
|
||||
};
|
||||
@@ -185,8 +187,8 @@ public class FenceBaseAssortGenerator(
|
||||
var itemQualityModifier = itemHelper.GetItemQualityModifierForItems(itemAndChildren);
|
||||
|
||||
// Multiply weapon+mods rouble price by quality modifier
|
||||
baseFenceAssort.BarterScheme[itemAndChildren[0].Id] = new List<List<BarterScheme>>
|
||||
{
|
||||
baseFenceAssort.BarterScheme[itemAndChildren[0].Id] =
|
||||
[
|
||||
new()
|
||||
{
|
||||
new BarterScheme
|
||||
@@ -195,7 +197,7 @@ public class FenceBaseAssortGenerator(
|
||||
Count = Math.Round(price * itemQualityModifier),
|
||||
},
|
||||
},
|
||||
};
|
||||
];
|
||||
|
||||
baseFenceAssort.LoyalLevelItems[itemAndChildren[0].Id] = 1;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class LootGenerator(
|
||||
if (sealedWeaponCrateCount > 0)
|
||||
{
|
||||
// Get list of all sealed containers from db - they're all the same, just for flavor
|
||||
var itemsDb = itemHelper.GetItems();
|
||||
var itemsDb = databaseService.GetItems().Values;
|
||||
var sealedWeaponContainerPool = itemsDb.Where(item =>
|
||||
item.Name.Contains("event_container_airdrop")
|
||||
);
|
||||
|
||||
@@ -55,7 +55,7 @@ public class RagfairAssortGenerator(
|
||||
|
||||
// Get cloned items from db
|
||||
var dbItemsClone = itemHelper
|
||||
.GetItems()
|
||||
.GetItemsClone()
|
||||
.Where(item => !string.Equals(item.Type, "Node", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// Store processed preset tpls so we don't add them when processing non-preset items
|
||||
@@ -136,7 +136,7 @@ public class RagfairAssortGenerator(
|
||||
/// <returns> Hydrated Item object </returns>
|
||||
protected Item CreateRagfairAssortRootItem(MongoId tplId, MongoId? id = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id))
|
||||
if (id == null || id.Value.IsEmpty())
|
||||
{
|
||||
id = new MongoId();
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public class RagfairOfferGenerator(
|
||||
/// <param name="loyalLevel">Loyalty level needed to buy item</param>
|
||||
/// <param name="quantity">Amount of item being listed</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,
|
||||
@@ -66,7 +67,8 @@ public class RagfairOfferGenerator(
|
||||
List<BarterScheme> barterScheme,
|
||||
int loyalLevel,
|
||||
int quantity,
|
||||
bool sellInOnePiece = false
|
||||
bool sellInOnePiece = false,
|
||||
bool isPlayerOffer = false
|
||||
)
|
||||
{
|
||||
var offer = CreateOffer(
|
||||
@@ -76,8 +78,13 @@ public class RagfairOfferGenerator(
|
||||
barterScheme,
|
||||
loyalLevel,
|
||||
quantity,
|
||||
sellInOnePiece
|
||||
sellInOnePiece,
|
||||
isPlayerOffer
|
||||
);
|
||||
|
||||
offer.ExtensionData ??= new Dictionary<string, object>();
|
||||
offer.ExtensionData.Add("isPlayerOffer", isPlayerOffer);
|
||||
|
||||
ragfairOfferService.AddOffer(offer);
|
||||
|
||||
return offer;
|
||||
@@ -93,6 +100,7 @@ public class RagfairOfferGenerator(
|
||||
/// <param name="loyalLevel">Loyalty level needed to buy item</param>
|
||||
/// <param name="quantity">Amount of item being listed</param>
|
||||
/// <param name="isPackOffer">Is offer being created flagged as a pack</param>
|
||||
/// <param name="isPlayerOffer">Offer is from a player</param>
|
||||
/// <returns>RagfairOffer</returns>
|
||||
protected RagfairOffer CreateOffer(
|
||||
MongoId userId,
|
||||
@@ -101,7 +109,8 @@ public class RagfairOfferGenerator(
|
||||
List<BarterScheme> barterScheme,
|
||||
int loyalLevel,
|
||||
int quantity,
|
||||
bool isPackOffer = false
|
||||
bool isPackOffer = false,
|
||||
bool isPlayerOffer = false
|
||||
)
|
||||
{
|
||||
var offerRequirements = barterScheme
|
||||
@@ -132,8 +141,8 @@ public class RagfairOfferGenerator(
|
||||
// Hydrate ammo boxes with cartridges + ensure only 1 item is present (ammo box)
|
||||
// On offer refresh don't re-add cartridges to ammo box that already has cartridges
|
||||
if (
|
||||
itemHelper.IsOfBaseclass(itemsClone[0].Template, BaseClasses.AMMO_BOX)
|
||||
&& itemsClone.Count == 1
|
||||
itemsClone.Count == 1
|
||||
&& itemHelper.IsOfBaseclass(itemsClone[0].Template, BaseClasses.AMMO_BOX)
|
||||
)
|
||||
{
|
||||
itemHelper.AddCartridgesToAmmoBox(
|
||||
@@ -151,7 +160,9 @@ public class RagfairOfferGenerator(
|
||||
{
|
||||
Id = new MongoId(),
|
||||
InternalId = offerCounter,
|
||||
User = CreateUserDataForFleaOffer(userId, ragfairServerHelper.IsTrader(userId)),
|
||||
User = isPlayerOffer
|
||||
? CreatePlayerUserDataForFleaOffer(userId)
|
||||
: CreateUserDataForFleaOffer(userId, ragfairServerHelper.IsTrader(userId)),
|
||||
Root = rootItem.Id,
|
||||
Items = itemsClone,
|
||||
ItemsCost = Math.Round(handbookHelper.GetTemplatePrice(rootItem.Template)), // Handbook price
|
||||
@@ -185,23 +196,6 @@ public class RagfairOfferGenerator(
|
||||
return new RagfairOfferUser { Id = userId, MemberType = MemberCategory.Trader };
|
||||
}
|
||||
|
||||
var isPlayerOffer = profileHelper.IsPlayer(userId);
|
||||
if (isPlayerOffer)
|
||||
{
|
||||
var playerProfile = profileHelper.GetPmcProfile(userId);
|
||||
return new RagfairOfferUser
|
||||
{
|
||||
Id = playerProfile.Id.Value,
|
||||
MemberType = playerProfile.Info.MemberCategory,
|
||||
SelectedMemberCategory = playerProfile.Info.SelectedMemberCategory,
|
||||
Nickname = playerProfile.Info.Nickname,
|
||||
Rating = playerProfile.RagfairInfo.Rating ?? 0,
|
||||
IsRatingGrowing = playerProfile.RagfairInfo.IsRatingGrowing,
|
||||
Avatar = null,
|
||||
Aid = playerProfile.Aid,
|
||||
};
|
||||
}
|
||||
|
||||
// 'Fake' pmc offer
|
||||
return new RagfairOfferUser
|
||||
{
|
||||
@@ -218,6 +212,27 @@ public class RagfairOfferGenerator(
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the user object stored inside each flea offer object
|
||||
/// </summary>
|
||||
/// <param name="userId">Player id</param>
|
||||
/// <returns>OfferUser object</returns>
|
||||
protected RagfairOfferUser CreatePlayerUserDataForFleaOffer(MongoId userId)
|
||||
{
|
||||
var playerProfile = profileHelper.GetPmcProfile(userId);
|
||||
return new RagfairOfferUser
|
||||
{
|
||||
Id = playerProfile.Id.Value,
|
||||
MemberType = playerProfile.Info.MemberCategory,
|
||||
SelectedMemberCategory = playerProfile.Info.SelectedMemberCategory,
|
||||
Nickname = playerProfile.Info.Nickname,
|
||||
Rating = playerProfile.RagfairInfo.Rating ?? 0,
|
||||
IsRatingGrowing = playerProfile.RagfairInfo.IsRatingGrowing,
|
||||
Avatar = null,
|
||||
Aid = playerProfile.Aid,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the offer price that's listed on the flea listing
|
||||
/// </summary>
|
||||
@@ -1083,15 +1098,15 @@ public class RagfairOfferGenerator(
|
||||
// Filter possible barters to items that match the price range + not itself
|
||||
var min = desiredItemCostRouble - offerCostVarianceRoubles;
|
||||
var max = desiredItemCostRouble + offerCostVarianceRoubles;
|
||||
var itemsInsidePriceBounds = itemFleaPrices.Where(itemAndPrice =>
|
||||
itemAndPrice.Price >= min
|
||||
&& itemAndPrice.Price <= max
|
||||
&& !string.Equals(
|
||||
itemAndPrice.Tpl,
|
||||
offerItems[0].Template,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
) // Don't allow the item being sold to be chosen
|
||||
);
|
||||
var rootOfferItem = offerItems.FirstOrDefault();
|
||||
|
||||
var itemsInsidePriceBounds = itemFleaPrices
|
||||
.Where(itemAndPrice =>
|
||||
itemAndPrice.Price >= min
|
||||
&& itemAndPrice.Price <= max
|
||||
&& itemAndPrice.Tpl != rootOfferItem.Template // Don't allow the item being sold to be chosen
|
||||
)
|
||||
.ToList();
|
||||
|
||||
// No items on flea have a matching price, fall back to currency
|
||||
if (!itemsInsidePriceBounds.Any())
|
||||
@@ -1100,7 +1115,7 @@ public class RagfairOfferGenerator(
|
||||
}
|
||||
|
||||
// Choose random item from price-filtered flea items
|
||||
var randomItem = randomUtil.GetArrayValue(itemsInsidePriceBounds.ToList());
|
||||
var randomItem = randomUtil.GetArrayValue(itemsInsidePriceBounds);
|
||||
|
||||
return [new BarterScheme { Count = barterItemCount, Template = randomItem.Tpl }];
|
||||
}
|
||||
|
||||
+2
-2
@@ -152,7 +152,7 @@ public class GiveSptCommand(
|
||||
|
||||
localizedGlobal = GetGlobalsLocale(locale);
|
||||
var allAllowedItemNames = _itemHelper
|
||||
.GetItems()
|
||||
.GetItemsClone()
|
||||
.Where(IsItemAllowed)
|
||||
.Select(i =>
|
||||
localizedGlobal
|
||||
@@ -207,7 +207,7 @@ public class GiveSptCommand(
|
||||
// item is just the tplId.
|
||||
MongoId tplId = isItemName
|
||||
? _itemHelper
|
||||
.GetItems()
|
||||
.GetItemsClone()
|
||||
.Where(IsItemAllowed)
|
||||
.FirstOrDefault(i =>
|
||||
(localizedGlobal[$"{i?.Id} Name"]?.ToLowerInvariant() ?? i.Properties.Name)
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DialogueHelper(ISptLogger<DialogueHelper> logger, ProfileHelper pro
|
||||
/// <param name="sessionID">Session/player id</param>
|
||||
/// <param name="itemId">Item being moved to inventory</param>
|
||||
/// <returns>Collection of items from message</returns>
|
||||
public List<Item> GetMessageItemContents(string messageID, MongoId sessionID, MongoId itemId)
|
||||
public List<Item> GetMessageItemContents(MongoId messageID, MongoId sessionID, MongoId itemId)
|
||||
{
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionID);
|
||||
var dialogueData = fullProfile.DialogueRecords;
|
||||
|
||||
@@ -1013,7 +1013,7 @@ public class InventoryHelper(
|
||||
{
|
||||
// Split requests don't use 'use' but 'splitItem' property
|
||||
fromInventoryItems = dialogueHelper.GetMessageItemContents(
|
||||
request.FromOwner.Id,
|
||||
request.FromOwner.Id.Value,
|
||||
sessionId,
|
||||
itemId
|
||||
);
|
||||
|
||||
@@ -121,9 +121,7 @@ public class ItemHelper(
|
||||
);
|
||||
|
||||
// Check if any item in the filtered pool matches the provided item
|
||||
return filteredPool.Any(poolItem =>
|
||||
string.Equals(poolItem.Template, itemTpl, StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
return filteredPool.Any(poolItem => poolItem.Template == itemTpl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -283,7 +281,7 @@ public class ItemHelper(
|
||||
/// <param name="tpl">Template id to check</param>
|
||||
/// <param name="invalidBaseTypes">OPTIONAL - Base types deemed invalid</param>
|
||||
/// <returns>true for items that may be in player possession and not quest items</returns>
|
||||
public bool IsValidItem(MongoId tpl, ICollection<MongoId>? invalidBaseTypes = null)
|
||||
public bool IsValidItem(MongoId tpl, ISet<MongoId>? invalidBaseTypes = null)
|
||||
{
|
||||
var baseTypes = invalidBaseTypes ?? _defaultInvalidBaseTypes;
|
||||
var itemDetails = GetItem(tpl);
|
||||
@@ -295,9 +293,9 @@ public class ItemHelper(
|
||||
|
||||
return !(itemDetails.Value.Properties.QuestItem ?? false)
|
||||
&& string.Equals(itemDetails.Value.Type, "Item", StringComparison.OrdinalIgnoreCase)
|
||||
&& baseTypes.All(x => !IsOfBaseclass(tpl, x))
|
||||
&& GetItemPrice(tpl) > 0
|
||||
&& !itemFilterService.IsItemBlacklisted(tpl);
|
||||
&& !itemFilterService.IsItemBlacklisted(tpl)
|
||||
&& baseTypes.All(x => !IsOfBaseclass(tpl, x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -502,7 +500,7 @@ public class ItemHelper(
|
||||
/// Get cloned copy of all item data from items.json
|
||||
/// </summary>
|
||||
/// <returns>List of TemplateItem objects</returns>
|
||||
public List<TemplateItem> GetItems()
|
||||
public List<TemplateItem> GetItemsClone()
|
||||
{
|
||||
return cloner.Clone(databaseService.GetItems().Values.ToList());
|
||||
}
|
||||
@@ -724,14 +722,8 @@ public class ItemHelper(
|
||||
{
|
||||
// Parent matches desired item + all items in list do not match
|
||||
if (
|
||||
string.Equals(
|
||||
itemFromAssort.ParentId,
|
||||
itemIdToFind,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
&& list.All(item =>
|
||||
!string.Equals(itemFromAssort.Id, item.Id, StringComparison.Ordinal)
|
||||
)
|
||||
itemFromAssort.ParentId == itemIdToFind
|
||||
&& list.All(item => itemFromAssort.Id != item.Id)
|
||||
)
|
||||
{
|
||||
list.Add(itemFromAssort);
|
||||
@@ -937,7 +929,7 @@ public class ItemHelper(
|
||||
// Update all parentIds of items attached to base item to use new id
|
||||
foreach (var item in itemWithChildren)
|
||||
{
|
||||
if (string.Equals(item.ParentId, oldId, StringComparison.OrdinalIgnoreCase))
|
||||
if (item.ParentId == oldId)
|
||||
{
|
||||
item.ParentId = newId;
|
||||
}
|
||||
@@ -992,9 +984,7 @@ public class ItemHelper(
|
||||
item.Id = newId;
|
||||
|
||||
// Find all children of item and update their parent ids to match
|
||||
var childItems = inventory.Items.Where(x =>
|
||||
string.Equals(x.ParentId, originalId, StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
var childItems = inventory.Items.Where(x => x.ParentId == originalId);
|
||||
foreach (var childItem in childItems)
|
||||
{
|
||||
childItem.ParentId = newId;
|
||||
@@ -1072,9 +1062,7 @@ public class ItemHelper(
|
||||
item.Id = newId;
|
||||
|
||||
// Find all children of item and update their parent ids to match
|
||||
var childItems = originalItems.Where(x =>
|
||||
string.Equals(x.ParentId, originalId, StringComparison.OrdinalIgnoreCase)
|
||||
);
|
||||
var childItems = originalItems.Where(x => x.ParentId == originalId);
|
||||
foreach (var childItem in childItems)
|
||||
{
|
||||
childItem.ParentId = newId;
|
||||
|
||||
@@ -1482,14 +1482,7 @@ public class QuestHelper(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
condition.Target.IsItem
|
||||
&& string.Equals(
|
||||
condition.Target.Item,
|
||||
completedQuestId,
|
||||
StringComparison.InvariantCultureIgnoreCase
|
||||
)
|
||||
)
|
||||
if (condition.Target.IsItem && condition.Target.Item == completedQuestId)
|
||||
{
|
||||
// Not a list, plain string
|
||||
return true;
|
||||
|
||||
@@ -92,7 +92,7 @@ public class RagfairOfferHelper(
|
||||
CheckAndLockOfferFromPlayerTieredFlea(
|
||||
tieredFlea,
|
||||
offer,
|
||||
tieredFleaLimitTypes.Keys.ToList(),
|
||||
tieredFleaLimitTypes.Keys.ToHashSet(),
|
||||
pmcData.Info.Level.Value
|
||||
);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public class RagfairOfferHelper(
|
||||
protected void CheckAndLockOfferFromPlayerTieredFlea(
|
||||
TieredFlea tieredFlea,
|
||||
RagfairOffer offer,
|
||||
List<MongoId> tieredFleaLimitTypes,
|
||||
HashSet<MongoId> tieredFleaLimitTypes,
|
||||
int playerLevel
|
||||
)
|
||||
{
|
||||
@@ -199,7 +199,7 @@ public class RagfairOfferHelper(
|
||||
CheckAndLockOfferFromPlayerTieredFlea(
|
||||
tieredFlea,
|
||||
offer,
|
||||
tieredFleaLimitTypes.Keys.ToList(),
|
||||
tieredFleaLimitTypes.Keys.ToHashSet(),
|
||||
pmcData.Info.Level.Value
|
||||
);
|
||||
}
|
||||
@@ -296,7 +296,7 @@ public class RagfairOfferHelper(
|
||||
CheckAndLockOfferFromPlayerTieredFlea(
|
||||
tieredFlea,
|
||||
offer,
|
||||
tieredFleaLimitTypes.Keys.ToList(),
|
||||
tieredFleaLimitTypes.Keys.ToHashSet(),
|
||||
pmcData.Info.Level.Value
|
||||
);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public readonly struct MongoId : IEquatable<MongoId>
|
||||
{
|
||||
if (other is null)
|
||||
{
|
||||
return other == this;
|
||||
return false;
|
||||
}
|
||||
|
||||
return other.ToString().Equals(ToString(), StringComparison.InvariantCultureIgnoreCase);
|
||||
@@ -142,7 +142,7 @@ public readonly struct MongoId : IEquatable<MongoId>
|
||||
|
||||
public bool IsEmpty()
|
||||
{
|
||||
if (_stringId == "000000000000000000000000" || string.IsNullOrEmpty(_stringId))
|
||||
if (string.IsNullOrEmpty(_stringId) || _stringId == "000000000000000000000000")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -138,11 +138,11 @@ public record ItemBuyData
|
||||
|
||||
// MongoId
|
||||
[JsonPropertyName("category")]
|
||||
public required List<MongoId> Category { get; set; }
|
||||
public required HashSet<MongoId> Category { get; set; }
|
||||
|
||||
// MongoId
|
||||
[JsonPropertyName("id_list")]
|
||||
public required List<MongoId> IdList { get; set; }
|
||||
public required HashSet<MongoId> IdList { get; set; }
|
||||
}
|
||||
|
||||
public record ItemSellData
|
||||
@@ -151,10 +151,10 @@ public record ItemSellData
|
||||
public Dictionary<string, object>? ExtensionData { get; set; }
|
||||
|
||||
[JsonPropertyName("category")]
|
||||
public required List<MongoId> Category { get; set; }
|
||||
public required HashSet<MongoId> Category { get; set; }
|
||||
|
||||
[JsonPropertyName("id_list")]
|
||||
public required List<MongoId> IdList { get; set; }
|
||||
public required HashSet<MongoId> IdList { get; set; }
|
||||
}
|
||||
|
||||
public record TraderInsurance
|
||||
|
||||
@@ -88,7 +88,7 @@ public record RagfairOffer
|
||||
/// Tightly bound to offer.items[0].upd.stackObjectsCount
|
||||
/// </summary>
|
||||
[JsonPropertyName("quantity")]
|
||||
public int? Quantity { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
}
|
||||
|
||||
public record OfferRequirement
|
||||
|
||||
@@ -106,7 +106,7 @@ public record FenceConfig
|
||||
/// Prevent duplicate offers of items of specific categories by parentId
|
||||
/// </summary>
|
||||
[JsonPropertyName("preventDuplicateOffersOfCategory")]
|
||||
public required List<MongoId> PreventDuplicateOffersOfCategory { get; set; }
|
||||
public required HashSet<MongoId> PreventDuplicateOffersOfCategory { get; set; }
|
||||
|
||||
[JsonPropertyName("regenerateAssortsOnRefresh")]
|
||||
public bool RegenerateAssortsOnRefresh { get; set; }
|
||||
|
||||
@@ -242,8 +242,8 @@ public class AirdropService(
|
||||
// Get all items that match the blacklisted types and fold into item blacklist
|
||||
var itemTypeBlacklist = _itemFilterService.GetItemRewardBaseTypeBlacklist();
|
||||
var itemsMatchingTypeBlacklist = _itemHelper
|
||||
.GetItems()
|
||||
.Where(templateItem => !string.IsNullOrEmpty(templateItem.Parent))
|
||||
.GetItemsClone()
|
||||
.Where(templateItem => !templateItem.Parent.IsEmpty())
|
||||
.Where(templateItem =>
|
||||
_itemHelper.IsOfBaseclasses(templateItem.Parent, itemTypeBlacklist)
|
||||
)
|
||||
|
||||
@@ -901,7 +901,7 @@ public class CircleOfCultistService(
|
||||
bool itemsShouldBeHighValue
|
||||
)
|
||||
{
|
||||
var allItems = itemHelper.GetItems();
|
||||
var allItems = itemHelper.GetItemsClone();
|
||||
var currentItemCount = 0;
|
||||
var attempts = 0;
|
||||
// `currentItemCount` var will look for the correct number of items, `attempts` var will keep this from never stopping if the highValueThreshold is too high
|
||||
|
||||
@@ -814,7 +814,7 @@ public class FenceService(
|
||||
var childItemsAndSingleRoot = baseFenceAssortClone
|
||||
.Items.Where(item =>
|
||||
!string.Equals(item.ParentId, "hideout", StringComparison.Ordinal)
|
||||
|| string.Equals(item.Id, chosenBaseAssortRoot.Id, StringComparison.Ordinal)
|
||||
|| item.Id == chosenBaseAssortRoot.Id
|
||||
)
|
||||
.ToList();
|
||||
|
||||
|
||||
@@ -89,25 +89,28 @@ public class ItemBaseClassService(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_itemBaseClassesCache.TryGetValue(itemTpl, out var baseClassList))
|
||||
var existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out var baseClassList);
|
||||
if (!existsInCache)
|
||||
{
|
||||
// Not found
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
serverLocalisationService.GetText("baseclass-item_not_found", itemTpl)
|
||||
);
|
||||
}
|
||||
|
||||
// Not found in cache, Hydrate again - some mods add items late in server startup lifecycle
|
||||
HydrateItemBaseClassCache();
|
||||
|
||||
existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out baseClassList);
|
||||
}
|
||||
|
||||
if (existsInCache)
|
||||
{
|
||||
return baseClassList.Overlaps(baseClasses);
|
||||
}
|
||||
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(serverLocalisationService.GetText("baseclass-item_not_found", itemTpl));
|
||||
}
|
||||
|
||||
// Not found in cache, Hydrate again - some mods add items late
|
||||
HydrateItemBaseClassCache();
|
||||
|
||||
// Check for item again, return false if item not found a second time
|
||||
if (_itemBaseClassesCache.TryGetValue(itemTpl, out var value))
|
||||
{
|
||||
return value.Any(baseClasses.Contains);
|
||||
}
|
||||
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("baseclass-item_not_found_failed", itemTpl)
|
||||
);
|
||||
|
||||
@@ -146,8 +146,11 @@ public class RagfairOfferHolder(
|
||||
var sellerIsTrader = _ragfairServerHelper.IsTrader(sellerId);
|
||||
var itemSoldTemplate = _itemHelper.GetItem(itemTpl);
|
||||
if (
|
||||
!string.IsNullOrEmpty(itemTpl)
|
||||
&& !(sellerIsTrader || _profileHelper.IsPlayer(sellerId))
|
||||
!itemTpl.IsEmpty()
|
||||
&& !(
|
||||
sellerIsTrader
|
||||
|| (bool)offer.ExtensionData.GetValueOrDefault("isPlayerOffer", false)
|
||||
)
|
||||
&& _offersByTemplate.TryGetValue(itemTpl, out var offers)
|
||||
&& offers?.Count
|
||||
>= _ragfairServerHelper.GetOfferCountByBaseType(itemSoldTemplate.Value.Parent)
|
||||
|
||||
Reference in New Issue
Block a user