diff --git a/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs b/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs
index 21bf90ab..1b6ffb44 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/LauncherController.cs
@@ -1,4 +1,3 @@
-using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Helpers;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
@@ -38,43 +37,30 @@ public class LauncherController(
public ConnectResponse Connect()
{
// Get all possible profile types + filter out any that are blacklisted
-
- var profiles = typeof(ProfileTemplates).GetProperties()
- .Where(p => p.CanWrite)
- .Select(p => p.GetJsonName())
- .Where(profileName => !_coreConfig.Features.CreateNewProfileTypesBlacklist.Contains(profileName))
- .ToList();
+ var profileTemplates = _databaseService.GetProfileTemplates()
+ .Where(profile => !_coreConfig.Features.CreateNewProfileTypesBlacklist.Contains(profile.Key))
+ .ToDictionary();
return new ConnectResponse
{
BackendUrl = _httpServerHelper.GetBackendUrl(),
Name = _coreConfig.ServerName,
- Editions = profiles,
- ProfileDescriptions = GetProfileDescriptions()
+ Editions = profileTemplates.Select(x => x.Key).ToList(),
+ ProfileDescriptions = GetProfileDescriptions(profileTemplates)
};
}
///
/// Get descriptive text for each of the profile editions a player can choose, keyed by profile.json profile type e.g. "Edge Of Darkness"
///
+ /// Profiles to get descriptions of
/// Dictionary of profile types with related descriptive text
- protected Dictionary GetProfileDescriptions()
+ protected Dictionary GetProfileDescriptions(Dictionary profileTemplates)
{
var result = new Dictionary();
- var dbProfiles = _databaseService.GetProfiles();
- foreach (var templatesProperty in typeof(ProfileTemplates).GetProperties()
- .Where(p => p.CanWrite
- && !string.Equals(p.Name, "extensiondata", StringComparison.InvariantCultureIgnoreCase)))
+ foreach (var (profileKey, profile) in profileTemplates)
{
- var propertyValue = templatesProperty.GetValue(dbProfiles);
- if (propertyValue == null)
- {
- _logger.Warning(_localisationService.GetText("launcher-missing_property", templatesProperty.Name));
- continue;
- }
-
- var casterPropertyValue = propertyValue as ProfileSides;
- result[templatesProperty.GetJsonName()] = _localisationService.GetText(casterPropertyValue?.DescriptionLocaleKey!);
+ result.TryAdd(profileKey, _localisationService.GetText(profile.DescriptionLocaleKey));
}
return result;
diff --git a/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs b/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs
index 9e8a69df..9d5ea553 100644
--- a/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs
+++ b/Libraries/SPTarkov.Server.Core/Controllers/LauncherV2Controller.cs
@@ -1,6 +1,4 @@
-using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
-using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Launcher;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Models.Spt.Config;
@@ -46,21 +44,11 @@ public class LauncherV2Controller(
public Dictionary Types()
{
var result = new Dictionary();
- var dbProfiles = _databaseService.GetProfiles();
+ var dbProfiles = _databaseService.GetProfileTemplates();
- foreach (var templatesProperty in typeof(ProfileTemplates).GetProperties()
- .Where(p => p.CanWrite
- && !string.Equals(p.Name, "extensiondata", StringComparison.InvariantCultureIgnoreCase)))
+ foreach (var profileKvP in dbProfiles)
{
- var propertyValue = templatesProperty.GetValue(dbProfiles);
- if (propertyValue == null)
- {
- _logger.Warning(_localisationService.GetText("launcher-missing_property", templatesProperty.Name));
- continue;
- }
-
- var casterPropertyValue = propertyValue as ProfileSides;
- result[templatesProperty.GetJsonName()] = _localisationService.GetText(casterPropertyValue?.DescriptionLocaleKey!);
+ result.TryAdd(profileKvP.Key, _localisationService.GetText(profileKvP.Value.DescriptionLocaleKey));
}
return result;
diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs
index aa91c8e3..8470b119 100644
--- a/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs
+++ b/Libraries/SPTarkov.Server.Core/Helpers/HealthHelper.cs
@@ -1,11 +1,9 @@
-using SPTarkov.Common.Extensions;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Models.Eft.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Eft.Profile;
using SPTarkov.Server.Core.Models.Spt.Config;
using SPTarkov.Server.Core.Servers;
-using SPTarkov.Server.Core.Services;
using SPTarkov.Server.Core.Utils;
using BodyPartHealth = SPTarkov.Server.Core.Models.Eft.Common.Tables.BodyPartHealth;
using Vitality = SPTarkov.Server.Core.Models.Eft.Profile.Vitality;
@@ -16,7 +14,7 @@ namespace SPTarkov.Server.Core.Helpers;
public class HealthHelper(
TimeUtil _timeUtil,
SaveServer _saveServer,
- DatabaseService _databaseService,
+ ProfileHelper _profileHelper,
ConfigServer _configServer
)
{
@@ -128,8 +126,6 @@ public class HealthHelper(
/// Post raid data
/// Session id
/// Is player dead
- /// Should effects be added to profile (default - true)
- /// Should all prior effects be removed before apply new ones (default - true)
public void UpdateProfileHealthPostRaid(
PmcData pmcData,
BotBaseHealth postRaidHealth,
@@ -139,16 +135,14 @@ public class HealthHelper(
var fullProfile = _saveServer.GetProfile(sessionID);
var profileEdition = fullProfile.ProfileInfo.Edition;
var profileSide = fullProfile.CharacterData.PmcData.Info.Side;
+
+ // Get matching 'side e.g. USEC
+ var matchingSide = _profileHelper.GetProfileTemplateForSide(profileEdition, profileSide);
- var defaultTemperature =
- _databaseService.GetProfiles()
- .GetByJsonProp(profileEdition)
- .GetByJsonProp(profileSide.ToLower())
- ?.Character?.Health?.Temperature ??
- new CurrentMinMax
- {
- Current = 36.6
- };
+ var defaultTemperature = matchingSide?.Character?.Health?.Temperature ?? new CurrentMinMax
+ {
+ Current = 36.6
+ };
StoreHydrationEnergyTempInProfile(
fullProfile,
diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs
index a1cd6f26..431ce184 100644
--- a/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs
+++ b/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs
@@ -754,4 +754,23 @@ public class ProfileHelper(
fullProfile.SptData.ExtraRepeatableQuests[repeatableId] += rewardValue;
}
}
+
+ ///
+ /// Get a profile template by the account and side
+ ///
+ /// Edition of profile desired, e.g. "Standard"
+ /// Side of profile desired, e.g. "Bear"
+ ///
+ public TemplateSide GetProfileTemplateForSide(string accountEdition, string side)
+ {
+ var profileTemplates = _databaseService.GetProfileTemplates();
+
+ // Get matching profile 'type' e.g. 'standard'
+ profileTemplates.TryGetValue(accountEdition, out var matchingProfileTemplate);
+
+ // Get matching profile by 'side' e.g. USEC
+ return string.Equals(side, "bear", StringComparison.OrdinalIgnoreCase)
+ ? matchingProfileTemplate.Bear
+ : matchingProfileTemplate.Usec;
+ }
}
diff --git a/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs
index 7f42f161..33912f6a 100644
--- a/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs
+++ b/Libraries/SPTarkov.Server.Core/Helpers/TraderHelper.cs
@@ -1,4 +1,4 @@
-using SPTarkov.Common.Extensions;
+using System.Security.Principal;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common;
@@ -136,7 +136,7 @@ public class TraderHelper(
/// trader id to reset
public void ResetTrader(string sessionID, string traderID)
{
- var profiles = _databaseService.GetProfiles();
+ var profiles = _databaseService.GetProfileTemplates();
var trader = _databaseService.GetTrader(traderID);
var fullProfile = _profileHelper.GetFullProfile(sessionID);
@@ -145,34 +145,34 @@ public class TraderHelper(
throw new Exception(_localisationService.GetText("trader-unable_to_find_profile_by_id", sessionID));
}
+ // Get matching profile 'type' e.g. 'standard'
+ profiles.TryGetValue(fullProfile.ProfileInfo.Edition, out var matchingProfileTemplate);
var pmcData = fullProfile.CharacterData.PmcData;
- var rawProfileTemplate = profiles.GetByJsonProp(fullProfile.ProfileInfo.Edition)
- .GetByJsonProp(pmcData.Info.Side.ToLower())
- .Trader;
+ var matchingSide = _profileHelper.GetProfileTemplateForSide(fullProfile.ProfileInfo.Edition, pmcData.Info.Side);
+
+ // Profiles trader settings
+ var profileTemplateTraderData = matchingSide.Trader;
var newTraderData = new TraderInfo
{
Disabled = false,
- LoyaltyLevel = rawProfileTemplate.InitialLoyaltyLevel.GetValueOrDefault(traderID, 1),
- SalesSum = rawProfileTemplate.InitialSalesSum,
- Standing = GetStartingStanding(traderID, rawProfileTemplate),
+ LoyaltyLevel = profileTemplateTraderData.InitialLoyaltyLevel.GetValueOrDefault(traderID, 1),
+ SalesSum = profileTemplateTraderData.InitialSalesSum,
+ Standing = GetStartingStanding(traderID, profileTemplateTraderData),
NextResupply = trader.Base.NextResupply,
Unlocked = trader.Base.UnlockedByDefault
};
- if (!pmcData.TradersInfo.TryAdd(traderID, newTraderData))
- {
- pmcData.TradersInfo[traderID] = newTraderData;
- }
-
+ // Add trader to profile if it doesn't already
+ pmcData.TradersInfo.TryAdd(traderID, newTraderData);
// Check if trader should be locked by default
- if (rawProfileTemplate.LockedByDefaultOverride?.Contains(traderID) ?? false)
+ if (profileTemplateTraderData.LockedByDefaultOverride?.Contains(traderID) ?? false)
{
pmcData.TradersInfo[traderID].Unlocked = true;
}
- if (rawProfileTemplate.PurchaseAllClothingByDefaultForTrader?.Contains(traderID) ?? false)
+ if (profileTemplateTraderData.PurchaseAllClothingByDefaultForTrader?.Contains(traderID) ?? false)
{
// Get traders clothing
var clothing = _databaseService.GetTrader(traderID).Suits;
@@ -186,16 +186,18 @@ public class TraderHelper(
}
}
- if ((rawProfileTemplate.FleaBlockedDays ?? 0) > 0)
+ // Template has flea block
+ if ((profileTemplateTraderData.FleaBlockedDays ?? 0) > 0)
{
- var newBanDateTime = _timeUtil.GetTimeStampFromNowDays(rawProfileTemplate.FleaBlockedDays ?? 0);
- var existingBan = pmcData.Info.Bans.FirstOrDefault(ban => ban.BanType == BanType.RagFair);
+ var newBanDateTime = _timeUtil.GetTimeStampFromNowDays(profileTemplateTraderData.FleaBlockedDays ?? 0);
+ var existingBan = pmcData.Info.Bans?.FirstOrDefault(ban => ban.BanType == BanType.RagFair);
if (existingBan is not null)
{
existingBan.DateTime = newBanDateTime;
}
else
{
+ pmcData.Info.Bans ??= [];
pmcData.Info.Bans.Add(
new Ban
{
@@ -208,7 +210,7 @@ public class TraderHelper(
if (traderID == Traders.JAEGER)
{
- pmcData.TradersInfo[traderID].Unlocked = rawProfileTemplate.JaegerUnlocked;
+ pmcData.TradersInfo[traderID].Unlocked = profileTemplateTraderData.JaegerUnlocked;
}
}
diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs
index 39e5b498..8a15511e 100644
--- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs
+++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs
@@ -3,75 +3,6 @@ using SPTarkov.Server.Core.Models.Eft.Profile;
namespace SPTarkov.Server.Core.Models.Eft.Common.Tables;
-public record ProfileTemplates
-{
- [JsonExtensionData]
- public Dictionary ExtensionData { get; set; }
-
- [JsonPropertyName("Standard")]
- public ProfileSides? Standard
- {
- get;
- set;
- }
-
- [JsonPropertyName("Left Behind")]
- public ProfileSides? LeftBehind
- {
- get;
- set;
- }
-
- [JsonPropertyName("Prepare To Escape")]
- public ProfileSides? PrepareToEscape
- {
- get;
- set;
- }
-
- [JsonPropertyName("Edge Of Darkness")]
- public ProfileSides? EdgeOfDarkness
- {
- get;
- set;
- }
-
- [JsonPropertyName("Unheard")]
- public ProfileSides? Unheard
- {
- get;
- set;
- }
-
- [JsonPropertyName("Tournament")]
- public ProfileSides? Tournament
- {
- get;
- set;
- }
-
- [JsonPropertyName("SPT Developer")]
- public ProfileSides? SPTDeveloper
- {
- get;
- set;
- }
-
- [JsonPropertyName("SPT Easy start")]
- public ProfileSides? SPTEasyStart
- {
- get;
- set;
- }
-
- [JsonPropertyName("SPT Zero to hero")]
- public ProfileSides? SPTZeroToHero
- {
- get;
- set;
- }
-}
-
public record ProfileSides
{
[JsonExtensionData]
diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Templates/Templates.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Templates/Templates.cs
index c984ebd1..cbe3206d 100644
--- a/Libraries/SPTarkov.Server.Core/Models/Spt/Templates/Templates.cs
+++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Templates/Templates.cs
@@ -69,7 +69,7 @@ public record Templates
/// The profile templates listed in the launcher on profile creation, split by account type (e.g. Standard) then side (e.g. bear/usec)
///
[JsonPropertyName("profiles")]
- public ProfileTemplates? Profiles
+ public Dictionary? Profiles
{
get;
set;
diff --git a/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs b/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs
index 941fbc23..93050ffd 100644
--- a/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs
@@ -43,9 +43,8 @@ public class CreateProfileService(
public string CreateProfile(string sessionId, ProfileCreateRequestData request)
{
var account = _cloner.Clone(_saveServer.GetProfile(sessionId));
- var profileTemplateClone = _cloner.Clone(
- _databaseService.GetProfiles()?.GetByJsonProp(account.ProfileInfo.Edition)?.GetByJsonProp(request.Side.ToLower())
- );
+ var profileTemplateClone = _cloner.Clone(_profileHelper.GetProfileTemplateForSide(account.ProfileInfo.Edition, request.Side));
+
var pmcData = profileTemplateClone.Character;
// Delete existing profile
diff --git a/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs b/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs
index cdc06e1b..12d073c7 100644
--- a/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs
@@ -257,7 +257,7 @@ public class DatabaseService(
}
/// assets/database/templates/profiles.json
- public ProfileTemplates GetProfiles()
+ public Dictionary GetProfileTemplates()
{
if (_databaseServer.GetTables().Templates?.Profiles == null)
{