diff --git a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs
index fedb694b..ccd76572 100644
--- a/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/ItemBaseClassService.cs
@@ -16,12 +16,11 @@ public class ItemBaseClassService(
ServerLocalisationService serverLocalisationService
)
{
- private bool _cacheGenerated;
-
///
/// Key = Item tpl, values = Ids of its parents
///
private Dictionary> _itemBaseClassesCache = [];
+ private readonly Lock _itemBaseClassesLock = new();
private readonly HashSet _rootNodeIds = [];
///
@@ -36,23 +35,34 @@ public class ItemBaseClassService(
var items = databaseService.GetItems();
foreach (var item in items)
{
- if (string.Equals(item.Value.Type, "Item", StringComparison.OrdinalIgnoreCase))
- {
- var itemIdToUpdate = item.Value.Id;
- if (!_itemBaseClassesCache.ContainsKey(item.Value.Id))
- {
- _itemBaseClassesCache[item.Value.Id] = [];
- }
+ AddItemToCache(item.Key);
+ }
+ }
- AddBaseItems(itemIdToUpdate, item.Value);
+ public void AddItemToCache(MongoId itemTpl)
+ {
+ logger.Debug($"Adding {itemTpl} to cache");
+
+ var itemDb = databaseService.GetItems();
+
+ if (!itemDb.TryGetValue(itemTpl, out var item))
+ {
+ logger.Error($"Could not add {itemTpl} to cache, it does not exist in the item database!");
+ return;
+ }
+
+ lock (_itemBaseClassesLock)
+ {
+ if (string.Equals(item.Type, "Item", StringComparison.OrdinalIgnoreCase))
+ {
+ _itemBaseClassesCache.TryAdd(item.Id, []);
+ AddBaseItems(item.Id, item);
}
else
{
- _rootNodeIds.Add(item.Key);
+ _rootNodeIds.Add(item.Id);
}
}
-
- _cacheGenerated = true;
}
///
@@ -79,11 +89,6 @@ public class ItemBaseClassService(
/// true if item inherits from base class passed in
public bool ItemHasBaseClass(MongoId itemTpl, IEnumerable baseClasses)
{
- if (!_cacheGenerated)
- {
- HydrateItemBaseClassCache();
- }
-
if (itemTpl.IsEmpty)
{
logger.Warning("Unable to check itemTpl base class as value passed is null");
@@ -107,8 +112,8 @@ public class ItemBaseClassService(
logger.Debug(serverLocalisationService.GetText("baseclass-item_not_found", itemTpl.ToString()));
}
- // Not found in cache, Hydrate again - some mods add items late in server startup lifecycle
- HydrateItemBaseClassCache();
+ // Not found in cache, attempt to add first
+ AddItemToCache(itemTpl);
existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out baseClassList);
}
@@ -131,11 +136,6 @@ public class ItemBaseClassService(
/// true if item inherits from base class passed in
public bool ItemHasBaseClass(MongoId itemTpl, MongoId baseClasses)
{
- if (!_cacheGenerated)
- {
- HydrateItemBaseClassCache();
- }
-
if (itemTpl.IsEmpty)
{
logger.Warning("Unable to check itemTpl base class as value passed is null");
@@ -159,8 +159,8 @@ public class ItemBaseClassService(
logger.Debug(serverLocalisationService.GetText("baseclass-item_not_found", itemTpl.ToString()));
}
- // Not found in cache, Hydrate again - some mods add items late in server startup lifecycle
- HydrateItemBaseClassCache();
+ // Not found in cache, attempt to add first
+ AddItemToCache(itemTpl);
existsInCache = _itemBaseClassesCache.TryGetValue(itemTpl, out baseClassList);
}
@@ -182,11 +182,6 @@ public class ItemBaseClassService(
/// array of base classes
public HashSet GetItemBaseClasses(MongoId itemTpl)
{
- if (!_cacheGenerated)
- {
- HydrateItemBaseClassCache();
- }
-
if (!_itemBaseClassesCache.TryGetValue(itemTpl, out var value))
{
return [];
diff --git a/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs b/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs
index 7f982923..57078670 100644
--- a/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs
+++ b/Libraries/SPTarkov.Server.Core/Services/Mod/CustomItemService.cs
@@ -66,7 +66,7 @@ public class CustomItemService(
AddToFleaPriceDb(newItemId, newItemDetails.FleaPriceRoubles);
- itemBaseClassService.HydrateItemBaseClassCache();
+ itemBaseClassService.AddItemToCache(newItemId);
if (itemHelper.IsOfBaseclass(itemClone.Id, BaseClasses.WEAPON))
{
@@ -112,7 +112,7 @@ public class CustomItemService(
AddToFleaPriceDb(newItem.Id, newItemDetails.FleaPriceRoubles);
- itemBaseClassService.HydrateItemBaseClassCache();
+ itemBaseClassService.AddItemToCache(newItem.Id);
if (itemHelper.IsOfBaseclass(newItem.Id, BaseClasses.WEAPON))
{