From 61ebc570e4403bccb3e3206d8fa3593881304cef Mon Sep 17 00:00:00 2001 From: Chomp Date: Sun, 12 Jan 2025 23:15:55 +0000 Subject: [PATCH] Added `CreateProfileService` Implementation --- Core/Controllers/ProfileController.cs | 249 +----------- .../Eft/Common/Tables/CustomisationStorage.cs | 32 +- Core/Models/Eft/Profile/SptProfile.cs | 5 +- Core/Services/CreateProfileService.cs | 355 ++++++++++++++++-- 4 files changed, 361 insertions(+), 280 deletions(-) diff --git a/Core/Controllers/ProfileController.cs b/Core/Controllers/ProfileController.cs index 3bcf627d..26c70203 100644 --- a/Core/Controllers/ProfileController.cs +++ b/Core/Controllers/ProfileController.cs @@ -2,8 +2,6 @@ using Core.Annotations; using Core.Generators; using Core.Helpers; using Core.Models.Eft.Common; -using Core.Models.Eft.Common.Tables; -using Core.Models.Eft.ItemEvent; using Core.Models.Eft.Launcher; using Core.Models.Eft.Profile; using Core.Models.Enums; @@ -28,6 +26,7 @@ public class ProfileController protected ItemHelper _itemHelper; protected ProfileFixerService _profileFixerService; protected LocalisationService _localisationService; + private readonly CreateProfileService _createProfileService; protected SeasonalEventService _seasonalEventService; @@ -51,6 +50,7 @@ public class ProfileController ItemHelper itemHelper, ProfileFixerService profileFixerService, LocalisationService localisationService, + CreateProfileService createProfileService, SeasonalEventService seasonalEventService, // TODO: MailSendService mailSendService, PlayerScavGenerator playerScavGenerator, @@ -71,6 +71,7 @@ public class ProfileController _itemHelper = itemHelper; _profileFixerService = profileFixerService; _localisationService = localisationService; + _createProfileService = createProfileService; _seasonalEventService = seasonalEventService; _playerScavGenerator = playerScavGenerator; _eventOutputHolder = eventOutputHolder; @@ -154,249 +155,9 @@ public class ProfileController * @param sessionID Player id * @returns Profiles _id value */ - public string CreateProfile(ProfileCreateRequestData info, string sessionID) + public string CreateProfile(ProfileCreateRequestData request, string sessionID) { - var account = _saveServer.GetProfile(sessionID).ProfileInfo; - var profileTemplate = _cloner.Clone(_databaseService.GetProfiles()?[account.Edition]?[info.Side.ToLower()]); - var pmcData = profileTemplate.Character; - - // Delete existing profile - DeleteProfileBySessionId(sessionID); - // PMC - pmcData.Id = account.ProfileId; - pmcData.Aid = account.Aid; - pmcData.Savage = account.ScavengerId; - pmcData.SessionId = sessionID; - pmcData.Info.Nickname = info.Nickname; - pmcData.Info.LowerNickname = account.Username.ToLower(); - pmcData.Info.RegistrationDate = _timeUtil.GetTimeStamp(); - pmcData.Info.Voice = _databaseService.GetCustomization()[info.VoiceId].Name; - pmcData.Stats = _profileHelper.GetDefaultCounters(); - pmcData.Info.NeedWipeOptions = []; - pmcData.Customization.Head = info.HeadId; - pmcData.Health.UpdateTime = _timeUtil.GetTimeStamp(); - pmcData.Quests = []; - pmcData.Hideout.Seed = _timeUtil.GetTimeStamp() + 8 * 60 * 60 * 24 * 365; // 8 years in future why? who knows, we saw it in live - pmcData.RepeatableQuests = []; - pmcData.CarExtractCounts = new(); - pmcData.CoopExtractCounts = new(); - pmcData.Achievements = new(); - - UpdateInventoryEquipmentId(pmcData); - - if (pmcData.UnlockedInfo == null) - { - pmcData.UnlockedInfo = new UnlockedInfo { UnlockedProductionRecipe = [] }; - } - - // Add required items to pmc stash - AddMissingInternalContainersToProfile(pmcData); - - // Change item IDs to be unique - pmcData.Inventory.Items = _itemHelper.ReplaceIDs( - pmcData.Inventory.Items, - pmcData, - null, - pmcData.Inventory.FastPanel - ); - - // Create profile - var profileDetails = new SptProfile - { - ProfileInfo = account, - CharacterData = new Characters { PmcData = pmcData, ScavData = new() }, - Suits = profileTemplate.Suits, - UserBuildData = profileTemplate.UserBuilds, - DialogueRecords = profileTemplate.Dialogues, - SptData = _profileHelper.GetDefaultSptDataObject(), - VitalityData = new(), - InraidData = new(), - InsuranceList = [], - TraderPurchases = new(), - PlayerAchievements = new(), - FriendProfileIds = [], - }; - - _profileFixerService.CheckForAndFixPmcProfileIssues(profileDetails.CharacterData.PmcData); - - _saveServer.AddProfile(profileDetails); - - if (profileTemplate.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) - { - _questHelper.AddAllQuestsToProfile(profileDetails.CharacterData.PmcData, [ - QuestStatusEnum.AvailableForStart, - QuestStatusEnum.Started, - QuestStatusEnum.AvailableForFinish, - ]); - - // Make unused response so applyQuestReward works - ItemEventRouterResponse? response = _eventOutputHolder.GetOutput(sessionID); - - // Add rewards for starting quests to profile - GivePlayerStartingQuestRewards(profileDetails, sessionID, response); - } - - ResetAllTradersInProfile(sessionID); - - _saveServer.GetProfile(sessionID).CharacterData.ScavData = GeneratePlayerScav(sessionID); - - // Store minimal profile and reload it - _saveServer.SaveProfile(sessionID); - _saveServer.LoadProfile(sessionID); - - // Completed account creation - _saveServer.GetProfile(sessionID).ProfileInfo.IsWiped = false; - _saveServer.SaveProfile(sessionID); - - return pmcData.Id; - } - - /** - * make profiles pmcData.Inventory.equipment unique - * @param pmcData Profile to update - */ - protected void UpdateInventoryEquipmentId(PmcData pmcData) - { - var oldEquipmentId = pmcData.Inventory.Equipment; - pmcData.Inventory.Equipment = _hashUtil.Generate(); - - foreach (var item in pmcData.Inventory.Items) - { - if (item.ParentId == oldEquipmentId) - { - item.ParentId = pmcData.Inventory.Equipment; - continue; - } - - if (item.Id == oldEquipmentId) - { - item.Id = pmcData.Inventory.Equipment; - } - } - } - - /** - * Ensure a profile has the necessary internal containers e.g. questRaidItems / sortingTable - * DOES NOT check that stash exists - * @param pmcData Profile to check - */ - protected void AddMissingInternalContainersToProfile(PmcData pmcData) - { - if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.HideoutCustomizationStashId)) - { - pmcData.Inventory.Items.Add(new() - { - Id = pmcData.Inventory.HideoutCustomizationStashId, - Template = ItemTpl.HIDEOUTAREACONTAINER_CUSTOMIZATION, - }); - } - - if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.SortingTable)) - { - pmcData.Inventory.Items.Add(new() - { - Id = pmcData.Inventory.SortingTable, - Template = ItemTpl.SORTINGTABLE_SORTING_TABLE, - }); - } - - if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.QuestStashItems)) - { - pmcData.Inventory.Items.Add(new() - { - Id = pmcData.Inventory.QuestStashItems, - Template = ItemTpl.STASH_QUESTOFFLINE, - }); - } - - if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.QuestRaidItems)) - { - pmcData.Inventory.Items.Add(new() - { - Id = pmcData.Inventory.QuestRaidItems, - Template = ItemTpl.STASH_QUESTRAID, - }); - } - } - - /** - * Delete a profile - * @param sessionID Id of profile to delete - */ - protected void DeleteProfileBySessionId(string sessionID) - { - if (_saveServer.GetProfiles().ContainsKey(sessionID)) - { - _saveServer.DeleteProfileById(sessionID); - } - else - { - _logger.Warning( - _localisationService.GetText("profile-unable_to_find_profile_by_id_cannot_delete", sessionID) - ); - } - } - - /** - * Iterate over all quests in player profile, inspect rewards for the quests current state (accepted/completed) - * and send rewards to them in mail - * @param profileDetails Player profile - * @param sessionID Session id - * @param response Event router response - */ - protected void GivePlayerStartingQuestRewards( - SptProfile profileDetails, - string sessionID, - ItemEventRouterResponse response - ) - { - foreach (var quest in profileDetails.CharacterData.PmcData.Quests) - { - var questFromDb = _questHelper.GetQuestFromDb(quest.QId, profileDetails.CharacterData.PmcData); - - // Get messageId of text to send to player as text message in game - // Copy of code from QuestController.acceptQuest() - var messageId = _questHelper.GetMessageIdForQuestStart( - questFromDb.StartedMessageText, - questFromDb.Description - ); - var itemRewards = _questRewardHelper.ApplyQuestReward( - profileDetails.CharacterData.PmcData, - quest.QId, - QuestStatusEnum.Started, - sessionID, - response - ); - - /* TODO: - _mailSendService.sendLocalisedNpcMessageToPlayer( - sessionID, - this.traderHelper.getTraderById(questFromDb.traderId), - MessageType.QUEST_START, - messageId, - itemRewards, - this.timeUtil.getHoursAsSeconds(100), - ); - */ - } - } - - /** - * For each trader reset their state to what a level 1 player would see - * @param sessionId Session id of profile to reset - */ - protected void ResetAllTradersInProfile(string sessionId) - { - foreach (var traderId in _databaseService.GetTraders().Keys) - { - _traderHelper.ResetTrader(sessionId, traderId); - } + return _createProfileService.CreateProfile(sessionID, request); } /** diff --git a/Core/Models/Eft/Common/Tables/CustomisationStorage.cs b/Core/Models/Eft/Common/Tables/CustomisationStorage.cs index f7394921..122bc7bc 100644 --- a/Core/Models/Eft/Common/Tables/CustomisationStorage.cs +++ b/Core/Models/Eft/Common/Tables/CustomisationStorage.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Core.Models.Eft.Common.Tables; @@ -12,4 +12,32 @@ public class CustomisationStorage [JsonPropertyName("type")] public string? Type { get; set; } -} \ No newline at end of file +} + +public class CustomisationType +{ + public const string SUITE = "suite"; + public const string DOG_TAG = "dogTag"; + public const string HEAD = "head"; + public const string VOICE = "voice"; + public const string GESTURE = "gesture"; + public const string ENVIRONMENT = "environment"; + public const string WALL = "wall"; + public const string FLOOR = "floor"; + public const string CEILING = "ceiling"; + public const string LIGHT = "light"; + public const string SHOOTING_RANGE_MARK = "shootingRangeMark"; + public const string CAT = "cat"; + public const string MANNEQUIN_POSE = "mannequinPose"; +} + +public class CustomisationSource +{ + public const string QUEST = "quest"; + public const string PRESTIGE = "prestige"; + public const string ACHIEVEMENT = "achievement"; + public const string UNLOCKED_IN_GAME = "unlockedInGame"; + public const string PAID = "paid"; + public const string DROP = "drop"; + public const string DEFAULT = "default"; +} diff --git a/Core/Models/Eft/Profile/SptProfile.cs b/Core/Models/Eft/Profile/SptProfile.cs index 44ff731e..ced6c391 100644 --- a/Core/Models/Eft/Profile/SptProfile.cs +++ b/Core/Models/Eft/Profile/SptProfile.cs @@ -1,4 +1,4 @@ -using Core.Models.Eft.Common; +using Core.Models.Eft.Common; using System.Text.Json.Serialization; using Core.Models.Eft.Common.Tables; using Core.Models.Enums; @@ -47,6 +47,9 @@ public class SptProfile /** List of friend profile IDs */ [JsonPropertyName("friends")] public List? FriendProfileIds { get; set; } + + [JsonPropertyName("customisationUnlocks")] + public List CustomisationUnlocks { get; set; } } public class TraderPurchaseData diff --git a/Core/Services/CreateProfileService.cs b/Core/Services/CreateProfileService.cs index 9c3f8410..d53a4188 100644 --- a/Core/Services/CreateProfileService.cs +++ b/Core/Services/CreateProfileService.cs @@ -10,78 +10,335 @@ using ILogger = Core.Models.Utils.ILogger; using Core.Models.Eft.Common; using Core.Models.Eft.Common.Tables; using Core.Models.Eft.ItemEvent; +using Core.Models.Enums; +using Core.Routers; [Injectable] public class CreateProfileService { private readonly ILogger _logger; private readonly TimeUtil _timeUtil; + private readonly HashUtil _hashUtil; private readonly DatabaseService _databaseService; + private readonly LocalisationService _localisationService; + private readonly ProfileHelper _profileHelper; + private readonly ItemHelper _itemHelper; + private readonly TraderHelper _traderHelper; + private readonly QuestHelper _questHelper; + private readonly QuestRewardHelper _questRewardHelper; + private readonly ProfileFixerService _profileFixerService; private readonly SaveServer _saveServer; + private readonly EventOutputHolder _eventOutputHolder; + private readonly PlayerScavGenerator _playerScavGenerator; private readonly ICloner _cloner; public CreateProfileService( ILogger logger, TimeUtil timeUtil, + HashUtil hashUtil, DatabaseService databaseService, - TraderAssortHelper traderAssortHelper, - TraderAssortService traderAssortService, + LocalisationService localisationService, ProfileHelper profileHelper, + ItemHelper itemHelper, TraderHelper traderHelper, - PaymentHelper paymentHelper, - RagfairPriceService ragfairPriceService, - TraderPurchasePersisterService traderPurchasePersisterService, - FenceBaseAssortGenerator fenceBaseAssortGenerator, - ConfigServer configServer, + QuestHelper questHelper, + QuestRewardHelper questRewardHelper, + ProfileFixerService profileFixerService, SaveServer saveServer, + EventOutputHolder eventOutputHolder, + PlayerScavGenerator playerScavGenerator, ICloner cloner) { _logger = logger; _timeUtil = timeUtil; + _hashUtil = hashUtil; _databaseService = databaseService; + _localisationService = localisationService; + _profileHelper = profileHelper; + _itemHelper = itemHelper; + _traderHelper = traderHelper; + _questHelper = questHelper; + _questRewardHelper = questRewardHelper; + _profileFixerService = profileFixerService; _saveServer = saveServer; + _eventOutputHolder = eventOutputHolder; + _playerScavGenerator = playerScavGenerator; _cloner = cloner; } - public string CreateProfile(string sessionID, ProfileCreateRequestData request) + public string CreateProfile(string sessionId, ProfileCreateRequestData request) { - var account = _saveServer.GetProfile(sessionID).ProfileInfo; - var profileTemplateClone = - _cloner.Clone(_databaseService.GetProfiles()[account.Edition][request.Side.ToLower()]); - var pmcData = profileTemplateClone.Character; + var account = _saveServer.GetProfile(sessionId).ProfileInfo; + var profileTemplate = _cloner.Clone(_databaseService.GetProfiles()?[account.Edition]?[request.Side.ToLower()]); + var pmcData = profileTemplate.Character; // Delete existing profile - DeleteProfileBySessionId(sessionID); - } + DeleteProfileBySessionId(sessionId); + // PMC + pmcData.Id = account.ProfileId; + pmcData.Aid = account.Aid; + pmcData.Savage = account.ScavengerId; + pmcData.SessionId = sessionId; + pmcData.Info.Nickname = request.Nickname; + pmcData.Info.LowerNickname = account.Username.ToLower(); + pmcData.Info.RegistrationDate = _timeUtil.GetTimeStamp(); + pmcData.Info.Voice = _databaseService.GetCustomization()[request.VoiceId].Name; + pmcData.Stats = _profileHelper.GetDefaultCounters(); + pmcData.Info.NeedWipeOptions = []; + pmcData.Customization.Head = request.HeadId; + pmcData.Health.UpdateTime = _timeUtil.GetTimeStamp(); + pmcData.Quests = []; + pmcData.Hideout.Seed = _timeUtil.GetTimeStamp() + 8 * 60 * 60 * 24 * 365; // 8 years in future why? who knows, we saw it in live + pmcData.RepeatableQuests = []; + pmcData.CarExtractCounts = new(); + pmcData.CoopExtractCounts = new(); + pmcData.Achievements = new(); - private void DeleteProfileBySessionId(string sessionId) - { + UpdateInventoryEquipmentId(pmcData); - } + if (pmcData.UnlockedInfo == null) + { + pmcData.UnlockedInfo = new UnlockedInfo { UnlockedProductionRecipe = [] }; + } - private void UpdateInventoryEquipmentId(PmcData pmcData) - { + // Add required items to pmc stash + AddMissingInternalContainersToProfile(pmcData); - } + // Change item IDs to be unique + pmcData.Inventory.Items = _itemHelper.ReplaceIDs( + pmcData.Inventory.Items, + pmcData, + null, + pmcData.Inventory.FastPanel + ); - private void ResetAllTradersInProfile(string sessionId) - { + // Create profile + var profileDetails = new SptProfile + { + ProfileInfo = account, + CharacterData = new Characters { PmcData = pmcData, ScavData = new() }, + Suits = profileTemplate.Suits, + UserBuildData = profileTemplate.UserBuilds, + DialogueRecords = profileTemplate.Dialogues, + SptData = _profileHelper.GetDefaultSptDataObject(), + VitalityData = new(), + InraidData = new(), + InsuranceList = [], + TraderPurchases = new(), + PlayerAchievements = new(), + FriendProfileIds = [], + CustomisationUnlocks = [] + }; + AddCustomisationUnlocksToProfile(profileDetails); + + _profileFixerService.CheckForAndFixPmcProfileIssues(profileDetails.CharacterData.PmcData); + + _saveServer.AddProfile(profileDetails); + + if (profileTemplate.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) + { + _questHelper.AddAllQuestsToProfile(profileDetails.CharacterData.PmcData, [ + QuestStatusEnum.AvailableForStart, + QuestStatusEnum.Started, + QuestStatusEnum.AvailableForFinish, + ]); + + // Make unused response so applyQuestReward works + ItemEventRouterResponse? response = _eventOutputHolder.GetOutput(sessionId); + + // Add rewards for starting quests to profile + GivePlayerStartingQuestRewards(profileDetails, sessionId, response); + } + + ResetAllTradersInProfile(sessionId); + + _saveServer.GetProfile(sessionId).CharacterData.ScavData = _playerScavGenerator.Generate(sessionId); + + // Store minimal profile and reload it + _saveServer.SaveProfile(sessionId); + _saveServer.LoadProfile(sessionId); + + // Completed account creation + _saveServer.GetProfile(sessionId).ProfileInfo.IsWiped = false; + _saveServer.SaveProfile(sessionId); + + return pmcData.Id; } /** - * Ensure a profile has the necessary internal containers e.g. questRaidItems / sortingTable - * DOES NOT check that stash exists - * @param pmcData Profile to check + * Delete a profile + * @param sessionID Id of profile to delete */ - private void AddMissingInternalContainersToProfile(PmcData pmcData) + protected void DeleteProfileBySessionId(string sessionID) { + if (_saveServer.GetProfiles().ContainsKey(sessionID)) + { + _saveServer.DeleteProfileById(sessionID); + } + else + { + _logger.Warning( + _localisationService.GetText("profile-unable_to_find_profile_by_id_cannot_delete", sessionID) + ); + } + } + /** + * make profiles pmcData.Inventory.equipment unique + * @param pmcData Profile to update + */ + protected void UpdateInventoryEquipmentId(PmcData pmcData) + { + var oldEquipmentId = pmcData.Inventory.Equipment; + pmcData.Inventory.Equipment = _hashUtil.Generate(); + + foreach (var item in pmcData.Inventory.Items) + { + if (item.ParentId == oldEquipmentId) + { + item.ParentId = pmcData.Inventory.Equipment; + continue; + } + + if (item.Id == oldEquipmentId) + { + item.Id = pmcData.Inventory.Equipment; + } + } + } + + /** + * For each trader reset their state to what a level 1 player would see + * @param sessionId Session id of profile to reset + */ + protected void ResetAllTradersInProfile(string sessionId) + { + foreach (var traderId in _databaseService.GetTraders().Keys) + { + _traderHelper.ResetTrader(sessionId, traderId); + } + } + + /** + * Ensure a profile has the necessary internal containers e.g. questRaidItems / sortingTable + * DOES NOT check that stash exists + * @param pmcData Profile to check + */ + protected void AddMissingInternalContainersToProfile(PmcData pmcData) + { + if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.HideoutCustomizationStashId)) + { + pmcData.Inventory.Items.Add(new() + { + Id = pmcData.Inventory.HideoutCustomizationStashId, + Template = ItemTpl.HIDEOUTAREACONTAINER_CUSTOMIZATION, + }); + } + + if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.SortingTable)) + { + pmcData.Inventory.Items.Add(new() + { + Id = pmcData.Inventory.SortingTable, + Template = ItemTpl.SORTINGTABLE_SORTING_TABLE, + }); + } + + if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.QuestStashItems)) + { + pmcData.Inventory.Items.Add(new() + { + Id = pmcData.Inventory.QuestStashItems, + Template = ItemTpl.STASH_QUESTOFFLINE, + }); + } + + if (!pmcData.Inventory.Items.Any((item) => item.Id == pmcData.Inventory.QuestRaidItems)) + { + pmcData.Inventory.Items.Add(new() + { + Id = pmcData.Inventory.QuestRaidItems, + Template = ItemTpl.STASH_QUESTRAID, + }); + } } private void AddCustomisationUnlocksToProfile(SptProfile fullProfile) { + // Some game versions have additional dogtag variants, add them + switch (GetGameEdition(fullProfile)) + { + case GameEditions.EDGE_OF_DARKNESS: + // Gets EoD tags + fullProfile.CustomisationUnlocks.Add( new CustomisationStorage { + Id = "6746fd09bafff85008048838", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "67471938bafff850080488b7", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + + break; + case GameEditions.UNHEARD: + // Gets EoD+Unheard tags + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "6746fd09bafff85008048838", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "67471938bafff850080488b7", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "67471928d17d6431550563b5", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "6747193f170146228c0d2226", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + break; + } + + var pretigeLevel = fullProfile?.CharacterData?.PmcData?.Info?.PrestigeLevel; + if (pretigeLevel is not null) + { + if (pretigeLevel >= 1) + { + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "674dbf593bee1152d407f005", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + } + + if (pretigeLevel >= 2) + { + fullProfile.CustomisationUnlocks.Add(new CustomisationStorage { + Id = "675dcfea7ae1a8792107ca99", + Source = CustomisationSource.DEFAULT, + Type = CustomisationType.DOG_TAG, + }); + } + } } private string GetGameEdition(SptProfile profile) @@ -90,14 +347,46 @@ public class CreateProfileService } /** - * Iterate over all quests in player profile, inspect rewards for the quests current state (accepted/completed) - * and send rewards to them in mail - * @param profileDetails Player profile - * @param sessionID Session id - * @param response Event router response - */ - private void GivePlayerStartingQuestRewards( SptProfile fullProfile, string sessionId, ItemEventRouterResponse response) + * Iterate over all quests in player profile, inspect rewards for the quests current state (accepted/completed) + * and send rewards to them in mail + * @param profileDetails Player profile + * @param sessionID Session id + * @param response Event router response + */ + protected void GivePlayerStartingQuestRewards( + SptProfile profileDetails, + string sessionID, + ItemEventRouterResponse response + ) { + foreach (var quest in profileDetails.CharacterData.PmcData.Quests) + { + var questFromDb = _questHelper.GetQuestFromDb(quest.QId, profileDetails.CharacterData.PmcData); + // Get messageId of text to send to player as text message in game + // Copy of code from QuestController.acceptQuest() + var messageId = _questHelper.GetMessageIdForQuestStart( + questFromDb.StartedMessageText, + questFromDb.Description + ); + var itemRewards = _questRewardHelper.ApplyQuestReward( + profileDetails.CharacterData.PmcData, + quest.QId, + QuestStatusEnum.Started, + sessionID, + response + ); + + /* TODO: + _mailSendService.sendLocalisedNpcMessageToPlayer( + sessionID, + this.traderHelper.getTraderById(questFromDb.traderId), + MessageType.QUEST_START, + messageId, + itemRewards, + this.timeUtil.getHoursAsSeconds(100), + ); + */ + } } }