using System.Collections.Concurrent;
using System.Collections.Frozen;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.Constants;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Enums;
using SPTarkov.Server.Core.Models.Spt.Bots;
using SPTarkov.Server.Core.Models.Utils;
namespace SPTarkov.Server.Core.Services;
///
/// Cache bots in a dictionary, keyed by the bots ID
///
[Injectable(InjectionType.Singleton)]
public class MatchBotDetailsCacheService(ISptLogger logger)
{
private static readonly FrozenSet _rolesToCache = [Sides.PmcUsec, Sides.PmcBear];
protected readonly ConcurrentDictionary BotDetailsCache = new();
///
/// Store a bot in the cache, keyed by its ID.
///
/// Bot details to cache
public void CacheBot(BotBase botToCache)
{
if (botToCache?.Id is null)
{
return;
}
if (botToCache.Info?.Nickname is null)
{
logger.Warning($"Unable to cache: {botToCache.Info?.Settings?.Role} bot with id: {botToCache.Id} as it lacks a nickname");
return;
}
// ignore bot when not in role whitelist
if (botToCache.Info?.Settings?.Role is null || !_rolesToCache.Contains(botToCache.Info.Settings.Role))
{
return;
}
BotDetailsCache.TryAdd(
botToCache.Id.Value,
new BotDetailsForChatMessages
{
Nickname = botToCache.Info.Nickname.Trim(),
Side = botToCache.Info.Side == Sides.PmcUsec ? DogtagSide.Usec : DogtagSide.Bear,
Aid = botToCache.Aid,
Type = botToCache.Info.MemberCategory,
Level = botToCache.Info.Level,
PrimaryWeapon = botToCache.Inventory.Items.FirstOrDefault(x => x.SlotId == "FirstPrimaryWeapon")?.Template,
}
);
}
///
/// Clean the cache of all bot details.
///
public void ClearCache()
{
BotDetailsCache.Clear();
}
///
/// Find a bot in the cache by its ID.
///
/// ID of bot to find
///
public BotDetailsForChatMessages? GetBotById(MongoId? id)
{
if (id == null)
{
return null;
}
var botInCache = BotDetailsCache.GetValueOrDefault(id.Value, null);
if (botInCache is null)
{
logger.Warning($"Bot not found in match bot cache: {id}");
return null;
}
return botInCache;
}
}