diff --git a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs index 45882e1b..cf15c816 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs @@ -908,7 +908,7 @@ public class HideoutController( var output = _eventOutputHolder.GetOutput(sessionID); var hideoutDb = _databaseService.GetHideout(); - if (request.RecipeId == HideoutHelper.BitcoinFarm) + if (request.RecipeId == HideoutHelper.BitcoinProductionId) { // Ensure server and client are in-sync when player presses 'get items' on farm _hideoutHelper.UpdatePlayerHideout(sessionID); diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs index 9a1c960c..cdff0730 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs @@ -6,12 +6,6 @@ namespace SPTarkov.Server.Core.Extensions { public static class ProductionExtensions { - private static readonly HashSet _idCheck = - [ - HideoutHelper.BitcoinFarm, - HideoutHelper.CultistCircleCraftId, - ]; - /// /// Has the craft completed /// Ignores bitcoin farm/cultist circle as they're continuous crafts @@ -20,7 +14,9 @@ namespace SPTarkov.Server.Core.Extensions /// True when craft is complete public static bool IsCraftComplete(this Production craft) { - return craft.Progress >= craft.ProductionTime && !_idCheck.Contains(craft.RecipeId); + return craft.Progress >= craft.ProductionTime + && !craft.IsCraftOfType(HideoutAreas.BitcoinFarm) + && !craft.IsCraftOfType(HideoutAreas.CircleOfCultists); } /// @@ -34,9 +30,9 @@ namespace SPTarkov.Server.Core.Extensions switch (hideoutType) { case HideoutAreas.WaterCollector: - return craft.RecipeId == HideoutHelper.WaterCollector; + return craft.RecipeId == HideoutHelper.WaterCollectorId; case HideoutAreas.BitcoinFarm: - return craft.RecipeId == HideoutHelper.BitcoinFarm; + return craft.RecipeId == HideoutHelper.BitcoinProductionId; case HideoutAreas.ScavCase: return craft.SptIsScavCase ?? false; case HideoutAreas.CircleOfCultists: diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs index 5c9ddbd6..06f1def0 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs @@ -30,10 +30,8 @@ public class HideoutHelper( ICloner _cloner ) { - public const string BitcoinFarm = "5d5c205bd582a50d042a3c0e"; - public const string CultistCircleCraftId = "66827062405f392b203a44cf"; - public const string BitcoinProductionId = "5d5c205bd582a50d042a3c0e"; - public const string WaterCollector = "5d5589c1f934db045e6c5492"; + public static readonly MongoId BitcoinProductionId = new("5d5c205bd582a50d042a3c0e"); + public static readonly MongoId WaterCollectorId = new("5d5589c1f934db045e6c5492"); public const int MaxSkillPoint = 5000; /// @@ -732,7 +730,7 @@ public class HideoutHelper( // Canister with purified water craft exists if ( - pmcData.Hideout.Production.TryGetValue(WaterCollector, out var purifiedWaterCraft) + pmcData.Hideout.Production.TryGetValue(WaterCollectorId, out var purifiedWaterCraft) && purifiedWaterCraft.GetType() == typeof(Production) ) { @@ -751,7 +749,7 @@ public class HideoutHelper( // seem to not trigger consistently var recipe = new HideoutSingleProductionStartRequestData { - RecipeId = WaterCollector, + RecipeId = WaterCollectorId, Action = "HideoutSingleProductionStart", Items = [], Tools = [], @@ -792,7 +790,7 @@ public class HideoutHelper( var timeReductionSeconds = 0D; // Bitcoin farm is excluded from crafting skill cooldown reduction - if (recipeId != BitcoinFarm) + if (recipeId != BitcoinProductionId) // Seconds to deduct from crafts total time { timeReductionSeconds += GetSkillProductionTimeReduction( @@ -844,7 +842,7 @@ public class HideoutHelper( ) { var filterDrainRate = GetWaterFilterDrainRate(pmcData); - var craftProductionTime = GetTotalProductionTimeSeconds(WaterCollector); + var craftProductionTime = GetTotalProductionTimeSeconds(WaterCollectorId); var secondsSinceServerTick = GetTimeElapsedSinceLastServerTick(pmcData, isGeneratorOn); filterDrainRate = GetTimeAdjustedWaterFilterDrainRate( @@ -1285,7 +1283,7 @@ public class HideoutHelper( { var bitcoinProductions = _databaseService .GetHideout() - .Production.Recipes.FirstOrDefault(production => production.Id == BitcoinFarm); + .Production.Recipes.FirstOrDefault(production => production.Id == BitcoinProductionId); var productionSlots = bitcoinProductions?.ProductionLimitCount ?? 3; // Default to 3 if none found var hasManagementSkillSlots = _profileHelper.HasEliteSkillLevel( SkillTypes.HideoutManagement, @@ -1400,7 +1398,7 @@ public class HideoutHelper( ) { // Get how many coins were crafted and ready to pick up - pmcData.Hideout.Production.TryGetValue(BitcoinFarm, out var bitcoinCraft); + pmcData.Hideout.Production.TryGetValue(BitcoinProductionId, out var bitcoinCraft); var craftedCoinCount = bitcoinCraft?.Products?.Count; if (bitcoinCraft is null || craftedCoinCount is null) { @@ -1445,15 +1443,16 @@ public class HideoutHelper( // Is at max capacity + we collected all coins - reset production start time var coinSlotCount = GetBTCSlots(pmcData); - if (pmcData.Hideout.Production[BitcoinFarm].Products.Count >= coinSlotCount) + if (pmcData.Hideout.Production[BitcoinProductionId].Products.Count >= coinSlotCount) // Set start to now { - pmcData.Hideout.Production[BitcoinFarm].StartTimestamp = _timeUtil.GetTimeStamp(); + pmcData.Hideout.Production[BitcoinProductionId].StartTimestamp = + _timeUtil.GetTimeStamp(); } // Remove crafted coins from production in profile now they've been collected // Can only collect all coins, not individually - pmcData.Hideout.Production[BitcoinFarm].Products = []; + pmcData.Hideout.Production[BitcoinProductionId].Products = []; } /// 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 62e3802e..beff1c13 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs @@ -938,7 +938,7 @@ public record Production // use this instead of productive and scavcase [JsonPropertyName("sptIsCultistCircle")] public bool? SptIsCultistCircle { get; set; } - public string? RecipeId { get; set; } + public MongoId RecipeId { get; set; } } public record BotHideoutArea @@ -1094,7 +1094,7 @@ public record Bonus public Dictionary? ExtensionData { get; set; } [JsonPropertyName("id")] - public MongoId? Id { get; set; } + public MongoId Id { get; set; } [JsonPropertyName("type")] [JsonConverter(typeof(JsonStringEnumConverter))] diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutArea.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutArea.cs index 160576cc..3b15f6ef 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutArea.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutArea.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Enums; @@ -10,7 +11,7 @@ public record HideoutArea public Dictionary? ExtensionData { get; set; } [JsonPropertyName("_id")] - public string? Id { get; set; } + public MongoId Id { get; set; } [JsonPropertyName("type")] public HideoutAreas? Type { get; set; } @@ -37,7 +38,7 @@ public record HideoutArea public bool? EnableAreaRequirements { get; set; } [JsonPropertyName("parentArea")] - public string? ParentArea { get; set; } + public MongoId? ParentArea { get; set; } [JsonPropertyName("stages")] public Dictionary? Stages { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs index 325fdf96..1259c5ac 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutCancelProductionRequestData.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Request; namespace SPTarkov.Server.Core.Models.Eft.Hideout; @@ -6,7 +7,7 @@ namespace SPTarkov.Server.Core.Models.Eft.Hideout; public record HideoutCancelProductionRequestData : BaseInteractionRequestData { [JsonPropertyName("recipeId")] - public string? RecipeId { get; set; } + public MongoId RecipeId { get; set; } [JsonPropertyName("timestamp")] public long? Timestamp { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs index 061c77d3..e2bdc090 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutContinuousProductionStartRequestData.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Inventory; namespace SPTarkov.Server.Core.Models.Eft.Hideout; @@ -9,7 +10,7 @@ public record HideoutContinuousProductionStartRequestData : InventoryBaseActionR public Dictionary? ExtensionData { get; set; } [JsonPropertyName("recipeId")] - public string? RecipeId { get; set; } + public MongoId? RecipeId { get; set; } [JsonPropertyName("timestamp")] public double? Timestamp { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutDeleteProductionRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutDeleteProductionRequestData.cs index 441b3d1d..26bf38b1 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutDeleteProductionRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutDeleteProductionRequestData.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Inventory; namespace SPTarkov.Server.Core.Models.Eft.Hideout; @@ -9,7 +10,7 @@ public record HideoutDeleteProductionRequestData : InventoryBaseActionRequestDat public Dictionary? ExtensionData { get; set; } [JsonPropertyName("recipeId")] - public string? RecipeId { get; set; } + public MongoId RecipeId { get; set; } [JsonPropertyName("timestamp")] public double? Timestamp { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutImproveAreaRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutImproveAreaRequestData.cs index 1a25b351..3e3252e5 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutImproveAreaRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutImproveAreaRequestData.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Eft.Inventory; using SPTarkov.Server.Core.Models.Enums; @@ -14,7 +15,7 @@ public record HideoutImproveAreaRequestData : InventoryBaseActionRequestData /// Hideout area id from areas.json /// [JsonPropertyName("id")] - public string? AreaId { get; set; } + public MongoId AreaId { get; set; } [JsonPropertyName("areaType")] public HideoutAreas? AreaType { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutProduction.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutProduction.cs index a1dc8757..ef441b21 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutProduction.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutProduction.cs @@ -25,7 +25,7 @@ public record HideoutProduction public Dictionary? ExtensionData { get; set; } [JsonPropertyName("_id")] - public string? Id { get; set; } + public MongoId Id { get; set; } [JsonPropertyName("areaType")] public HideoutAreas? AreaType { get; set; } @@ -40,7 +40,7 @@ public record HideoutProduction /// Tpl of item being crafted /// [JsonPropertyName("endProduct")] - public string? EndProduct { get; set; } + public MongoId EndProduct { get; set; } [JsonPropertyName("isEncoded")] public bool? IsEncoded { get; set; } @@ -109,7 +109,7 @@ public record ScavRecipe public Dictionary? ExtensionData { get; set; } [JsonPropertyName("_id")] - public string? Id { get; set; } + public MongoId Id { get; set; } [JsonPropertyName("requirements")] public List? Requirements { get; set; } @@ -142,5 +142,5 @@ public record CultistRecipe public Dictionary? ExtensionData { get; set; } [JsonPropertyName("_id")] - public string? Id { get; set; } + public MongoId Id { get; set; } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutScavCaseStartRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutScavCaseStartRequestData.cs index 292c3aa7..ee753ace 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutScavCaseStartRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutScavCaseStartRequestData.cs @@ -10,7 +10,7 @@ public record HideoutScavCaseStartRequestData : InventoryBaseActionRequestData public Dictionary? ExtensionData { get; set; } [JsonPropertyName("recipeId")] - public string? RecipeId { get; set; } + public MongoId RecipeId { get; set; } [JsonPropertyName("items")] public List? Items { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutSingleProductionStartRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutSingleProductionStartRequestData.cs index ba0a9e9e..ea27b732 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutSingleProductionStartRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutSingleProductionStartRequestData.cs @@ -10,7 +10,7 @@ public record HideoutSingleProductionStartRequestData : InventoryBaseActionReque public Dictionary? ExtensionData { get; set; } [JsonPropertyName("recipeId")] - public string? RecipeId { get; set; } + public MongoId RecipeId { get; set; } [JsonPropertyName("items")] public List? Items { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutTakeProductionRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutTakeProductionRequestData.cs index 636a597e..1dd64420 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutTakeProductionRequestData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Hideout/HideoutTakeProductionRequestData.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Inventory; namespace SPTarkov.Server.Core.Models.Eft.Hideout; @@ -9,7 +10,7 @@ public record HideoutTakeProductionRequestData : InventoryBaseActionRequestData public Dictionary? ExtensionData { get; set; } [JsonPropertyName("recipeId")] - public string? RecipeId { get; set; } + public MongoId RecipeId { get; set; } [JsonPropertyName("timestamp")] public int? Timestamp { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs b/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs index 55e902a1..6e4b3d6a 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs @@ -1037,7 +1037,7 @@ public class ProfileFixerService( protected Bonus? GetBonusFromProfile(List? profileBonuses, Bonus bonus) { // match by id first, used by "TextBonus" bonuses - if (bonus.Id is not null) + if (!bonus.Id.IsEmpty()) { return profileBonuses?.FirstOrDefault(x => x.Id == bonus.Id); } diff --git a/Tools/HideoutCraftQuestIdGenerator/HideoutCraftQuestIdGenerator.cs b/Tools/HideoutCraftQuestIdGenerator/HideoutCraftQuestIdGenerator.cs index e0e6bf6c..a45aaefa 100644 --- a/Tools/HideoutCraftQuestIdGenerator/HideoutCraftQuestIdGenerator.cs +++ b/Tools/HideoutCraftQuestIdGenerator/HideoutCraftQuestIdGenerator.cs @@ -1,5 +1,6 @@ using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Helpers; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Eft.Hideout; using SPTarkov.Server.Core.Models.Enums; @@ -20,7 +21,7 @@ public class HideoutCraftQuestIdGenerator( DatabaseImporter _databaseImporter ) { - private static readonly HashSet _blacklistedProductions = + private static readonly HashSet _blacklistedProductions = [ "6617cdb6b24b0ea24505f618", // Old event quest production "Radio Repeater" alt recipe "66140c4a9688754de10dac07", // Old event quest production "Documents with decrypted data" @@ -29,13 +30,14 @@ public class HideoutCraftQuestIdGenerator( "67093210d514d26f8408612b", // Old event quest production "TG-Vi-24 true vaccine" ]; - private static readonly Dictionary _forcedQuestToProductionAssociations = new() - { - // KEY = PRODUCTION, VALUE = QUEST - { "63a571802116d261d2336cd1", "625d6ffaf7308432be1d44c5" }, // Network Provider - Part 2 - }; + private static readonly Dictionary _forcedQuestToProductionAssociations = + new() + { + // KEY = PRODUCTION, VALUE = QUEST + { "63a571802116d261d2336cd1", "625d6ffaf7308432be1d44c5" }, // Network Provider - Part 2 + }; - private readonly Dictionary _questProductionMap = new(); + private readonly Dictionary _questProductionMap = new(); private readonly List _questProductionOutputList = []; public async Task Run() @@ -238,9 +240,9 @@ public class HideoutCraftQuestIdGenerator( public class QuestProductionOutput { - public string QuestId { get; set; } + public MongoId QuestId { get; set; } - public string ItemTemplate { get; set; } + public MongoId ItemTemplate { get; set; } public double Quantity { get; set; } }