using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using PhoenixLib.Caching; using PhoenixLib.Logging; using WingsEmu.DTOs.Maps; using WingsEmu.Game.Managers.ServerData; using WingsEmu.Plugins.BasicImplementations.ServerConfigs.ImportObjects; using WingsEmu.Plugins.BasicImplementations.ServerConfigs.ImportObjects.Npcs; using WingsEmu.Plugins.BasicImplementations.ServerConfigs.Persistence; namespace WingsEmu.Plugins.BasicImplementations.ServerConfigs; public class MapNpcManager : IMapNpcManager { private readonly ILongKeyCachedRepository _mapNpcById; private readonly IEnumerable _mapNpcConfigurations; private readonly IKeyValueCache> _mapNpcs; public MapNpcManager(IEnumerable mapNpcConfigurations, ILongKeyCachedRepository mapNpcById, IKeyValueCache> mapNpcs) { _mapNpcConfigurations = mapNpcConfigurations; _mapNpcById = mapNpcById; _mapNpcs = mapNpcs; } public async Task InitializeAsync() { List npcs = null; bool dbFirst = ParserDataPostgresReader.DbFirstEnabled; bool strictDbOnly = ParserDataPostgresReader.StrictDbOnlyEnabled; if (dbFirst) { try { npcs = ParserDataPostgresReader.LoadMapNpcs(); Log.Info($"[DB_FIRST] Loaded {npcs.Count} map_npcs from database"); } catch (Exception e) { if (strictDbOnly) { throw new InvalidOperationException("DB_FIRST/STRICT_DB_ONLY enabled but failed to load map_npcs from database.", e); } Log.Error("[DB_FIRST] Could not load map_npcs from database", e); } if (strictDbOnly && (npcs == null || npcs.Count == 0)) { throw new InvalidOperationException("DB_FIRST/STRICT_DB_ONLY enabled but no map_npcs were loaded from database."); } } if (npcs == null || npcs.Count == 0) { IEnumerable importedNpcs = _mapNpcConfigurations.SelectMany(x => x.Npcs.Select(s => { s.MapId = x.MapId; return s; })); npcs = importedNpcs.Select(s => s.ToDto()).ToList(); ParserDataPostgresSync.SyncMapNpcs(npcs); } int count = 0; foreach (MapNpcDTO npcDto in npcs) { _mapNpcById.Set(npcDto.Id, npcDto); _mapNpcs.GetOrSet($"by-map-id-{npcDto.MapId.ToString()}", () => new List()).Add(npcDto); _mapNpcs.GetOrSet($"by-npc-vnum-{npcDto.NpcVNum.ToString()}", () => new List()).Add(npcDto); count++; } Log.Info($"[DATABASE] Loaded {count.ToString()} MapNPCs"); } public MapNpcDTO GetById(int mapNpcId) => _mapNpcById.Get(mapNpcId); public IReadOnlyList GetByMapId(int mapId) => _mapNpcs.Get($"by-map-id-{mapId.ToString()}"); public IReadOnlyList GetMapNpcsPerVNum(int npcMonsterVnum) => _mapNpcs.Get($"by-npc-vnum-{npcMonsterVnum.ToString()}"); }