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;