From d64dc5d0403c15ad004bde3635b6e0d92672c061 Mon Sep 17 00:00:00 2001 From: Chomp Date: Tue, 14 Jan 2025 10:50:15 +0000 Subject: [PATCH] Expanded `PrestigeController` implementation --- Core/Callbacks/PrestigeCallbacks.cs | 9 +- Core/Controllers/PrestigeController.cs | 118 +++++++++++++++++- Core/Generators/PlayerScavGenerator.cs | 2 +- Core/Helpers/ProfileHelper.cs | 6 +- Core/Models/Eft/Common/Tables/BotBase.cs | 13 +- Core/Models/Eft/Common/Tables/BotType.cs | 10 +- .../Eft/Profile/ProfileCreateRequestData.cs | 3 + Core/Models/Eft/Profile/SptProfile.cs | 2 +- Core/Routers/EventOutputHolder.cs | 2 +- Core/Routers/Static/PrestigeStaticRouter.cs | 5 +- Core/Services/ProfileFixerService.cs | 2 +- 11 files changed, 147 insertions(+), 25 deletions(-) diff --git a/Core/Callbacks/PrestigeCallbacks.cs b/Core/Callbacks/PrestigeCallbacks.cs index 94c9225c..ae24e339 100644 --- a/Core/Callbacks/PrestigeCallbacks.cs +++ b/Core/Callbacks/PrestigeCallbacks.cs @@ -1,9 +1,10 @@ -using Core.Annotations; +using Core.Annotations; using Core.Controllers; using Core.Helpers; using Core.Models.Eft.Common; using Core.Models.Eft.Common.Tables; using Core.Models.Eft.HttpResponse; +using Core.Models.Eft.Prestige; using Core.Utils; namespace Core.Callbacks; @@ -48,8 +49,10 @@ public class PrestigeCallbacks /// /// /// - public string ObtainPrestige(string url, EmptyRequestData info, string sessionID) + public string ObtainPrestige(string url, List info, string sessionID) { - return _httpResponseUtil.GetBody(_prestigeController.ObtainPrestige(sessionID, info)); + _prestigeController.ObtainPrestige(sessionID, info); + + return _httpResponseUtil.NullResponse(); } } diff --git a/Core/Controllers/PrestigeController.cs b/Core/Controllers/PrestigeController.cs index 9cd9bf15..320c2aa8 100644 --- a/Core/Controllers/PrestigeController.cs +++ b/Core/Controllers/PrestigeController.cs @@ -1,21 +1,50 @@ using Core.Annotations; +using Core.Helpers; using Core.Models.Eft.Common; using Core.Models.Eft.Common.Tables; +using Core.Models.Eft.Inventory; +using Core.Models.Eft.Prestige; +using Core.Models.Eft.Profile; +using Core.Routers; using Core.Services; +using Core.Utils; +using Core.Utils.Cloners; +using ILogger = Core.Models.Utils.ILogger; namespace Core.Controllers; [Injectable] public class PrestigeController { + private readonly ILogger _logger; + private readonly TimeUtil _timeUtil; + private readonly InventoryHelper _inventoryHelper; + private readonly ProfileHelper _profileHelper; + private readonly EventOutputHolder _eventOutputHolder; + private readonly CreateProfileService _createProfileService; private DatabaseService _databaseService; + private readonly ICloner _cloner; public PrestigeController ( - DatabaseService databaseService + ILogger logger, + TimeUtil timeUtil, + InventoryHelper inventoryHelper, + ProfileHelper profileHelper, + EventOutputHolder eventOutputHolder, + CreateProfileService createProfileService, + DatabaseService databaseService, + ICloner cloner ) { + _logger = logger; + _timeUtil = timeUtil; + _inventoryHelper = inventoryHelper; + _profileHelper = profileHelper; + _eventOutputHolder = eventOutputHolder; + _createProfileService = createProfileService; _databaseService = databaseService; + _cloner = cloner; } /// @@ -35,12 +64,91 @@ public class PrestigeController /// Handle /client/prestige/obtain /// /// - /// + /// /// - public object ObtainPrestige( // TODO: returns `any` in the node server, not implemented either + public void ObtainPrestige( string sessionId, - EmptyRequestData info) + List request) { - throw new NotImplementedException("Method not Implemented"); + var prePrestigeProfileClone = _cloner.Clone(_profileHelper.GetFullProfile(sessionId)); + var prePrestigePmc = prePrestigeProfileClone.CharacterData.PmcData; + var createRequest = new ProfileCreateRequestData { + Side = prePrestigePmc.Info.Side, + Nickname = prePrestigePmc.Info.Nickname, + HeadId = prePrestigePmc.Customization.Head, + VoiceId = _databaseService.GetTemplates().Customization.FirstOrDefault( + (customisation) => customisation.Value.Name == prePrestigePmc.Info.Voice).Value.Id, + SptForcePrestigeLevel = prePrestigeProfileClone.CharacterData.PmcData.Info.PrestigeLevel.GetValueOrDefault(0) + 1, // Current + 1 + }; + + // Reset profile + _createProfileService.CreateProfile(sessionId, createRequest); + + // Get freshly reset profile ready for editing + var newProfile = _profileHelper.GetFullProfile(sessionId); + + // Skill copy + var commonSkillsToCopy = prePrestigePmc.Skills.Common; + foreach (var skillToCopy in commonSkillsToCopy) { + // Set progress to max level 20 + skillToCopy.Progress = Math.Min(skillToCopy.Progress.Value, 2000); + var existingSkill = newProfile.CharacterData.PmcData.Skills.Common.FirstOrDefault((skill) => skill.Id == skillToCopy.Id); + if (existingSkill is not null) + { + existingSkill.Progress = skillToCopy.Progress; + } + else + { + newProfile.CharacterData.PmcData.Skills.Common.Add(skillToCopy); + } + } + + var masteringSkillsToCopy = prePrestigePmc.Skills.Mastering; + foreach (var skillToCopy in masteringSkillsToCopy) { + // Set progress to max level 20 + skillToCopy.Progress = Math.Min(skillToCopy.Progress.Value, 2000); + var existingSkill = newProfile.CharacterData.PmcData.Skills.Mastering.FirstOrDefault( + (skill) => skill.Id == skillToCopy.Id); + if (existingSkill is not null) + { + existingSkill.Progress = skillToCopy.Progress; + } + else + { + newProfile.CharacterData.PmcData.Skills.Mastering.Add(skillToCopy); + } + } + + var indexToGet = Math.Min(createRequest.SptForcePrestigeLevel.Value - 1, 1); // Index starts at 0 + var rewards = _databaseService.GetTemplates().Prestige.Elements[indexToGet].Rewards; + AddPrestigeRewardsToProfile(sessionId, newProfile, rewards); + + // Copy transferred items + foreach (var transferRequest in request) { + var item = prePrestigePmc.Inventory.Items.FirstOrDefault((item) => item.Id == transferRequest.Id); + var addItemRequest = new AddItemDirectRequest { + ItemWithModsToAdd = [item], + FoundInRaid = item.Upd?.SpawnedInSession, + UseSortingTable = false, + Callback = null, + }; + _inventoryHelper.AddItemToStash( + sessionId, + addItemRequest, + newProfile.CharacterData.PmcData, + _eventOutputHolder.GetOutput(sessionId)); + } + + // Add "Prestigious" achievement + if (!newProfile.PlayerAchievements.ContainsKey("676091c0f457869a94017a23")) + { + newProfile.PlayerAchievements.Add("676091c0f457869a94017a23", _timeUtil.GetTimeStamp()); + } } + + private void AddPrestigeRewardsToProfile(string sessionId, SptProfile newProfile, IEnumerable rewards) + { + _logger.Error("NOT IMPLEMENTED AddPrestigeRewardsToProfile()"); + } + } diff --git a/Core/Generators/PlayerScavGenerator.cs b/Core/Generators/PlayerScavGenerator.cs index 5dc5cac2..78d927ff 100644 --- a/Core/Generators/PlayerScavGenerator.cs +++ b/Core/Generators/PlayerScavGenerator.cs @@ -305,7 +305,7 @@ public class PlayerScavGenerator { return new() { - Common = new(new(), new()), + Common = new(), Mastering = new (), Points = 0 }; diff --git a/Core/Helpers/ProfileHelper.cs b/Core/Helpers/ProfileHelper.cs index da486721..8de4d0dd 100644 --- a/Core/Helpers/ProfileHelper.cs +++ b/Core/Helpers/ProfileHelper.cs @@ -445,7 +445,7 @@ public class ProfileHelper if (profileSkills == null) return false; - var profileSkill = profileSkills.Dictionary.FirstOrDefault(s => s.Value.Id == skill.ToString()).Value; + var profileSkill = profileSkills.FirstOrDefault(s => s.Id == skill.ToString()); if (profileSkill == null) { _logger.Error(_localisationService.GetText("quest-no_skill_found", skill)); @@ -479,7 +479,7 @@ public class ProfileHelper return; } - var profileSkill = profileSkills.Dictionary.FirstOrDefault(s => s.Value.Id == skill.ToString()).Value; + var profileSkill = profileSkills.FirstOrDefault(s => s.Id == skill.ToString()); if (profileSkill == null) { _logger.Error(_localisationService.GetText("quest-no_skill_found", skill)); @@ -508,7 +508,7 @@ public class ProfileHelper /// Common skill object from desired profile public Common? GetSkillFromProfile(PmcData pmcData, SkillTypes skill) { - var skillToReturn = pmcData?.Skills?.Common.List.FirstOrDefault(s => s.Id == skill.ToString()); + var skillToReturn = pmcData?.Skills?.Common.FirstOrDefault(s => s.Id == skill.ToString()); if (skillToReturn == null) _logger.Warning($"Profile {pmcData.SessionId} does not have a skill named: {skill.ToString()}"); diff --git a/Core/Models/Eft/Common/Tables/BotBase.cs b/Core/Models/Eft/Common/Tables/BotBase.cs index f76911fa..a5e36ece 100644 --- a/Core/Models/Eft/Common/Tables/BotBase.cs +++ b/Core/Models/Eft/Common/Tables/BotBase.cs @@ -184,7 +184,7 @@ public class Info [JsonPropertyName("isMigratedSkills")] public bool? IsMigratedSkills { get; set; } - public double? PrestigeLevel { get; set; } + public int? PrestigeLevel { get; set; } } public class BotInfoSettings @@ -291,17 +291,18 @@ public class BotBaseInventory public class BaseJsonSkills { - public Dictionary? Common { get; set; } - public Dictionary? Mastering { get; set; } + public List? Common { get; set; } + + + public List? Mastering { get; set; } public double? Points { get; set; } } public class Skills { - public DictionaryOrList? Common { get; set; } + public List? Common { get; set; } - [JsonConverter(typeof(ArrayToObjectFactoryConverter))] - public Dictionary? Mastering { get; set; } + public List? Mastering { get; set; } public double? Points { get; set; } } diff --git a/Core/Models/Eft/Common/Tables/BotType.cs b/Core/Models/Eft/Common/Tables/BotType.cs index 83268791..8bc1b3af 100644 --- a/Core/Models/Eft/Common/Tables/BotType.cs +++ b/Core/Models/Eft/Common/Tables/BotType.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Text.Json.Serialization; using Core.Models.Common; using Core.Utils.Json.Converters; @@ -35,7 +34,7 @@ public class BotType public List? LastNames { get; set; } [JsonPropertyName("skills")] - public Skills? BotSkills { get; set; } + public BotDbSkills? BotSkills { get; set; } } public class Appearance @@ -370,3 +369,10 @@ public class ItemPools public Dictionary? SpecialLoot { get; set; } public Dictionary? TacticalVest { get; set; } } + +public class BotDbSkills +{ + public Dictionary? Common { get; set; } + + public Dictionary? Mastering { get; set; } +} diff --git a/Core/Models/Eft/Profile/ProfileCreateRequestData.cs b/Core/Models/Eft/Profile/ProfileCreateRequestData.cs index 92dfe29e..ef52e2c0 100644 --- a/Core/Models/Eft/Profile/ProfileCreateRequestData.cs +++ b/Core/Models/Eft/Profile/ProfileCreateRequestData.cs @@ -16,4 +16,7 @@ public class ProfileCreateRequestData : IRequestData [JsonPropertyName("voiceId")] public string? VoiceId { get; set; } + + [JsonPropertyName("sptForcePrestigeLevel")] + public int? SptForcePrestigeLevel { get; set; } } diff --git a/Core/Models/Eft/Profile/SptProfile.cs b/Core/Models/Eft/Profile/SptProfile.cs index ced6c391..c82cb010 100644 --- a/Core/Models/Eft/Profile/SptProfile.cs +++ b/Core/Models/Eft/Profile/SptProfile.cs @@ -42,7 +42,7 @@ public class SptProfile /** Achievements earned by player */ [JsonPropertyName("achievements")] - public Dictionary? PlayerAchievements { get; set; } + public Dictionary? PlayerAchievements { get; set; } /** List of friend profile IDs */ [JsonPropertyName("friends")] diff --git a/Core/Routers/EventOutputHolder.cs b/Core/Routers/EventOutputHolder.cs index e9cb5851..c1667bc1 100644 --- a/Core/Routers/EventOutputHolder.cs +++ b/Core/Routers/EventOutputHolder.cs @@ -63,7 +63,7 @@ public class EventOutputHolder Items = new ItemChanges(){ NewItems = [], ChangedItems = [], DeletedItems = []}, Production = new Dictionary(), Improvements = new Dictionary(), - Skills = new Skills{ Common = new DictionaryOrList(null, []), Mastering = new Dictionary(), Points = 0}, + Skills = new Skills{ Common = [], Mastering = [], Points = 0}, Health = _cloner.Clone(pmcProfile.Health), TraderRelations = new Dictionary(), RecipeUnlocked = {}, diff --git a/Core/Routers/Static/PrestigeStaticRouter.cs b/Core/Routers/Static/PrestigeStaticRouter.cs index 796eb39f..2fe7dc98 100644 --- a/Core/Routers/Static/PrestigeStaticRouter.cs +++ b/Core/Routers/Static/PrestigeStaticRouter.cs @@ -1,7 +1,8 @@ -using Core.Annotations; +using Core.Annotations; using Core.Callbacks; using Core.DI; using Core.Models.Eft.Common; +using Core.Models.Eft.Prestige; using Core.Utils; namespace Core.Routers.Static; @@ -32,7 +33,7 @@ public class PrestigeStaticRouter : StaticRouter info, sessionID, output - ) => _presetCallbacks.ObtainPrestige(url, info as EmptyRequestData, sessionID)) + ) => _presetCallbacks.ObtainPrestige(url, info as List, sessionID)) ] ) { diff --git a/Core/Services/ProfileFixerService.cs b/Core/Services/ProfileFixerService.cs index e5abd9bd..90cde9a5 100644 --- a/Core/Services/ProfileFixerService.cs +++ b/Core/Services/ProfileFixerService.cs @@ -457,7 +457,7 @@ public class ProfileFixerService { var skills = pmcProfile.Skills.Common; - foreach (var skill in skills.List + foreach (var skill in skills .Where(skill => skill.Progress > 5100)) { skill.Progress = 5100;