using LiteNetLib; using MMOserver.Game.Channel.Maps; using MMOserver.Game.Channel.Maps.InstanceDungeun; using MMOserver.Game.Party; namespace MMOserver.Game.Channel; public class Channel { // 채널 내 유저 NetPeer (hashKey → NetPeer) — BroadcastToChannel 교차 조회 제거용 private readonly Dictionary connectPeers = new(); // 채널 내 유저 상태 (hashKey → Player) private readonly Dictionary connectUsers = new(); // 채널 맵 관리 private readonly Dictionary maps = new(); // 진행중 채널 맵 관리 private readonly Dictionary useInstanceMaps = new(); // 동적 레이드 맵 할당용 ID 카운터 (사전 생성 10개 이후부터 시작) private int nextDynamicRaidMapId = 1011; // 파티 private readonly PartyManager partyManager = new(); public Channel(int channelId) { ChannelId = channelId; // 일단 하드코딩으로 맵 생성 { // 로비 maps.Add(1, new Robby(1)); // 인던 int defaultValue = 1000; for (int i = 1; i <= 10; i++) { maps.Add(i + defaultValue, new BossInstance(i + defaultValue)); } } } public int ChannelId { get; } public int UserCount { get; private set; } public int UserCountMax { get; private set; } = 100; public void AddUser(int userId, Player player, NetPeer peer) { connectUsers[userId] = player; connectPeers[userId] = peer; UserCount++; // 처음 접속 시 1번 맵(로비)으로 입장 ChangeMap(userId, player, 1); } public void RemoveUser(int userId) { // 현재 맵에서도 제거 if (connectUsers.TryGetValue(userId, out Player? player) && maps.TryGetValue(player.CurrentMapId, out AMap? currentMap)) { currentMap.RemoveUser(userId); } if (connectUsers.Remove(userId)) { UserCount--; } connectPeers.Remove(userId); } // 맵 이동 (현재 맵 제거 → 새 맵 추가 → CurrentMapId 갱신) public bool ChangeMap(int userId, Player player, int mapId) { if (!maps.TryGetValue(mapId, out AMap? newMap)) { return false; } // 기존 맵에서 제거 if (maps.TryGetValue(player.CurrentMapId, out AMap? oldMap)) { oldMap.RemoveUser(userId); } newMap.AddUser(userId, player); player.CurrentMapId = mapId; return true; } // 재연결(WiFi→LTE 등) 시 동일 유저의 peer 교체 public void UpdatePeer(int userId, NetPeer peer) { connectPeers[userId] = peer; } // 채널 내 모든 유저의 hashKey 반환 (채널 입장 시 기존 플레이어 목록 조회용) public IEnumerable GetConnectUsers() { return connectUsers.Keys; } // 채널 내 모든 Player 반환 public IEnumerable GetPlayers() { return connectUsers.Values; } // 채널 내 모든 NetPeer 반환 — BroadcastToChannel 전용 (sessions 교차 조회 불필요) public IEnumerable GetConnectPeers() { return connectPeers.Values; } // 특정 유저의 Player 반환 public Player? GetPlayer(int userId) { connectUsers.TryGetValue(userId, out Player? player); return player; } // 특정 유저의 NetPeer 반환 public NetPeer? GetPeer(int userId) { connectPeers.TryGetValue(userId, out NetPeer? peer); return peer; } public int HasUser(int userId) { if (connectUsers.ContainsKey(userId)) { return ChannelId; } return -1; } // 맵들 가져옴 public Dictionary GetMaps() { return maps; } // 맵 가져옴 public AMap? GetMap(int mapId) { AMap? map = null; maps.TryGetValue(mapId, out map); return map; } // 사용 가능한 레이드 맵 ID 반환 // 기존 맵(1001~) 중 미사용 탐색 → 없으면 동적 생성 후 반환 public int GetOrCreateAvailableRaidMap() { // 기존 맵 중 미사용 탐색 foreach (int mapId in maps.Keys) { if (mapId >= 1001 && !useInstanceMaps.ContainsKey(mapId)) { return mapId; } } // 모두 사용 중 → 동적 생성 int newMapId = nextDynamicRaidMapId++; BossInstance newMap = new(newMapId); maps.Add(newMapId, newMap); return newMapId; } // 레이드 맵 사용 시작 (진행중 목록에 등록) public void AddInstanceMap(int mapId) { if (maps.TryGetValue(mapId, out AMap? map)) { useInstanceMaps[mapId] = map; } } // 레이드 맵 사용 종료 (진행중 목록에서 제거) public void RemoveInstanceMap(int mapId) { useInstanceMaps.Remove(mapId); } // 파티매니저 가져옴 public PartyManager GetPartyManager() { return partyManager; } // TODO : 채널 가져오기 }