diff --git a/Libraries/SPTarkov.Common/Extensions/StringExtensions.cs b/Libraries/SPTarkov.Common/Extensions/StringExtensions.cs index 4910e4a5..c444e332 100644 --- a/Libraries/SPTarkov.Common/Extensions/StringExtensions.cs +++ b/Libraries/SPTarkov.Common/Extensions/StringExtensions.cs @@ -5,18 +5,18 @@ namespace SPTarkov.Common.Extensions; public static class StringExtensions { - private static readonly Dictionary RegexCache = new(); - private static readonly Lock RegexCacheLock = new(); + private static readonly Dictionary _regexCache = new(); + private static readonly Lock _regexCacheLock = new(); public static string RegexReplace(this string source, [StringSyntax(StringSyntaxAttribute.Regex)] string regexString, string newValue) { Regex regex; - lock (RegexCacheLock) + lock (_regexCacheLock) { - if (!RegexCache.TryGetValue(regexString, out regex)) + if (!_regexCache.TryGetValue(regexString, out regex)) { regex = new Regex(regexString); - RegexCache[regexString] = regex; + _regexCache[regexString] = regex; } } @@ -26,12 +26,12 @@ public static class StringExtensions public static bool RegexMatch(this string source, [StringSyntax(StringSyntaxAttribute.Regex)] string regexString, out Match? matchedString) { Regex regex; - lock (RegexCacheLock) + lock (_regexCacheLock) { - if (!RegexCache.TryGetValue(regexString, out regex)) + if (!_regexCache.TryGetValue(regexString, out regex)) { regex = new Regex(regexString); - RegexCache[regexString] = regex; + _regexCache[regexString] = regex; } } diff --git a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs index 7525b2a7..a0bc1189 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/BotController.cs @@ -39,6 +39,7 @@ public class BotController( { private readonly BotConfig _botConfig = _configServer.GetConfig(); private readonly PmcConfig _pmcConfig = _configServer.GetConfig(); + private static readonly Lock _botListLock = new(); /// /// Return the number of bot load-out varieties to be generated @@ -201,7 +202,10 @@ public class BotController( condition.Limit), // Choose largest between value passed in from request vs what's in bot.config _botHelper.IsBotPmc(condition.Role)); - result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId)); + lock (_botListLock) + { + result.AddRange(GenerateBotWave(condition, botWaveGenerationDetails, sessionId)); + } })).ToArray()); stopwatch.Stop(); diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/PmcData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/PmcData.cs index ee22fd8e..282b8f3b 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/PmcData.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/PmcData.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System.ComponentModel; +using System.Text.Json.Serialization; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Utils.Json.Converters; @@ -20,7 +21,10 @@ public record PmcData : BotBase set; } - public object CheckedChambers + /// + /// Returns the list of IDs of the weapons, which the player has checked the chamber of in the last raid. + /// + public List CheckedChambers { get; set; diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs index 19a04dce..438b70c8 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs @@ -169,11 +169,11 @@ public record ItemLocation } [JsonPropertyName("r")] - public object? R + public int R { get; set; - } // TODO: Can be string or number + } [JsonPropertyName("isSearched")] public bool? IsSearched @@ -186,11 +186,11 @@ public record ItemLocation /// SPT property? /// [JsonPropertyName("rotation")] - public object? Rotation + public bool? Rotation { get; set; - } // TODO: Can be string or boolean + } } public record Upd @@ -668,7 +668,8 @@ public record UpdDogtag } [JsonPropertyName("Side")] - public object? Side + [JsonConverter(typeof(DogtagSideConverter))] + public DogtagSide? Side { get; set; diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs index 6ccbbc4e..6244b47b 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs @@ -179,11 +179,11 @@ public record Quest /// Becomes 'AppearStatus' inside client /// [JsonPropertyName("status")] - public object? Status + public int? Status { get; set; - } // TODO: string | number + } [JsonPropertyName("KeyQuest")] public bool? KeyQuest @@ -447,11 +447,11 @@ public record QuestCondition } [JsonPropertyName("type")] - public object? Type + public string? Type { get; set; - } // TODO: boolean | string + } [JsonPropertyName("status")] public List? Status diff --git a/Libraries/SPTarkov.Server.Core/Models/Enums/DogtagSide.cs b/Libraries/SPTarkov.Server.Core/Models/Enums/DogtagSide.cs new file mode 100644 index 00000000..d94e0717 --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Models/Enums/DogtagSide.cs @@ -0,0 +1,12 @@ +namespace SPTarkov.Server.Core.Models.Enums; + +public enum DogtagSide +{ + /// + /// This is for the dogtag equipped by the player, which shows up as 0 (integer) on the profile json. + /// + NotApplicable, + + Usec, + Bear +} diff --git a/Libraries/SPTarkov.Server.Core/Servers/ConfigServer.cs b/Libraries/SPTarkov.Server.Core/Servers/ConfigServer.cs index 888c5b38..106513ed 100644 --- a/Libraries/SPTarkov.Server.Core/Servers/ConfigServer.cs +++ b/Libraries/SPTarkov.Server.Core/Servers/ConfigServer.cs @@ -1,4 +1,5 @@ using SPTarkov.Common.Annotations; +using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Enums; using SPTarkov.Server.Core.Models.Spt.Config; using SPTarkov.Server.Core.Models.Utils; @@ -10,11 +11,11 @@ namespace SPTarkov.Server.Core.Servers; [Injectable(InjectionType.Singleton)] public class ConfigServer { - protected static readonly string[] acceptableFileExtensions = ["json", "jsonc"]; + protected readonly string[] acceptableFileExtensions = ["json", "jsonc"]; protected FileUtil _fileUtil; protected JsonUtil _jsonUtil; protected ISptLogger _logger; - protected Dictionary configs = new(); + private static Dictionary _configs = new(); public ConfigServer( ISptLogger logger, @@ -25,18 +26,22 @@ public class ConfigServer _logger = logger; _jsonUtil = jsonUtil; _fileUtil = fileUtil; - Initialize(); + + if (_configs.Count == 0) + { + Initialize(); + } } public T GetConfig() where T : BaseConfig { var configKey = GetConfigKey(typeof(T)); - if (!configs.ContainsKey(configKey.GetValue())) + if (!_configs.ContainsKey(configKey.GetValue())) { throw new Exception($"Config: {configKey} is undefined. Ensure you have not broken it via editing"); } - return configs[configKey.GetValue()] as T; + return _configs[configKey.GetValue()] as T; } private ConfigTypes GetConfigKey(Type type) @@ -52,7 +57,7 @@ public class ConfigServer public T GetConfigByString(string configType) where T : BaseConfig { - return configs[configType] as T; + return _configs[configType] as T; } public void Initialize() @@ -80,18 +85,9 @@ public class ConfigServer throw new Exception($"Server will not run until the: {file} config error mentioned above is fixed"); } - configs[$"spt-{_fileUtil.StripExtension(file)}"] = deserializedContent; + _configs[$"spt-{_fileUtil.StripExtension(file)}"] = deserializedContent; } } - - /** TODO: deal with this: - this.logger.info(`Commit hash: { - globalThis.G_COMMIT || "DEBUG" - }`); - this.logger.info(`Build date: { - globalThis.G_BUILDTIME || "DEBUG" - }`); - **/ } private Type GetConfigTypeByFilename(string filename) diff --git a/Libraries/SPTarkov.Server.Core/Utils/Json/Converters/DogtagSideConverter.cs b/Libraries/SPTarkov.Server.Core/Utils/Json/Converters/DogtagSideConverter.cs new file mode 100644 index 00000000..b7b2b4ae --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Utils/Json/Converters/DogtagSideConverter.cs @@ -0,0 +1,33 @@ +using System.Text.Json; +using System.Text.Json.Serialization; +using SPTarkov.Server.Core.Models.Enums; + +namespace SPTarkov.Server.Core.Utils.Json.Converters; + +public class DogtagSideConverter : JsonConverter +{ + public override DogtagSide Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + { + return DogtagSide.NotApplicable; + } + + var value = reader.GetString(); + return value != null ? Enum.Parse(value) : DogtagSide.NotApplicable; + } + + public override void Write(Utf8JsonWriter writer, DogtagSide value, JsonSerializerOptions options) + { + switch (value) + { + case DogtagSide.NotApplicable: + writer.WriteNumberValue(0); + break; + case DogtagSide.Usec: + case DogtagSide.Bear: + writer.WriteStringValue(value.ToString()); + break; + } + } +}