diff --git a/Libraries/SPTarkov.Server.Core/Controllers/TraderController.cs b/Libraries/SPTarkov.Server.Core/Controllers/TraderController.cs index a8e27365..50164598 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/TraderController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/TraderController.cs @@ -44,7 +44,7 @@ public class TraderController( var traders = databaseService.GetTraders(); foreach (var (traderId, trader) in traders) { - if (traderId == Traders.LIGHTHOUSEKEEPER || traderId == "ragfair") + if (traderId == Traders.LIGHTHOUSEKEEPER) { continue; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Common/MongoId.cs b/Libraries/SPTarkov.Server.Core/Models/Common/MongoId.cs index bbf5a584..7b7d4c45 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Common/MongoId.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Common/MongoId.cs @@ -7,13 +7,7 @@ public readonly struct MongoId : IEquatable { private readonly string? _stringId; - public MongoId( - string? id, - // TODO: TEMPORARY REMOVE ME WHEN DONE!!!! - [CallerFilePath] string callerFilePath = "", - [CallerMemberName] string methodName = "", - [CallerLineNumber] int callerLineNumber = 0 - ) + public MongoId(string? id) { // Handle null strings, various id's are null either by BSG or by our own doing with LINQ if (string.IsNullOrEmpty(id)) @@ -26,15 +20,13 @@ public readonly struct MongoId : IEquatable if (id.Length != 24) { // TODO: Items.json root item has an empty parentId property - Console.WriteLine( - $"Critical MongoId error [{callerFilePath}::{methodName} L{callerLineNumber}]: Incorrect length. id: {id}" - ); + Console.WriteLine($"Critical MongoId error: Incorrect length. id: {id}"); } if (!IsValidMongoId(id)) { Console.WriteLine( - $"Critical MongoId error [{callerFilePath}::{methodName} L{callerLineNumber}]: Incorrect format. Must be a hexadecimal [a-f0-9] of 24 characters. id: {id}" + $"Critical MongoId error: Incorrect format. Must be a hexadecimal [a-f0-9] of 24 characters. id: {id}" ); } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/HandbookBase.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/HandbookBase.cs index e5598f5e..9df57aea 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/HandbookBase.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/HandbookBase.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; namespace SPTarkov.Server.Core.Models.Eft.Common.Tables; @@ -20,11 +21,11 @@ public record HandbookCategory public Dictionary? ExtensionData { get; set; } [JsonPropertyName("Id")] - public string? Id { get; set; } + public MongoId Id { get; set; } [JsonPropertyName("ParentId")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public string? ParentId { get; set; } + public MongoId? ParentId { get; set; } [JsonPropertyName("Icon")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] @@ -43,11 +44,11 @@ public record HandbookItem public Dictionary? ExtensionData { get; set; } [JsonPropertyName("Id")] - public string? Id { get; set; } + public MongoId Id { get; set; } [JsonPropertyName("ParentId")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - public string? ParentId { get; set; } + public MongoId ParentId { get; set; } [JsonPropertyName("Price")] public double? Price { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Server/DatabaseTables.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Server/DatabaseTables.cs index c9aef7fb..a1d14556 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Server/DatabaseTables.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Server/DatabaseTables.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; @@ -21,7 +22,7 @@ public record DatabaseTables public Templates.Templates? Templates { get; set; } - public Dictionary Traders { get; set; } + public Dictionary Traders { get; set; } public Globals? Globals { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs b/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs index da345319..a13a1717 100644 --- a/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/DatabaseService.cs @@ -328,7 +328,7 @@ public class DatabaseService( } /// assets/database/traders/ - public Dictionary GetTraders() + public Dictionary GetTraders() { if (_databaseServer.GetTables().Traders == null) { diff --git a/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs b/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs index a1840339..2de81df4 100644 --- a/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs +++ b/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs @@ -3,6 +3,7 @@ using System.Security.Cryptography; using System.Text; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.DI; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Spt.Server; using SPTarkov.Server.Core.Models.Utils; @@ -128,22 +129,8 @@ public class DatabaseImporter( VerifyDatabase ); - // TODO: Fix loading of traders, so their full path is not included as the key - - var tempTraders = new Dictionary(); - - // temp fix for trader keys - foreach (var trader in dataToImport.Traders) - { - // fix string for key - var tempKey = trader.Key.Split("/").Last(); - tempTraders.Add(tempKey, trader.Value); - } - timer.Stop(); - dataToImport.Traders = tempTraders; - _logger.Info(_serverLocalisationService.GetText("importing_database_finish")); _logger.Debug($"Database import took {timer.ElapsedMilliseconds}ms"); _databaseServer.SetTables(dataToImport); diff --git a/Libraries/SPTarkov.Server.Core/Utils/ImporterUtil.cs b/Libraries/SPTarkov.Server.Core/Utils/ImporterUtil.cs index d17e9a53..70ee7f74 100644 --- a/Libraries/SPTarkov.Server.Core/Utils/ImporterUtil.cs +++ b/Libraries/SPTarkov.Server.Core/Utils/ImporterUtil.cs @@ -1,7 +1,9 @@ +using System.Collections; using System.Collections.Frozen; using System.Linq.Expressions; using System.Reflection; using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Utils; using SPTarkov.Server.Core.Utils.Json; @@ -169,26 +171,55 @@ public class ImporterUtil(ISptLogger _logger, FileUtil _fileUtil, { try { - var setMethod = GetSetMethod( - directory.Split("/").Last().Replace("_", ""), - loadedType, - out var matchedProperty, - out var isDictionary - ); + var directoryName = directory.Split("/").Last().Replace("_", ""); - var loadedData = await LoadRecursiveAsync( - $"{directory}/", - matchedProperty, - onReadCallback, - onObjectDeserialized - ); - - lock (dictionaryLock) + if (MongoId.IsValidMongoId(directoryName)) { - setMethod.Invoke( - result, - isDictionary ? [directory, loadedData] : new[] { loadedData } + // For trader MongoId directories, we need to get the parent property. Get parent directory name to find the property + var parentDirectory = directory.Substring(0, directory.LastIndexOf('/')); + var parentName = parentDirectory.Split("/").Last().Replace("_", ""); + + GetSetMethod(parentName, loadedType, out var matchedProperty, out _); + + var loadedData = await LoadRecursiveAsync( + $"{directory}/", + matchedProperty, + onReadCallback, + onObjectDeserialized ); + + lock (dictionaryLock) + { + // Traders already have a dictionary, so we only need to handle this here + if (result is IDictionary dictionary) + { + dictionary[new MongoId(directoryName)] = loadedData; + } + } + } + else + { + var setMethod = GetSetMethod( + directoryName, + loadedType, + out var matchedProperty, + out var isDictionary + ); + + var loadedData = await LoadRecursiveAsync( + $"{directory}/", + matchedProperty, + onReadCallback, + onObjectDeserialized + ); + + lock (dictionaryLock) + { + setMethod.Invoke( + result, + isDictionary ? [directory, loadedData] : new[] { loadedData } + ); + } } } catch (Exception ex)