From a1e0dadd086288fca7f170cae21299883a78d6d4 Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 23 Jul 2025 15:55:28 +0100 Subject: [PATCH] Part 2 of list to ienumerable --- .../Controllers/BuildController.cs | 22 ++++---- .../Controllers/InsuranceController.cs | 36 ++++++------- .../Controllers/InventoryController.cs | 2 +- .../Controllers/TradeController.cs | 2 +- .../Generators/BotEquipmentModGenerator.cs | 19 +++---- .../Generators/BotLootGenerator.cs | 2 +- .../Generators/BotWeaponGenerator.cs | 2 +- .../Generators/FenceBaseAssortGenerator.cs | 8 +-- .../Generators/LocationLootGenerator.cs | 6 +-- .../Generators/RagfairAssortGenerator.cs | 21 ++++---- .../Generators/RagfairOfferGenerator.cs | 16 +++--- .../RepeatableQuestRewardGenerator.cs | 2 +- .../Generators/ScavCaseRewardGenerator.cs | 12 ++--- .../Helpers/HandbookHelper.cs | 2 +- .../Helpers/HideoutHelper.cs | 12 ++--- .../Helpers/InRaidHelper.cs | 54 +++++++++---------- .../Helpers/InventoryHelper.cs | 4 +- .../Helpers/ItemHelper.cs | 29 +++++----- .../Helpers/PrestigeHelper.cs | 6 ++- .../Helpers/TraderHelper.cs | 4 +- .../Models/Eft/Common/Tables/BotBase.cs | 23 ++++---- .../Eft/Inventory/AddItemsDirectRequest.cs | 2 +- .../PresetBuildActionRequestData.cs | 2 +- .../Models/Spt/Bots/ModToSpawnRequest.cs | 2 +- .../Models/Spt/Config/QuestConfig.cs | 4 +- .../Services/FenceService.cs | 14 +++-- .../Services/ItemBaseClassService.cs | 2 +- .../Services/LocationLifecycleService.cs | 12 ++--- .../Services/PmcChatResponseService.cs | 6 ++- 29 files changed, 166 insertions(+), 162 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/BuildController.cs b/Libraries/SPTarkov.Server.Core/Controllers/BuildController.cs index af9717ef..688b595f 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/BuildController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/BuildController.cs @@ -87,29 +87,29 @@ public class BuildController( /// Handle client/builds/weapon/save /// /// Session/Player id - /// - public void SaveWeaponBuild(MongoId sessionId, PresetBuildActionRequestData body) + /// + public void SaveWeaponBuild(MongoId sessionId, PresetBuildActionRequestData request) { var pmcData = profileHelper.GetPmcProfile(sessionId); // Replace duplicate Id's. The first item is the base item. // The root ID and the base item ID need to match. - body.Items = itemHelper.ReplaceIDs(body.Items, pmcData); - body.Root = body.Items.FirstOrDefault().Id; + request.Items = itemHelper.ReplaceIDs(request.Items, pmcData); + request.Root = request.Items.FirstOrDefault().Id; // Create new object ready to save into profile userbuilds.weaponBuilds var newBuild = new WeaponBuild { - Id = body.Id, - Name = body.Name, - Root = body.Root, - Items = body.Items, + Id = request.Id, + Name = request.Name, + Root = request.Root, + Items = request.Items.ToList(), }; var profile = profileHelper.GetFullProfile(sessionId); var savedWeaponBuilds = profile.UserBuildData.WeaponBuilds; - var existingBuild = savedWeaponBuilds.FirstOrDefault(x => x.Id == body.Id); + var existingBuild = savedWeaponBuilds.FirstOrDefault(x => x.Id == request.Id); if (existingBuild is not null) { // exists, replace @@ -146,8 +146,8 @@ public class BuildController( Id = request.Id, Name = request.Name, BuildType = EquipmentBuildType.Custom, - Root = request.Items[0].Id, - Items = request.Items, + Root = request.Items.First().Id, + Items = request.Items.ToList(), }; var existingBuild = existingSavedEquipmentBuilds?.FirstOrDefault(build => diff --git a/Libraries/SPTarkov.Server.Core/Controllers/InsuranceController.cs b/Libraries/SPTarkov.Server.Core/Controllers/InsuranceController.cs index ac88d71b..cffc2b7d 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/InsuranceController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/InsuranceController.cs @@ -66,7 +66,7 @@ public class InsuranceController( var insuranceDetails = FilterInsuredItems(sessionId); // Skip profile if no insured items to process - if (insuranceDetails.Count == 0) + if (!insuranceDetails.Any()) { return; } @@ -80,7 +80,7 @@ public class InsuranceController( /// Session/Player id /// The time to check ready status against. Current time by default /// All insured items that are ready to be processed - protected List FilterInsuredItems(MongoId sessionId, long? time = null) + protected IEnumerable FilterInsuredItems(MongoId sessionId, long? time = null) { // Use the current time by default. var insuranceTime = time ?? timeUtil.GetTimeStamp(); @@ -96,9 +96,7 @@ public class InsuranceController( } } - return profileInsuranceDetails - .Where(insured => insuranceTime >= insured.ScheduledTime) - .ToList(); + return profileInsuranceDetails.Where(insured => insuranceTime >= insured.ScheduledTime); } /// @@ -106,12 +104,12 @@ public class InsuranceController( /// /// The insured items to process /// session ID that should receive the processed items - protected void ProcessInsuredItems(List insuranceDetails, MongoId sessionId) + protected void ProcessInsuredItems(IEnumerable insuranceDetails, MongoId sessionId) { if (logger.IsLogEnabled(LogLevel.Debug)) { logger.Debug( - $"Processing {insuranceDetails.Count} insurance packages, which includes a total of: {CountAllInsuranceItems(insuranceDetails)} items, in profile: {sessionId}" + $"Processing {insuranceDetails.Count()} insurance packages, which includes a total of: {CountAllInsuranceItems(insuranceDetails)} items, in profile: {sessionId}" ); } @@ -149,7 +147,7 @@ public class InsuranceController( /// /// /// Count of insured items - protected int CountAllInsuranceItems(List insuranceDetails) + protected int CountAllInsuranceItems(IEnumerable insuranceDetails) { return insuranceDetails.Select(ins => ins.Items.Count).Count(); } @@ -238,13 +236,13 @@ public class InsuranceController( /// The insurance object containing the items to evaluate /// A Dictionary for quick item look-up by item ID /// A dictionary containing parent item IDs to arrays of their attachment items - protected Dictionary> PopulateParentAttachmentsMap( + protected Dictionary> PopulateParentAttachmentsMap( string rootItemParentID, Insurance insured, Dictionary itemsMap ) { - var mainParentToAttachmentsMap = new Dictionary>(); + var mainParentToAttachmentsMap = new Dictionary>(); foreach (var insuredItem in insured.Items) { // Use the parent ID from the item to get the parent item. @@ -335,12 +333,12 @@ public class InsuranceController( /// Dictionary containing parent item IDs to arrays of their attachment items /// Hashset containing parent item IDs to arrays of their attachment items which are not moddable in-raid /// - protected Dictionary> RemoveNonModdableAttachments( - Dictionary> parentAttachmentsMap, + protected Dictionary> RemoveNonModdableAttachments( + Dictionary> parentAttachmentsMap, Dictionary itemsMap ) { - var updatedMap = new Dictionary>(); + var updatedMap = new Dictionary>(); foreach (var map in parentAttachmentsMap) { @@ -389,7 +387,7 @@ public class InsuranceController( protected void ProcessRegularItems( Insurance insured, HashSet toDelete, - Dictionary> parentAttachmentsMap + Dictionary> parentAttachmentsMap ) { foreach (var insuredItem in insured.Items) @@ -436,7 +434,7 @@ public class InsuranceController( /// Trader ID from the Insurance object /// Tracked attachment ids to be removed protected void ProcessAttachments( - Dictionary> mainParentToAttachmentsMap, + Dictionary> mainParentToAttachmentsMap, Dictionary itemsMap, MongoId? insuredTraderId, HashSet toDelete @@ -474,7 +472,7 @@ public class InsuranceController( /// ID of the trader to that has ensured these items /// array that accumulates the IDs of the items to be deleted protected void ProcessAttachmentByParent( - List attachments, + IEnumerable attachments, MongoId traderId, HashSet toDelete ) @@ -522,8 +520,8 @@ public class InsuranceController( /// /// protected void LogAttachmentsBeingRemoved( - List attachmentIdsToRemove, - List attachments, + IEnumerable attachmentIdsToRemove, + IEnumerable attachments, Dictionary attachmentPrices ) { @@ -547,7 +545,7 @@ public class InsuranceController( /// /// Item attachments /// - protected Dictionary WeightAttachmentsByPrice(List attachments) + protected Dictionary WeightAttachmentsByPrice(IEnumerable attachments) { var result = new Dictionary(); diff --git a/Libraries/SPTarkov.Server.Core/Controllers/InventoryController.cs b/Libraries/SPTarkov.Server.Core/Controllers/InventoryController.cs index 5c49fb01..d4aa2524 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/InventoryController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/InventoryController.cs @@ -183,7 +183,7 @@ public class InventoryController( { // The client sends the full list of favorite items, so clear the current favorites pmcData.Inventory.FavoriteItems = []; - pmcData.Inventory.FavoriteItems.AddRange(request.Items); + pmcData.Inventory.FavoriteItems = pmcData.Inventory.FavoriteItems.Union(request.Items); } /// diff --git a/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs b/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs index a8ca63cb..80885fd1 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/TradeController.cs @@ -336,7 +336,7 @@ public class TradeController( /// Rouble price protected int GetPriceOfItemAndChildren( MongoId parentItemId, - List items, + IEnumerable items, Dictionary handbookPrices, TraderBase traderDetails ) diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs index c9ad3f27..d591dbfb 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs @@ -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( @@ -1125,7 +1126,7 @@ public class BotEquipmentModGenerator( var parentSlot = request.ParentTemplate.Properties.Slots?.FirstOrDefault(i => i.Name == request.ModSlot ); - var weaponTemplate = itemHelper.GetItem(request.Weapon[0].Template).Value; + var weaponTemplate = itemHelper.GetItem(request.Weapon.First().Template).Value; // It's ammo, use predefined ammo parameter if (GetAmmoContainers().Contains(request.ModSlot) && request.ModSlot != "mod_magazine") @@ -1155,7 +1156,7 @@ public class BotEquipmentModGenerator( if (modPool.Count > 1) { modPool = FilterSightsByWeaponType( - request.Weapon[0], + request.Weapon.First(), modPool, request.BotWeaponSightWhitelist ); @@ -1261,7 +1262,7 @@ public class BotEquipmentModGenerator( if (parentSlot.Required.GetValueOrDefault(false)) { logger.Warning( - $"Required slot unable to be filled, {request.ModSlot} on {request.ParentTemplate.Name} {request.ParentTemplate.Id} for weapon: {request.Weapon[0].Template}" + $"Required slot unable to be filled, {request.ModSlot} on {request.ParentTemplate.Name} {request.ParentTemplate.Id} for weapon: {request.Weapon.First().Template}" ); } @@ -1323,7 +1324,7 @@ public class BotEquipmentModGenerator( HashSet modPool, Slot parentSlot, ModSpawn? choiceTypeEnum, - List weapon, + IEnumerable weapon, string modSlotName ) { @@ -1366,7 +1367,7 @@ public class BotEquipmentModGenerator( public ChooseRandomCompatibleModResult GetCompatibleModFromPool( HashSet modPool, ModSpawn? modSpawnType, - List weapon + IEnumerable weapon ) { // Create exhaustable pool to pick mod item from @@ -1649,11 +1650,11 @@ public class BotEquipmentModGenerator( /// Array of items that make up a weapon /// Mod to check compatibility with weapon /// True if incompatible - public bool WeaponModComboIsIncompatible(List weapon, MongoId modTpl) + public bool WeaponModComboIsIncompatible(IEnumerable weapon, MongoId modTpl) { // STM-9 + AR-15 Lone Star Ion Lite handguard if ( - weapon[0].Template == ItemTpl.SMG_SOYUZTM_STM9_GEN2_9X19_CARBINE + weapon.First().Template == ItemTpl.SMG_SOYUZTM_STM9_GEN2_9X19_CARBINE && modTpl == ItemTpl.HANDGUARD_AR15_LONE_STAR_ION_LITE ) { @@ -1714,7 +1715,7 @@ public class BotEquipmentModGenerator( MongoId fallbackModTpl, Slot parentSlot, string modSlot, - List items + IEnumerable items ) { // Find compatible mods and make an array of them diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotLootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotLootGenerator.cs index df64341f..cda42851 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/BotLootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/BotLootGenerator.cs @@ -552,7 +552,7 @@ public class BotLootGenerator( new() { Id = newRootItemId, - Template = itemToAddTemplate?.Id ?? string.Empty, + Template = itemToAddTemplate?.Id ?? MongoId.Empty(), Upd = botGeneratorHelper.GenerateExtraPropertiesForItem( itemToAddTemplate, botRole diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotWeaponGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotWeaponGenerator.cs index 11b07388..784b748a 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/BotWeaponGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/BotWeaponGenerator.cs @@ -619,7 +619,7 @@ public class BotWeaponGenerator( /// The bot type we are getting the magazine for. /// Magazine template string. protected MongoId? GetMagazineTemplateFromWeaponTemplate( - List weaponMods, + IEnumerable weaponMods, TemplateItem weaponTemplate, string botRole ) diff --git a/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs index ffc699df..802c274d 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs @@ -35,7 +35,7 @@ public class FenceBaseAssortGenerator( public void GenerateFenceBaseAssorts() { var blockedSeasonalItems = seasonalEventService.GetInactiveSeasonalEventItems(); - var baseFenceAssort = databaseService.GetTrader(Traders.FENCE).Assort; + var baseFenceAssort = databaseService.GetTrader(Traders.FENCE)?.Assort; foreach (var (itemId, rootItemDb) in databaseService.GetItems()) { @@ -165,7 +165,7 @@ public class FenceBaseAssortGenerator( } // Construct preset + mods - var itemAndChildren = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); + var itemAndChildren = _cloner.Clone(defaultPreset.Items).ReplaceIDs(); // Find root item and add some properties to it var rootItem = itemAndChildren.FirstOrDefault(item => @@ -187,7 +187,7 @@ public class FenceBaseAssortGenerator( var itemQualityModifier = itemHelper.GetItemQualityModifierForItems(itemAndChildren); // Multiply weapon+mods rouble price by quality modifier - baseFenceAssort.BarterScheme[itemAndChildren[0].Id] = + baseFenceAssort.BarterScheme[itemAndChildren.First().Id] = [ new() { @@ -199,7 +199,7 @@ public class FenceBaseAssortGenerator( }, ]; - baseFenceAssort.LoyalLevelItems[itemAndChildren[0].Id] = 1; + baseFenceAssort.LoyalLevelItems[itemAndChildren.First().Id] = 1; } } diff --git a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs index 64106ba7..cb97567c 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs @@ -624,8 +624,8 @@ public class LocationLootGenerator( ); // Update root item properties with result of position finder - items[0].SlotId = "main"; - items[0].Location = new ItemLocation + items.First().SlotId = "main"; + items.First().Location = new ItemLocation { X = result.X, Y = result.Y, @@ -1460,7 +1460,7 @@ public record ContainerGroupCount public class ContainerItem { [JsonPropertyName("items")] - public List? Items { get; set; } + public IEnumerable? Items { get; set; } [JsonPropertyName("width")] public int? Width { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs index e1517b42..6323397f 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs @@ -41,7 +41,7 @@ public class RagfairAssortGenerator( /// Each sub list contains item + children (if any) /// /// List with children lists of items - public List> GetAssortItems() + public IEnumerable> GetAssortItems() { return GenerateRagfairAssortItems(); } @@ -50,9 +50,9 @@ public class RagfairAssortGenerator( /// Generate a list of lists (item + children) the flea can sell /// /// List of lists (item + children) - protected List> GenerateRagfairAssortItems() + protected IEnumerable> GenerateRagfairAssortItems() { - List> results = []; + IEnumerable> results = []; // Get cloned items from db var dbItems = databaseService @@ -76,16 +76,16 @@ public class RagfairAssortGenerator( // Add presets base item tpl to the processed list so its skipped later on when processing items processedArmorItems.Add(preset.Items[0].Template); - presetAndModsClone[0].ParentId = "hideout"; - presetAndModsClone[0].SlotId = "hideout"; - presetAndModsClone[0].Upd = new Upd + presetAndModsClone.First().ParentId = "hideout"; + presetAndModsClone.First().SlotId = "hideout"; + presetAndModsClone.First().Upd = new Upd { StackObjectsCount = 99999999, UnlimitedCount = true, SptPresetId = preset.Id, }; - results.Add(presetAndModsClone); + results = results.Union([presetAndModsClone]); } foreach (var (id, item) in dbItems) @@ -105,15 +105,14 @@ public class RagfairAssortGenerator( continue; } - if (processedArmorItems.Contains(id)) // Already processed + if (processedArmorItems.Contains(id)) { continue; } - var ragfairAssort = CreateRagfairAssortRootItem(id, id); // tpl and id must be the same so hideout recipe rewards work - - results.Add([ragfairAssort]); + var assortItemToAdd = new List { CreateRagfairAssortRootItem(id, id) }; // tpl and id must be the same so hideout recipe rewards work + results = results.Union([assortItemToAdd]); } return results; diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs index efe4f9a8..91c8d458 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs @@ -362,13 +362,13 @@ public class RagfairOfferGenerator( stopwatch.Restart(); var tasks = new List(); - foreach (var assortItem in assortItemsToProcess) + foreach (var assortItemWithChildren in assortItemsToProcess) { tasks.Add( Task.Factory.StartNew(() => { CreateOffersFromAssort( - assortItem, + assortItemWithChildren, replacingExpiredOffers, ragfairConfig.Dynamic ); @@ -725,12 +725,12 @@ public class RagfairOfferGenerator( /// DB details of first item protected void RandomiseOfferItemUpdProperties( MongoId userID, - List itemWithMods, + IEnumerable itemWithMods, TemplateItem itemDetails ) { // Add any missing properties to first item in array - AddMissingConditions(itemWithMods[0]); + AddMissingConditions(itemWithMods.First()); if (!(profileHelper.IsPlayer(userID) || ragfairServerHelper.IsTrader(userID))) { @@ -781,11 +781,11 @@ public class RagfairOfferGenerator( /// DB Item details of first item in list protected void RandomiseItemCondition( MongoId conditionSettingsId, - List itemWithMods, + IEnumerable itemWithMods, TemplateItem itemDetails ) { - var rootItem = itemWithMods[0]; + var rootItem = itemWithMods.First(); var itemConditionValues = ragfairConfig.Dynamic.Condition[conditionSettingsId]; var maxMultiplier = randomUtil.GetDouble( @@ -827,7 +827,7 @@ public class RagfairOfferGenerator( if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.WEAPON)) { RandomiseWeaponDurability( - itemWithMods[0], + itemWithMods.First(), itemDetails, maxMultiplier, currentMultiplier @@ -924,7 +924,7 @@ public class RagfairOfferGenerator( /// Chosen multiplier to use for current durability value /// Chosen multiplier to use for max durability value protected void RandomiseArmorDurabilityValues( - List armorWithMods, + IEnumerable armorWithMods, double currentMultiplier, double maxMultiplier ) diff --git a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs index 068c5545..88f916ff 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs @@ -821,7 +821,7 @@ public class RepeatableQuestRewardGenerator( MongoId tpl, HashSet itemTplBlacklist, HashSet itemTypeBlacklist, - List? itemBaseWhitelist = null + IEnumerable? itemBaseWhitelist = null ) { // Return early if not valid item to give as reward diff --git a/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs index 5b51a8a7..e8072f87 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs @@ -40,7 +40,7 @@ public class ScavCaseRewardGenerator( /// /// recipe of the scav case craft /// Product array - public List> Generate(MongoId recipeId) + public IEnumerable> Generate(MongoId recipeId) { CacheDbItems(); @@ -91,13 +91,9 @@ public class ScavCaseRewardGenerator( RewardRarity.SuperRare ); - var result = new List>(); - result = result.Concat(commonRewards).ToList(); - result = result.Concat(rareRewards).ToList(); - result = result.Concat(superRareRewards).ToList(); - // TODO: please make this better, how merge 2d Lists + var result = commonRewards.Concat(rareRewards).Concat(superRareRewards); - return result.ToList(); + return result; } /// @@ -365,7 +361,7 @@ public class ScavCaseRewardGenerator( /// The rarity desired ammo reward is for /// Product array protected List> RandomiseContainerItemRewards( - List rewardItems, + IEnumerable rewardItems, string rarity ) { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HandbookHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HandbookHelper.cs index 8e997beb..342301bd 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HandbookHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HandbookHelper.cs @@ -130,7 +130,7 @@ public class HandbookHelper( /// /// Items to Sum /// - public double GetTemplatePriceForItems(List items) + public double GetTemplatePriceForItems(IEnumerable items) { var total = 0D; foreach (var item in items) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs index 35dabc70..c118b110 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs @@ -1510,9 +1510,9 @@ public class HideoutHelper( ); // Get all slotted dogtag items - var activeDogtags = pmcData - .Inventory.Items.Where(item => item?.SlotId?.StartsWith("dogtag") ?? false) - .ToList(); + var activeDogtags = pmcData.Inventory.Items.Where(item => + item?.SlotId?.StartsWith("dogtag") ?? false + ); // Calculate bonus percent (apply hideoutManagement bonus) var hideoutManagementSkill = pmcData.GetSkillFromProfile(SkillTypes.HideoutManagement); @@ -1534,7 +1534,7 @@ public class HideoutHelper( /// Combat bonus protected static double GetDogtagCombatSkillBonusPercent( PmcData pmcData, - List activeDogtags + IEnumerable activeDogtags ) { // Not own dogtag @@ -1542,12 +1542,12 @@ public class HideoutHelper( var result = 0D; foreach (var dogtag in activeDogtags) { - if (dogtag.Upd.Dogtag is null) + if (dogtag.Upd?.Dogtag?.AccountId is null) { continue; } - if (int.Parse(dogtag.Upd.Dogtag?.AccountId) == pmcData.Aid) + if (int.Parse(dogtag.Upd.Dogtag.AccountId) == pmcData.Aid) { continue; } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs index 403edee3..8c3bf174 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs @@ -110,7 +110,7 @@ public class InRaidHelper( /// Remove FiR status from items. /// /// Items to process - protected void RemoveFiRStatusFromItems(List items) + protected void RemoveFiRStatusFromItems(IEnumerable items) { var dbItems = databaseService.GetItems(); @@ -225,40 +225,38 @@ public class InRaidHelper( /// /// Profile to get items from /// List of items lost on death - protected List GetInventoryItemsLostOnDeath(PmcData pmcProfile) + protected IEnumerable GetInventoryItemsLostOnDeath(PmcData pmcProfile) { var inventoryItems = pmcProfile.Inventory.Items ?? []; var equipmentRootId = pmcProfile?.Inventory?.Equipment; var questRaidItemContainerId = pmcProfile?.Inventory?.QuestRaidItems; - return inventoryItems - .Where(item => + return inventoryItems.Where(item => + { + // Keep items flagged as kept after death + if (IsItemKeptAfterDeath(pmcProfile, item)) { - // Keep items flagged as kept after death - if (IsItemKeptAfterDeath(pmcProfile, item)) - { - return false; - } - - // Remove normal items or quest raid items - if (item.ParentId == equipmentRootId || item.ParentId == questRaidItemContainerId) - { - return true; - } - - // Pocket items are lost on death - // Ensure we don't pick up pocket items from mannequins - if ( - item.SlotId.StartsWith("pocket") - && pmcProfile.DoesItemHaveRootId(item, pmcProfile.Inventory.Equipment) - ) - { - return true; - } - return false; - }) - .ToList(); + } + + // Remove normal items or quest raid items + if (item.ParentId == equipmentRootId || item.ParentId == questRaidItemContainerId) + { + return true; + } + + // Pocket items are lost on death + // Ensure we don't pick up pocket items from mannequins + if ( + item.SlotId.StartsWith("pocket") + && pmcProfile.DoesItemHaveRootId(item, pmcProfile.Inventory.Equipment) + ) + { + return true; + } + + return false; + }); } /// diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs index 71cb0eb3..a3ff906e 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs @@ -257,10 +257,10 @@ public class InventoryHelper( /// Container grid /// Item to check fits /// True it fits - public bool CanPlaceItemInContainer(int[,] containerFS2D, List itemWithChildren) + public bool CanPlaceItemInContainer(int[,] containerFS2D, IEnumerable itemWithChildren) { // Get x/y size of item - var rootItem = itemWithChildren[0]; + var rootItem = itemWithChildren.First(); var (sizeX, sizeY) = GetItemSize(rootItem.Template, rootItem.Id, itemWithChildren); // Look for a place to slot item into diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index 44f1f533..6376d052 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -67,8 +67,12 @@ public class ItemHelper( ItemTpl.BARTER_DOGTAG_USEC_TUE, ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_1, ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_2, + ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_3, + ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_4, ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_1, ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_2, + ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_3, + ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_4, ]; protected static readonly FrozenSet _softInsertIds = @@ -328,7 +332,7 @@ public class ItemHelper( /// Item to check base classes of /// Base classes to check for /// True if any supplied base classes match - public bool IsOfBaseclasses(MongoId tpl, ICollection baseClassTpls) + public bool IsOfBaseclasses(MongoId tpl, IEnumerable baseClassTpls) { return itemBaseClassService.ItemHasBaseClass(tpl, baseClassTpls); } @@ -729,7 +733,7 @@ public class ItemHelper( /// Template id of item to check for /// List of items to check in /// List of children of requested item - public List FindAndReturnChildrenByAssort(MongoId itemIdToFind, List assort) + public List FindAndReturnChildrenByAssort(MongoId itemIdToFind, IEnumerable assort) { List list = []; var itemIdToFindString = itemIdToFind.ToString(); @@ -901,8 +905,8 @@ public class ItemHelper( /// List of Item objects. public List FindBarterItems( string by, - List itemsToSearch, - List desiredBarterItemIds + IEnumerable itemsToSearch, + IEnumerable desiredBarterItemIds ) { // Find required items to take after buying (handles multiple items) @@ -933,13 +937,13 @@ public class ItemHelper( /// /// Item with mods to update. /// New id to add on children of base item. - public void ReplaceRootItemID(List itemWithChildren, string newId = "") + public void ReplaceRootItemID(IEnumerable itemWithChildren, MongoId newId) { // original id on base item - var oldId = itemWithChildren[0].Id; + var oldId = itemWithChildren.First().Id; // Update base item to use new id - itemWithChildren[0].Id = newId; + itemWithChildren.First().Id = newId; // Update all parentIds of items attached to base item to use new id foreach (var item in itemWithChildren) @@ -958,7 +962,7 @@ public class ItemHelper( /// public void ReplaceProfileInventoryIds( BotBaseInventory inventory, - List? insuredItems = null + IEnumerable? insuredItems = null ) { // Blacklist @@ -1028,10 +1032,10 @@ public class ItemHelper( /// Insured items that should not have their IDs replaced /// Quick slot panel /// Items - public List ReplaceIDs( - List originalItems, + public IEnumerable ReplaceIDs( + IEnumerable originalItems, PmcData? pmcData, - List? insuredItems = null, + IEnumerable? insuredItems = null, Dictionary? fastPanel = null ) { @@ -1090,6 +1094,7 @@ public class ItemHelper( } // Update quickslot id + // TODO: i dont think the fast panel key is a mongoid, it should be e.g. "Item4" if (pmcData.Inventory.FastPanel.ContainsKey(originalId)) { pmcData.Inventory.FastPanel[originalId] = newId; @@ -1105,7 +1110,7 @@ public class ItemHelper( /// Will not flag ammo or currency as FiR /// /// The list of items to mark as FiR - public void SetFoundInRaid(List items) + public void SetFoundInRaid(IEnumerable items) { foreach (var item in items) { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs index a996ca37..5a7c4e5b 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs @@ -65,7 +65,8 @@ public class PrestigeHelper( } else { - newProfile.CharacterData.PmcData.Skills.Common.Add(skillToCopy); + newProfile.CharacterData.PmcData.Skills.Common = + newProfile.CharacterData.PmcData.Skills.Common.Union([skillToCopy]); } } @@ -84,7 +85,8 @@ public class PrestigeHelper( } else { - newProfile.CharacterData.PmcData.Skills.Mastering.Add(skillToCopy); + newProfile.CharacterData.PmcData.Skills.Mastering = + newProfile.CharacterData.PmcData.Skills.Mastering.Union([skillToCopy]); } } } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs index 7eb6a4c5..62be0e89 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs @@ -225,8 +225,8 @@ public class TraderHelper( else { pmcData.Info.Bans ??= []; - pmcData.Info.Bans.Add( - new Ban { BanType = BanType.RagFair, DateTime = newBanDateTime } + pmcData.Info.Bans = pmcData.Info.Bans.Union( + [new Ban { BanType = BanType.RagFair, DateTime = newBanDateTime }] ); } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs index 1e34bb3c..6fceb70c 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs @@ -208,7 +208,7 @@ public record Info public MemberCategory? SelectedMemberCategory { get; set; } - public List? Bans { get; set; } + public IEnumerable? Bans { get; set; } [JsonPropertyName("lockedMoveCommands")] public bool? LockedMoveCommands { get; set; } @@ -425,11 +425,14 @@ public record BotBaseInventory // TODO: key should be EAreaType enum public Dictionary? HideoutAreaStashes { get; set; } // Key = hideout area key as string + /// + /// key = "Item4", "Item10" + /// [JsonPropertyName("fastPanel")] public Dictionary? FastPanel { get; set; } [JsonPropertyName("favoriteItems")] - public List? FavoriteItems { get; set; } + public IEnumerable? FavoriteItems { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonPropertyName("hideoutCustomizationStashId")] @@ -441,9 +444,9 @@ public record Skills [JsonExtensionData] public Dictionary? ExtensionData { get; set; } - public List Common { get; set; } + public IEnumerable Common { get; set; } - public List? Mastering { get; set; } + public IEnumerable? Mastering { get; set; } public double? Points { get; set; } } @@ -491,9 +494,9 @@ public record EftStats [JsonExtensionData] public Dictionary? ExtensionData { get; set; } - public List? CarriedQuestItems { get; set; } + public IEnumerable? CarriedQuestItems { get; set; } - public List? Victims { get; set; } + public IEnumerable? Victims { get; set; } public double? TotalSessionExperience { get; set; } @@ -510,9 +513,9 @@ public record EftStats [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public Aggressor? Aggressor { get; set; } - public List? DroppedItems { get; set; } + public IEnumerable? DroppedItems { get; set; } - public List? FoundInRaidItems { get; set; } + public IEnumerable? FoundInRaidItems { get; set; } public DamageHistory? DamageHistory { get; set; } @@ -588,7 +591,7 @@ public record SessionCounters [JsonExtensionData] public Dictionary? ExtensionData { get; set; } - public List? Items { get; set; } + public IEnumerable? Items { get; set; } } public record OverallCounters @@ -604,7 +607,7 @@ public record CounterKeyValue [JsonExtensionData] public Dictionary? ExtensionData { get; set; } - public List? Key { get; set; } + public IEnumerable? Key { get; set; } public double? Value { get; set; } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Inventory/AddItemsDirectRequest.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Inventory/AddItemsDirectRequest.cs index cc2db11c..a4b2c1a9 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Inventory/AddItemsDirectRequest.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Inventory/AddItemsDirectRequest.cs @@ -12,7 +12,7 @@ public record AddItemsDirectRequest /// Item and child mods to add to player inventory /// [JsonPropertyName("itemsWithModsToAdd")] - public List>? ItemsWithModsToAdd { get; set; } + public IEnumerable>? ItemsWithModsToAdd { get; set; } [JsonPropertyName("foundInRaid")] public bool? FoundInRaid { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs index 5cd15e6f..657776fa 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/PresetBuild/PresetBuildActionRequestData.cs @@ -26,5 +26,5 @@ public record PresetBuildActionRequestData : IRequestData public string? Root { get; set; } [JsonPropertyName("Items")] - public List? Items { get; set; } + public IEnumerable? Items { get; set; } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs index 37471983..9ade62a7 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs @@ -48,7 +48,7 @@ public record ModToSpawnRequest /// List with only weapon tpl in it, ready for mods to be added /// [JsonPropertyName("weapon")] - public List? Weapon { get; set; } + public IEnumerable? Weapon { get; set; } /// /// Ammo tpl to use if slot requires a cartridge to be added (e.g. mod_magazine) diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs index 78797caa..e51703e3 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs @@ -326,13 +326,13 @@ public record TraderWhitelist /// Quest types this trader can provide: Completion/Exploration/Elimination. /// [JsonPropertyName("questTypes")] - public required List QuestTypes { get; set; } + public required HashSet QuestTypes { get; set; } /// /// Item categories that the reward can be /// [JsonPropertyName("rewardBaseWhitelist")] - public required List RewardBaseWhitelist { get; set; } + public required IEnumerable RewardBaseWhitelist { get; set; } /// /// Can this reward be a weapon? diff --git a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs index 377c1a99..b17cef34 100644 --- a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs @@ -1364,15 +1364,13 @@ public class FenceService( if (!randomUtil.GetChance100(plateExistsChance)) { // Remove plate from armor - armorItemAndMods = armorItemAndMods - .Where(item => - !string.Equals( - item.SlotId, - plateSlot.Name, - StringComparison.CurrentCultureIgnoreCase - ) + armorItemAndMods = armorItemAndMods.Where(item => + !string.Equals( + item.SlotId, + plateSlot.Name, + StringComparison.CurrentCultureIgnoreCase ) - .ToList(); + ); continue; } diff --git a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs index 65bd2116..cad84e03 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs @@ -68,7 +68,7 @@ public class ItemBaseClassService( /// ItemTpl item to check base classes of /// BaseClass base class to check for /// true if item inherits from base class passed in - public bool ItemHasBaseClass(MongoId itemTpl, ICollection baseClasses) + public bool ItemHasBaseClass(MongoId itemTpl, IEnumerable baseClasses) { if (!_cacheGenerated) { diff --git a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs index ae611951..cd4f3296 100644 --- a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs @@ -960,12 +960,12 @@ public class LocationLifecycleService( // Must occur AFTER killer messages have been sent matchBotDetailsCacheService.ClearCache(); - var roles = new List { "pmcbear", "pmcusec" }; + var roles = new HashSet { "pmcbear", "pmcusec" }; - var victims = postRaidProfile - .Stats.Eft.Victims.Where(victim => roles.Contains(victim.Role.ToLowerInvariant())) - .ToList(); - if (victims?.Count > 0) + var victims = postRaidProfile.Stats.Eft.Victims.Where(victim => + roles.Contains(victim.Role.ToLowerInvariant()) + ); + if (victims is not null && victims.Any()) // Player killed PMCs, send some mail responses to them { pmcChatResponseService.SendVictimResponse(sessionId, victims, serverPmcProfile); @@ -1233,7 +1233,7 @@ public class LocationLifecycleService( /// Reset the skill points earned in a raid to 0, ready for next raid /// /// Profile common skills to update - protected void ResetSkillPointsEarnedDuringRaid(List commonSkills) + protected void ResetSkillPointsEarnedDuringRaid(IEnumerable commonSkills) { foreach (var skill in commonSkills) { diff --git a/Libraries/SPTarkov.Server.Core/Services/PmcChatResponseService.cs b/Libraries/SPTarkov.Server.Core/Services/PmcChatResponseService.cs index 20e30949..0bd9bea8 100644 --- a/Libraries/SPTarkov.Server.Core/Services/PmcChatResponseService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/PmcChatResponseService.cs @@ -35,7 +35,11 @@ public class PmcChatResponseService( /// Session ID /// List of bots killed by player /// Player profile - public void SendVictimResponse(MongoId sessionId, List pmcVictims, PmcData pmcData) + public void SendVictimResponse( + MongoId sessionId, + IEnumerable pmcVictims, + PmcData pmcData + ) { foreach (var victim in pmcVictims) {