From 2423a66f403920b054bc164480e3454db8534349 Mon Sep 17 00:00:00 2001 From: Chomp Date: Fri, 28 Mar 2025 17:54:32 +0000 Subject: [PATCH] Refactored how clothing is stored and processed `Suits` is no longer used in full profile, `customisationUnlocks` should be used --- .../Controllers/CustomizationController.cs | 10 +++----- .../Helpers/TraderHelper.cs | 24 ++++++++++--------- .../Eft/Common/Tables/CustomisationStorage.cs | 2 +- .../Models/Eft/Profile/SptProfile.cs | 6 ++++- .../Services/CreateProfileService.cs | 15 ++++++------ .../Services/ProfileFixerService.cs | 15 ++++++++---- 6 files changed, 40 insertions(+), 32 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/CustomizationController.cs b/Libraries/SPTarkov.Server.Core/Controllers/CustomizationController.cs index 0ad314fa..586cd55b 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/CustomizationController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/CustomizationController.cs @@ -128,14 +128,10 @@ public class CustomizationController( /// true if already purchased protected bool OutfitAlreadyPurchased(object suitId, string sessionId) { - var suits = _saveServer.GetProfile(sessionId).Suits; + var fullProfile = _profileHelper.GetFullProfile(sessionId); - if (suits is null || suits.Count == 0) - { - return false; - } - - return suits.Contains(suitId); + // Check if clothing can be found by id + return fullProfile.CustomisationUnlocks.Exists(customisation => Equals(customisation.Id, suitId)); } /// diff --git a/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs index 5850172d..d8f487c6 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs @@ -230,21 +230,23 @@ public class TraderHelper( /// /// Add a list of suit ids to a profiles suit list, no duplicates /// - /// Profile to add to - /// Suit Ids to add - protected void AddSuitsToProfile(SptProfile fullProfile, List suitIds) + /// Profile to add clothing to + /// Clothing Ids to add to profile + public void AddSuitsToProfile(SptProfile fullProfile, List clothingIds) { - if (fullProfile.Suits is null) - { - fullProfile.Suits = []; - } + fullProfile.CustomisationUnlocks ??= []; - foreach (var suitId in suitIds) - // Don't add dupes + foreach (var suitId in clothingIds) { - if (!fullProfile.Suits.Contains(suitId)) + if (!fullProfile.CustomisationUnlocks.Exists((customisation) => customisation.Id == suitId)) { - fullProfile.Suits.Add(suitId); + // Clothing item doesn't exist in profile, add it + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage + { + Id = suitId, + Source = CustomisationSource.UNLOCKED_IN_GAME, + Type = CustomisationType.SUITE + }); } } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/CustomisationStorage.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/CustomisationStorage.cs index 69927900..2591680d 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/CustomisationStorage.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/CustomisationStorage.cs @@ -6,7 +6,7 @@ public record CustomisationStorage { // Customisation.json/itemId [JsonPropertyName("id")] - public string? Id + public string Id { get; set; diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs index 7647084f..c1db3aaa 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs @@ -24,8 +24,9 @@ public record SptProfile } /// - /// Clothing purchases + /// No longer used as of 4.0.0 /// + [Obsolete("Replaced with CustomisationUnlocks")] [JsonPropertyName("suits")] public List? Suits { @@ -95,6 +96,9 @@ public record SptProfile set; } + /// + /// Stores profile-related customisation, e.g. clothing / hideout walls / floors + /// [JsonPropertyName("customisationUnlocks")] public List? CustomisationUnlocks { diff --git a/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs b/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs index 0ac248e4..9752fa38 100644 --- a/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs @@ -43,10 +43,10 @@ public class CreateProfileService( public string CreateProfile(string sessionId, ProfileCreateRequestData request) { var account = _cloner.Clone(_saveServer.GetProfile(sessionId)); - var profileTemplate = _cloner.Clone( + var profileTemplateClone = _cloner.Clone( _databaseService.GetProfiles()?.GetByJsonProp(account.ProfileInfo.Edition)?.GetByJsonProp(request.Side.ToLower()) ); - var pmcData = profileTemplate.Character; + var pmcData = profileTemplateClone.Character; // Delete existing profile DeleteProfileBySessionId(sessionId); @@ -113,9 +113,8 @@ public class CreateProfileService( PmcData = pmcData, ScavData = new PmcData() }, - Suits = profileTemplate.Suits, - UserBuildData = profileTemplate.UserBuilds, - DialogueRecords = profileTemplate.Dialogues, + UserBuildData = profileTemplateClone.UserBuilds, + DialogueRecords = profileTemplateClone.Dialogues, SptData = _profileHelper.GetDefaultSptDataObject(), VitalityData = new Vitality(), InraidData = new Inraid(), @@ -127,6 +126,8 @@ public class CreateProfileService( AddCustomisationUnlocksToProfile(profileDetails); + _traderHelper.AddSuitsToProfile(profileDetails, profileTemplateClone.Suits); + _profileFixerService.CheckForAndFixPmcProfileIssues(profileDetails.CharacterData.PmcData); if (profileDetails.CharacterData.PmcData.Achievements.Count > 0) @@ -176,13 +177,13 @@ public class CreateProfileService( _saveServer.AddProfile(profileDetails); - if (profileTemplate.Trader.SetQuestsAvailableForStart ?? false) + if (profileTemplateClone.Trader.SetQuestsAvailableForStart ?? false) { _questHelper.AddAllQuestsToProfile(profileDetails.CharacterData.PmcData, [QuestStatusEnum.AvailableForStart]); } // Profile is flagged as wanting quests set to ready to hand in and collect rewards - if (profileTemplate.Trader.SetQuestsAvailableForFinish ?? false) + if (profileTemplateClone.Trader.SetQuestsAvailableForFinish ?? false) { _questHelper.AddAllQuestsToProfile( profileDetails.CharacterData.PmcData, diff --git a/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs b/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs index 29ec207e..21aae322 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs @@ -650,13 +650,18 @@ public class ProfileFixerService( } var clothingDb = _databaseService.GetTemplates().Customization; - foreach (var suitId in fullProfile.Suits.Where(suitId => !clothingDb.ContainsKey(suitId))) + foreach (var clothingItem in fullProfile.CustomisationUnlocks.Where(customisation => customisation.Type == CustomisationType.SUITE)) { - _logger.Error(_localisationService.GetText("fixer-clothing_item_found", suitId)); - if (_coreConfig.Fixes.RemoveModItemsFromProfile) + if (!clothingDb.ContainsKey(clothingItem.Id)) { - fullProfile.Suits.Remove(suitId); - _logger.Warning($"Non-default suit purchase: {suitId} removed from profile"); + // Item in profile not found in db, not good + _logger.Error(_localisationService.GetText("fixer-clothing_item_found", clothingItem)); + + if (_coreConfig.Fixes.RemoveModItemsFromProfile) + { + fullProfile.CustomisationUnlocks.Remove(clothingItem); + _logger.Warning($"Non-default clothing purchase: {clothingItem} removed from profile"); + } } }