From 52602aa4da2080c6af5c2d8779f0c86a16617877 Mon Sep 17 00:00:00 2001 From: Cj <161484149+CJ-SPT@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:30:57 -0500 Subject: [PATCH 01/18] Add Console.ReadLine() to prevent server window from closing --- SPTarkov.Server/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SPTarkov.Server/Program.cs b/SPTarkov.Server/Program.cs index 62058cbc..43d22c0c 100644 --- a/SPTarkov.Server/Program.cs +++ b/SPTarkov.Server/Program.cs @@ -59,6 +59,7 @@ public static class Program "=========================================================================================================" ); + Console.ReadLine(); return; } From 513f272e81375ae90e134029c34f594074549973 Mon Sep 17 00:00:00 2001 From: Chomp Date: Sun, 30 Nov 2025 17:12:59 +0000 Subject: [PATCH 02/18] Update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 62be3207..ef897b6d 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ In Rider, after installing the CSharpier plugin: We have a number of tests that are run automatically when you submit a pull request. You can run these tests locally by running The unit test sub-project. If you're adding a new feature or fixing a bug, please consider adding tests to cover your changes so that we can ensure they don't break in the future. + ## License This project is licensed under the NCSA Open Source License. See the [LICENSE](LICENSE) file for details. From 223fec91f7dd13a859379421aedc570c625ced9e Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 3 Dec 2025 09:22:36 +0000 Subject: [PATCH 03/18] Fixed medical items in profile presets having incorrect medial use values #711 --- .../SPT_Data/database/templates/profiles.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json index 7ac43a5b..7a62c951 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json @@ -8396,7 +8396,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -12127,7 +12127,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -15664,7 +15664,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -16089,7 +16089,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -16106,7 +16106,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -16138,7 +16138,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -19980,7 +19980,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -20056,7 +20056,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -20073,7 +20073,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, @@ -20238,7 +20238,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 5 + "HpResource": 3 } } }, From 040246eeee41b2e08d7bf8767eed55ac6d39831d Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 3 Dec 2025 09:24:48 +0000 Subject: [PATCH 04/18] Fixed Vaseline Balm in profile presets having incorrect medial use value #708 --- .../SPT_Data/database/templates/profiles.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json index 7a62c951..dcad9798 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/templates/profiles.json @@ -1626,7 +1626,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 6 + "HpResource": 3 } } }, @@ -4784,7 +4784,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 6 + "HpResource": 3 } } }, @@ -7798,7 +7798,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 6 + "HpResource": 3 } } }, @@ -11638,7 +11638,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 6 + "HpResource": 3 } } }, @@ -15071,7 +15071,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 6 + "HpResource": 3 } } }, @@ -19394,7 +19394,7 @@ "slotId": "hideout", "upd": { "MedKit": { - "HpResource": 6 + "HpResource": 3 } } }, From 0b56131aba9b32ff2ce738e99ba30133bc84162c Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 3 Dec 2025 10:30:31 +0000 Subject: [PATCH 05/18] Purge globally backlisted items from ragfair assort data --- .../SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs index b6522a86..2d8a7f81 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs @@ -18,6 +18,7 @@ public class RagfairAssortGenerator( DatabaseService databaseService, PresetHelper presetHelper, SeasonalEventService seasonalEventService, + ItemFilterService itemFilterService, ConfigServer configServer, ICloner cloner ) @@ -44,7 +45,8 @@ public class RagfairAssortGenerator( IEnumerable> results = []; // Get cloned items from db - var dbItems = databaseService.GetItems().Where(item => !string.Equals(item.Value.Type, "Node", StringComparison.OrdinalIgnoreCase)); + var blacklist = itemFilterService.GetBlacklistedItems(); + var dbItems = databaseService.GetItems().Where(item => !string.Equals(item.Value.Type, "Node", StringComparison.OrdinalIgnoreCase) && !blacklist.Contains(item.Key)); // Store processed preset tpls so we don't add them when processing non-preset items HashSet processedArmorItems = []; From bcfe10a9ca828a33d62f9a5b4469c9e3e0dc988d Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 3 Dec 2025 10:30:56 +0000 Subject: [PATCH 06/18] Removed `!!!DO NOT USE!!!40x46 mm M716(Smoke)` from PMC ammo pool --- .../SPT_Data/database/bots/types/bear.json | 1 - .../SPT_Data/database/bots/types/usec.json | 1 - 2 files changed, 2 deletions(-) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bear.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bear.json index b66bfc3d..ba94c730 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bear.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bear.json @@ -3215,7 +3215,6 @@ "5ede474b0c226a66f5402622": 1, "5ede475339ee016e8c534742": 1, "5ede475b549eed7c6d5c18fb": 1, - "5ede47641cf3836a88318df1": 1, "5f0c892565703e5c461894e9": 1 }, "Caliber46x30": { diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/usec.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/usec.json index 8052449f..3a2ad17f 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/usec.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/usec.json @@ -3206,7 +3206,6 @@ "5ede474b0c226a66f5402622": 1, "5ede475339ee016e8c534742": 1, "5ede475b549eed7c6d5c18fb": 1, - "5ede47641cf3836a88318df1": 1, "5f0c892565703e5c461894e9": 1 }, "Caliber46x30": { From 928508bd77a452dc39daf200bedcb6d4582e2178 Mon Sep 17 00:00:00 2001 From: sp-tarkov-bot Date: Wed, 3 Dec 2025 10:31:56 +0000 Subject: [PATCH 07/18] Format Style Fixes --- .../SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs index 2d8a7f81..1718999d 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs @@ -46,7 +46,9 @@ public class RagfairAssortGenerator( // Get cloned items from db var blacklist = itemFilterService.GetBlacklistedItems(); - var dbItems = databaseService.GetItems().Where(item => !string.Equals(item.Value.Type, "Node", StringComparison.OrdinalIgnoreCase) && !blacklist.Contains(item.Key)); + var dbItems = databaseService + .GetItems() + .Where(item => !string.Equals(item.Value.Type, "Node", StringComparison.OrdinalIgnoreCase) && !blacklist.Contains(item.Key)); // Store processed preset tpls so we don't add them when processing non-preset items HashSet processedArmorItems = []; From 1fd1a6d834eb820b450af31924b5ae81aaa12040 Mon Sep 17 00:00:00 2001 From: Archangel Date: Thu, 4 Dec 2025 23:11:21 +0100 Subject: [PATCH 08/18] Refactor bundle hash caching to save only after mod is loaded (#709) --- .../Loaders/BundleLoader.cs | 2 ++ .../Services/BundleHashCacheService.cs | 34 +++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Loaders/BundleLoader.cs b/Libraries/SPTarkov.Server.Core/Loaders/BundleLoader.cs index f5328aa2..c7641ffe 100644 --- a/Libraries/SPTarkov.Server.Core/Loaders/BundleLoader.cs +++ b/Libraries/SPTarkov.Server.Core/Loaders/BundleLoader.cs @@ -65,6 +65,8 @@ public class BundleLoader(ISptLogger logger, JsonUtil jsonUtil, Bu AddBundle(bundleManifest.Key, new BundleInfo(relativeModPath, bundleManifest, bundleHash)); } + + await bundleHashCacheService.WriteCache(); } /// diff --git a/Libraries/SPTarkov.Server.Core/Services/BundleHashCacheService.cs b/Libraries/SPTarkov.Server.Core/Services/BundleHashCacheService.cs index 86f21806..05f56432 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BundleHashCacheService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BundleHashCacheService.cs @@ -1,4 +1,5 @@ using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Models.Eft.Profile; using SPTarkov.Server.Core.Models.Utils; using SPTarkov.Server.Core.Utils; @@ -10,6 +11,7 @@ public class BundleHashCacheService(ISptLogger logger, J protected const string _bundleHashCachePath = "./user/cache/"; protected const string _cacheName = "bundleHashCache.json"; protected Dictionary _bundleHashes = []; + private readonly SemaphoreSlim _writeLock = new(1, 1); public async Task HydrateCache() { @@ -29,6 +31,27 @@ public class BundleHashCacheService(ISptLogger logger, J _bundleHashes = await jsonUtil.DeserializeFromFileAsync>(fullCachePath) ?? []; } + public async Task WriteCache() + { + await _writeLock.WaitAsync(); + + try + { + var bundleHashesSerialized = jsonUtil.Serialize(_bundleHashes); + + if (bundleHashesSerialized is null) + { + return; + } + + await fileUtil.WriteFileAsync(Path.Join(_bundleHashCachePath, _cacheName), bundleHashesSerialized); + } + finally + { + _writeLock.Release(); + } + } + protected uint GetStoredValue(string key) { if (!_bundleHashes.TryGetValue(key, out var value)) @@ -43,16 +66,7 @@ public class BundleHashCacheService(ISptLogger logger, J { _bundleHashes[bundlePath] = hash; - var bundleHashesSerialized = jsonUtil.Serialize(_bundleHashes); - - if (bundleHashesSerialized is null) - { - return; - } - - await fileUtil.WriteFileAsync(Path.Join(_bundleHashCachePath, _cacheName), bundleHashesSerialized); - - logger.Debug($"Bundle: {bundlePath} hash stored in: ${_bundleHashCachePath}"); + logger.Debug($"Bundle: {bundlePath} hash stored in cache"); } /// From 3d8b046f09af7f3c29621ba2d215af2c3d5b98d6 Mon Sep 17 00:00:00 2001 From: Archangel Date: Thu, 4 Dec 2025 23:19:06 +0100 Subject: [PATCH 09/18] Update build props --- Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build.props b/Build.props index 0e02c66b..fe2a13ef 100644 --- a/Build.props +++ b/Build.props @@ -1,7 +1,7 @@ - 4.0.7 + 4.0.8 a12b34 0000000000 LOCAL From 5c6ea280669d598321807e07cebe46c9c34cdb07 Mon Sep 17 00:00:00 2001 From: Archangel Date: Sat, 6 Dec 2025 02:01:56 +0100 Subject: [PATCH 10/18] Improve backup service compatibility with different calendars --- .../Services/BackupService.cs | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Services/BackupService.cs b/Libraries/SPTarkov.Server.Core/Services/BackupService.cs index 4b450f68..d2300a50 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BackupService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BackupService.cs @@ -30,6 +30,16 @@ public class BackupService protected readonly TimeUtil TimeUtil; protected readonly IReadOnlyList LoadedMods; + private static readonly CultureInfo[] Cultures = + [ + CultureInfo.InvariantCulture, + new CultureInfo("fa-IR") { DateTimeFormat = { Calendar = new PersianCalendar() } }, + new CultureInfo("ar-SA") { DateTimeFormat = { Calendar = new HijriCalendar() } }, + new CultureInfo("he-IL") { DateTimeFormat = { Calendar = new HebrewCalendar() } }, + new CultureInfo("th-TH") { DateTimeFormat = { Calendar = new ThaiBuddhistCalendar() } }, + new CultureInfo("ja-JP") { DateTimeFormat = { Calendar = new JapaneseCalendar() } }, + ]; + public BackupService( ISptLogger logger, IReadOnlyList loadedMods, @@ -233,9 +243,9 @@ public class BackupService } } - protected SortedDictionary GetBackupPathsWithCreationTimestamp(IEnumerable backupPaths) + protected SortedDictionary GetBackupPathsWithCreationTimestamp(IEnumerable backupPaths) { - var result = new SortedDictionary(); + var result = new SortedDictionary(); foreach (var backupPath in backupPaths) { var date = ExtractDateFromFolderName(backupPath); @@ -244,7 +254,7 @@ public class BackupService continue; } - result.Add(date.Value.ToFileTimeUtc(), backupPath); + result.Add(date.Value, backupPath); } return result; @@ -297,7 +307,7 @@ public class BackupService return 0; // Skip comparison if either date is invalid. } - return (int)(dateA.Value.ToFileTimeUtc() - dateB.Value.ToFileTimeUtc()); + return dateA.Value.CompareTo(dateB.Value); } /// @@ -308,11 +318,29 @@ public class BackupService protected DateTime? ExtractDateFromFolderName(string folderPath) { var folderName = Path.GetFileName(folderPath); - const string format = "yyyy-MM-dd_HH-mm-ss"; - if (DateTime.TryParseExact(folderName, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime)) + + var now = DateTime.UtcNow; + var minDate = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc); + var maxDate = now.AddYears(5); + + foreach (var culture in Cultures) { - return dateTime; + if ( + DateTime.TryParseExact( + folderName, + format, + culture, + DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, + out var dt + ) + ) + { + if (dt >= minDate && dt <= maxDate) + { + return DateTime.SpecifyKind(dt, DateTimeKind.Utc); + } + } } Logger.Warning($"Invalid backup folder name format: {folderPath}, [{folderName}]"); From c64e112cb66bea9d872bf9282c7a4280439179f8 Mon Sep 17 00:00:00 2001 From: Archangel Date: Tue, 9 Dec 2025 20:28:48 +0100 Subject: [PATCH 11/18] Route icon to favicon --- Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs b/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs index 755267b2..9a380831 100644 --- a/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs +++ b/Libraries/SPTarkov.Server.Core/Utils/DatabaseImporter.cs @@ -55,6 +55,11 @@ public class DatabaseImporter( var bsgPath = $"/{newBasePath}/{filePathNoExtension}".Replace("\\", "/"); imageRouter.AddRoute(bsgPath, fileNameWithPath); + + if (fileNameWithNoSPTPath.Contains("icon.ico")) + { + imageRouter.AddRoute("/favicon", fileNameWithPath); + } } } From 9ce2f4a4f6c1ce52ff7e6b114c5d53fdaf576700 Mon Sep 17 00:00:00 2001 From: Archangel Date: Thu, 11 Dec 2025 22:57:29 +0100 Subject: [PATCH 12/18] Further improve FilterCartridges --- .../Services/BotEquipmentFilterService.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs b/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs index bb61c163..94728b50 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs @@ -281,16 +281,13 @@ public class BotEquipmentFilterService( continue; } - // Loop over each cartridge + weight - // Clear all cartridges ready for whitelist to be added - foreach (var ammoKvP in cartridges) - // Cartridge not on whitelist + // Get all cartridges that aren't on the whitelist + var cartridgesToRemove = cartridges.Keys.Where(cartridge => !matchingWhitelist.Contains(cartridge)).ToList(); + + // Remove said cartridges from the original dictionary + foreach (var cartridge in cartridgesToRemove) { - if (!matchingWhitelist.Contains(ammoKvP.Key)) - // Remove - { - cartridges.Remove(ammoKvP.Key); - } + cartridges.Remove(cartridge); } } From 304e549caeb5bee35a15d6c5a0fdab030aa12158 Mon Sep 17 00:00:00 2001 From: Archangel Date: Thu, 11 Dec 2025 23:03:59 +0100 Subject: [PATCH 13/18] Improve null check --- .../SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs b/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs index 94728b50..54c961db 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs @@ -270,7 +270,7 @@ public class BotEquipmentFilterService( /// Filtered bot file protected void FilterCartridges(BotType baseBotNode, EquipmentFilterDetails? blacklist, EquipmentFilterDetails? whitelist) { - if (whitelist is not null) + if (whitelist is not null && whitelist.Cartridge is not null) { // Loop over each caliber + cartridges of that type foreach (var (caliber, cartridges) in baseBotNode.BotInventory.Ammo) From 9407e8308d1cd5e2b305495670d3b8d61439c293 Mon Sep 17 00:00:00 2001 From: Chomp Date: Fri, 12 Dec 2025 09:31:03 +0000 Subject: [PATCH 14/18] Fixed Christms Killa lacking armor inserts --- .../database/bots/types/bosskilla.json | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bosskilla.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bosskilla.json index 3aa14df1..7c3228f0 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bosskilla.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/database/bots/types/bosskilla.json @@ -2808,6 +2808,32 @@ "6575ea6760703324250610de" ] }, + "674d91ce6e862d5a95059ed6": { + "Back_plate": [ + "656efaf54772930db4031ff5" + ], + "Collar": [ + "6575ea719c7cad336508e418" + ], + "Front_plate": [ + "656f611f94b480b8a500c0db" + ], + "Groin": [ + "6575ea7c60703324250610e2" + ], + "Soft_armor_back": [ + "6575ea4cf6a13a7b7100adc4" + ], + "Soft_armor_front": [ + "6575ea3060703324250610da" + ], + "Soft_armor_left": [ + "6575ea5cf6a13a7b7100adc8" + ], + "soft_armor_right": [ + "6575ea6760703324250610de" + ] + }, "5c0e874186f7745dc7616606": { "Helmet_back": [ "6571138e818110db4600aa71" @@ -2822,6 +2848,20 @@ "5c0e842486f77443a74d2976" ] }, + "6759af0f9c8a538dd70bfae6": { + "Helmet_back": [ + "6571138e818110db4600aa71" + ], + "Helmet_ears": [ + "657112fa818110db4600aa6b" + ], + "Helmet_top": [ + "6571133d22996eaf11088200" + ], + "mod_equipment": [ + "5c0e842486f77443a74d2976" + ] + }, "65ae4f57e343f0acc00824da": { "mod_foregrip": [ "588226d124597767ad33f787", From b10d1db5da6591995657f67c76991f72eeb21d83 Mon Sep 17 00:00:00 2001 From: Chomp Date: Fri, 12 Dec 2025 10:02:16 +0000 Subject: [PATCH 15/18] Adjusted Christmas event to start on 13th, 1 day later Adjusted snow to start on 13th to match Christmas, 8 days earlier --- .../SPT_Data/configs/seasonalevents.json | 2 +- .../SPTarkov.Server.Assets/SPT_Data/configs/weather.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json index 819f7e33..51a31178 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json @@ -9931,7 +9931,7 @@ "enableChristmasHideout": true, "enableSanta": true }, - "startDay": "12", + "startDay": "13", "startMonth": "12", "type": "CHRISTMAS" }, diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/weather.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/weather.json index 94142bef..0601fe72 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/weather.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/weather.json @@ -287,13 +287,13 @@ "name": "AUTUMN_LATE", "startDay": "1", "startMonth": "11", - "endDay": "21", + "endDay": "13", "endMonth": "12" }, { "seasonType": 2, "name": "WINTER_START", - "startDay": "21", + "startDay": "13", "startMonth": "12", "endDay": "31", "endMonth": "12" From 4390948ff07c04a408fb6c4a463b69621f73457a Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 29 Nov 2025 11:04:17 +0000 Subject: [PATCH 16/18] Persist customisations during prestige event #704 (backport) --- .../SPTarkov.Server.Core/Helpers/PrestigeHelper.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs index ae025796..5d8d6f3e 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/PrestigeHelper.cs @@ -125,6 +125,17 @@ public class PrestigeHelper( ); } + // Copy over existing unlocked hideout customisation unlocks to new profile that player doesn't already have + newProfile.CustomisationUnlocks ??= []; + foreach (var oldUnlock in oldProfile.CustomisationUnlocks ?? []) + { + if (newProfile.CustomisationUnlocks.FirstOrDefault(unlock => unlock.Id == oldUnlock.Id) is null) + { + newProfile.CustomisationUnlocks.Add(oldUnlock); + } + } + + // Set prestige level on new profile newProfile.CharacterData!.PmcData!.Info!.PrestigeLevel = prestige.PrestigeLevel; } From 63c15f233e1fdc2ea2f82feb58b59b77558cb69d Mon Sep 17 00:00:00 2001 From: Chomp Date: Fri, 12 Dec 2025 13:51:49 +0000 Subject: [PATCH 17/18] Enable rundans event during Christmas, add config to enable/disable --- .../SPT_Data/configs/seasonalevents.json | 3 ++- .../Models/Spt/Config/SeasonalEventConfig.cs | 3 +++ .../Services/SeasonalEventService.cs | 11 +++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json index 51a31178..c7af2788 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json @@ -9929,7 +9929,8 @@ "settings": { "adjustBotAppearances": true, "enableChristmasHideout": true, - "enableSanta": true + "enableSanta": true, + "enableRundansEvent": true }, "startDay": "13", "startMonth": "12", diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs index f241eb1d..b60278f5 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs @@ -140,6 +140,9 @@ public record SeasonalEventSettings [JsonPropertyName("disableWaves")] public List? DisableWaves { get; set; } + + [JsonPropertyName("enableRundansEvent")] + public bool? EnableRundansEvent { get; set; } } public record ZombieSettings diff --git a/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs b/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs index 13345891..0ba5c231 100644 --- a/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs @@ -514,9 +514,20 @@ public class SeasonalEventService( AdjustBotAppearanceValues(eventType.Type); } + if (eventType.Settings?.EnableRundansEvent ?? false) + { + EnableRunnansEvent(databaseService.GetGlobals()); + } + ChangeBtrToTarColaSkin(); } + protected void EnableRunnansEvent(Globals globals) + { + globals.Configuration.RunddansSettings.Active = true; + globals.Configuration.RunddansSettings.ActivePVE = true; + } + private void ChangeBtrToTarColaSkin() { var btrSettings = databaseService.GetGlobals().Configuration.BTRSettings; From b0ea8200adbe4e3869c9de423c3880fcbfadfa20 Mon Sep 17 00:00:00 2001 From: sp-tarkov-bot Date: Fri, 12 Dec 2025 13:52:45 +0000 Subject: [PATCH 18/18] Format Style Fixes --- .../SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json | 2 +- Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json index c7af2788..cb298be6 100644 --- a/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json +++ b/Libraries/SPTarkov.Server.Assets/SPT_Data/configs/seasonalevents.json @@ -9930,7 +9930,7 @@ "adjustBotAppearances": true, "enableChristmasHideout": true, "enableSanta": true, - "enableRundansEvent": true + "enableRundansEvent": true }, "startDay": "13", "startMonth": "12", diff --git a/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs b/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs index 0ba5c231..3656a68a 100644 --- a/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs @@ -518,7 +518,7 @@ public class SeasonalEventService( { EnableRunnansEvent(databaseService.GetGlobals()); } - + ChangeBtrToTarColaSkin(); }