using MMOserver.Utils; namespace MMOserver.Game.Party; public class PartyManager { private readonly UuidGenerator partyUuidGenerator = new UuidGenerator(); // partyId → PartyInfo private readonly Dictionary parties = new(); // playerId → partyId (한 플레이어는 하나의 파티만) private readonly Dictionary playerPartyMap = new(); // 파티 생성 public bool CreateParty(int leaderId, string partyName, out PartyInfo? party, List? memeberIds = null) { if (playerPartyMap.ContainsKey(leaderId)) { party = null; return false; // 이미 파티에 속해있음 } int partyId = partyUuidGenerator.Create(); if (memeberIds == null) { memeberIds = new List(); } party = new PartyInfo { PartyId = partyId, LeaderId = leaderId, PartyName = partyName, PartyMemberIds = memeberIds }; party.PartyMemberIds.Add(leaderId); parties[partyId] = party; playerPartyMap[leaderId] = partyId; return true; } // 파티 참가 public bool JoinParty(int playerId, int partyId, out PartyInfo? party) { party = null; if (playerPartyMap.ContainsKey(playerId)) { return false; // 이미 파티에 속해있음 } if (!parties.TryGetValue(partyId, out party)) { return false; // 파티 없음 } if (party.GetPartyMemberCount() >= PartyInfo.partyMemberMax) { party = null; return false; // 파티 인원 초과 } party.PartyMemberIds.Add(playerId); playerPartyMap[playerId] = partyId; return true; } // 파티 탈퇴 public bool LeaveParty(int playerId, out PartyInfo? party) { party = null; if (!playerPartyMap.TryGetValue(playerId, out int partyId)) { return false; // 파티에 속해있지 않음 } if (!parties.TryGetValue(partyId, out party)) { return false; } party.PartyMemberIds.Remove(playerId); playerPartyMap.Remove(playerId); // 마지막 멤버가 나가면 파티 해산 if (party.PartyMemberIds.Count == 0) { DeletePartyInternal(partyId, party); // id가 필요하다 그래서 참조해 둔다. // party = null; return true; } // 리더가 나갔으면 남은 멤버 중 첫 번째를 리더로 승계 if (party.LeaderId == playerId) { party.LeaderId = party.PartyMemberIds[0]; } return true; } // 파티 해산 (리더만) public bool DeleteParty(int leaderId, int partyId, out PartyInfo? party) { party = null; if (!parties.TryGetValue(partyId, out party)) { return false; } if (party.LeaderId != leaderId) { party = null; return false; // 리더만 해산 가능 } DeletePartyInternal(partyId, party); return true; } // 파티 업데이트 public bool UpdateParty(int leaderId, int partyId, string newPartyName, out PartyInfo? party) { party = null; if (!parties.TryGetValue(partyId, out party)) { return false; } if (party.LeaderId != leaderId) { party = null; return false; // 리더만 업데이트 가능 } // 파티 이름 변경 party.PartyName = newPartyName; return true; } // 전체 파티 목록 조회 public IEnumerable GetAllParties() { return parties.Values; } // 조회 public PartyInfo? GetParty(int partyId) { parties.TryGetValue(partyId, out PartyInfo? party); return party; } public PartyInfo? GetPartyByPlayer(int playerId) { if (!playerPartyMap.TryGetValue(playerId, out int partyId)) { return null; } parties.TryGetValue(partyId, out PartyInfo? party); return party; } // 삭제 private void DeletePartyInternal(int partyId, PartyInfo party) { // 남아 있는인원도 제거 foreach (int memberId in party.PartyMemberIds) { playerPartyMap.Remove(memberId); } parties.Remove(partyId); partyUuidGenerator.Release(partyId); } }