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.Monsters; using WingsEmu.Plugins.BasicImplementations.ServerConfigs.Persistence; namespace WingsEmu.Plugins.BasicImplementations.ServerConfigs; public class MapMonsterManager : IMapMonsterManager { private readonly IEnumerable _files; private readonly ILongKeyCachedRepository _mapMonsterById; private readonly IKeyValueCache> _mapMonsters; public MapMonsterManager(IEnumerable files, ILongKeyCachedRepository mapMonsterById, IKeyValueCache> mapMonsters) { _files = files; _mapMonsterById = mapMonsterById; _mapMonsters = mapMonsters; } public async Task InitializeAsync() { List monsters = null; bool dbFirst = ParserDataPostgresReader.DbFirstEnabled; bool strictDbOnly = ParserDataPostgresReader.StrictDbOnlyEnabled; if (dbFirst) { try { monsters = ParserDataPostgresReader.LoadMapMonsters(); Log.Info($"[DB_FIRST] Loaded {monsters.Count} map_monsters from database"); } catch (Exception e) { if (strictDbOnly) { throw new InvalidOperationException("DB_FIRST/STRICT_DB_ONLY enabled but failed to load map_monsters from database.", e); } Log.Error("[DB_FIRST] Could not load map_monsters from database", e); } if (strictDbOnly && (monsters == null || monsters.Count == 0)) { throw new InvalidOperationException("DB_FIRST/STRICT_DB_ONLY enabled but no map_monsters were loaded from database."); } } if (monsters == null || monsters.Count == 0) { monsters = _files.SelectMany(x => x.Monsters.Select(s => { s.MapId = x.MapId; return s.ToDto(); })).ToList(); ParserDataPostgresSync.SyncMapMonsters(monsters); } int count = 0; foreach (MapMonsterDTO npcDto in monsters) { _mapMonsterById.Set(npcDto.Id, npcDto); _mapMonsters.GetOrSet($"by-map-id-{npcDto.MapId.ToString()}", () => new List()).Add(npcDto); _mapMonsters.GetOrSet($"by-monster-vnum-{npcDto.MonsterVNum.ToString()}", () => new List()).Add(npcDto); count++; } Log.Info($"[DATABASE] Loaded {count.ToString()} MapMonsters"); } public MapMonsterDTO GetById(int mapNpcId) => _mapMonsterById.Get(mapNpcId); public IReadOnlyList GetByMapId(int mapId) => _mapMonsters.Get($"by-map-id-{mapId.ToString()}"); public IReadOnlyList GetMapMonstersPerVNum(int npcMonsterVnum) => _mapMonsters.Get($"by-monster-vnum-{npcMonsterVnum.ToString()}"); }