using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; namespace GameServer; public class PersonalPartyAction : EntityActionBase { private PersonalParty? m_party { get; set; } public PersonalPartyAction(Player owner) : base(owner) { } public override async Task onInit() { await Task.CompletedTask; var result = new Result(); return result; } public override void onClear() { return; } public bool isParty() => m_party != null; public async Task setPersonalParty(string party_guid) { var player = getOwner() as Player; ArgumentNullException.ThrowIfNull(player); m_party = new PersonalParty(player, party_guid); await m_party.onInit(); } public async Task setPersonalPartyGuid(string party_guid) { var owner = getOwner() as Player; ArgumentNullException.ThrowIfNull(owner); // 1. LoginCache 갱신 var user_login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(owner) ; ArgumentNullException.ThrowIfNull(user_login_cache_request); var login_cache = user_login_cache_request.getLoginCache(); NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login cache is null !!! - {owner.toBasicString()}"); login_cache.PartyGuid = party_guid; var result = await user_login_cache_request.upsertLogin(); return result; } public async Task clearPersonalParty() { var result = await setPersonalPartyGuid(string.Empty); if (result.isFail()) return result; m_party?.Dispose(); m_party = null; return result; } public async Task sendPartyChat(string chat_message) { var result = new Result(); var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => "player is null !!"); // 1. Party 확인 if (null == m_party) { var err_msg = $"Failed to send party chat !!! : not party member - {owner.getUserGuid()}"; result.setFail(ServerErrorCode.NotPartyMember, err_msg); Log.getLogger().error(err_msg); return result; } var global_party = GameServerApp.getServerLogic().findGlobalEntity(); NullReferenceCheckHelper.throwIfNull(global_party, () => "global party is null !!!"); NullReferenceCheckHelper.throwIfNull(m_party, () => "personal party is null !!!"); var party = global_party.getParty(m_party.getPartyGuid()); NullReferenceCheckHelper.throwIfNull(party, () => $"global party detail is null !!! - {m_party.getPartyGuid()} "); // 2. 메시지 전송 ( to server ) var server_message = new ServerMessage(); server_message.NtfPartyChat = new(); server_message.NtfPartyChat.PartyGuid = m_party.getPartyGuid(); server_message.NtfPartyChat.PartySenderGuid = owner.getUserGuid(); server_message.NtfPartyChat.PartySenderNickname = owner.getUserNickname(); server_message.NtfPartyChat.PartySendMessage = chat_message; PartyHelper.BroadcastToServers(party, server_message, true); // 3. 메시지 전송 ( to client ) var client_message = ChatNotifyHelper.makeChatMessage(ChatType.Party, owner.getUserNickname(), string.Empty, PlayerStateType.None, chat_message); PartyHelper.BroadcastToClients(party, client_message, new List() ); return await Task.FromResult(result); } public PersonalParty? getPersonalParty() => m_party; public async Task runPartyTick() { var result = new Result(); var player = getOwner() as Player; ArgumentNullException.ThrowIfNull(player); // 1. 파티 상태 체크 var party_guid = m_party?.getPartyGuid(); if (string.IsNullOrEmpty(party_guid)) return result; // 2. 해당 파티 정보 얻기 var party = GameServerApp.getServerLogic().findGlobalEntity()?.getParty(party_guid); ArgumentNullException.ThrowIfNull(party); var party_action = party.getEntityAction(); ArgumentNullException.ThrowIfNull(party_action); // 3. 파티장 체크 if (!party_action.isLeader(player.getUserGuid())) return result; // 4. 파티 Keep 실행 result = await party_action.keepParty(); return result; } public async Task<(bool in_party, string party_guid)> hasInParty() { var player = getOwner() as Player; ArgumentNullException.ThrowIfNull(player); var login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(player); if(login_cache_request == null) { return (false, string.Empty); } var login_cache = login_cache_request.getLoginCache(); NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login cache is null !!! - {player.toBasicString()}"); return await Task.FromResult((true != login_cache.PartyGuid.isNullOrWhiteSpace(), login_cache.PartyGuid)); } public async Task tryLoadParty() { var result = new Result(); string err_msg; var player = getOwner() as Player; ArgumentNullException.ThrowIfNull(player); // 1. user 의 Party invite recv 가져오기 var party_invite_recv_action = player.getEntityAction(); result = await party_invite_recv_action.loadInvitePartyRecv(); if (result.isFail()) return result; // 2. 파티에 가입중인가? var has_in_party = await hasInParty(); if (false == has_in_party.in_party) { return result; } // 3. party join 시키기 var global_party = GameServerApp.getServerLogic().findGlobalEntity(); var global_party_action = global_party?.getEntityAction(); if (null == global_party_action) { err_msg = $"Fail to get entity action !!! : {nameof(GlobalPartyAction)}"; result.setFail(ServerErrorCode.EntityActionNotFound, err_msg ); Log.getLogger().error(err_msg); return result; } var user = PartyHelper.makePartyMember(player.getUserGuid(), player.getUserNickname()); result = await global_party_action.joinParty(has_in_party.party_guid, user); if (result.isFail()) return result; // 4. 파티 정보 설정 await setPersonalParty(has_in_party.party_guid); return result; } public async Task createDefaultParty() { var result = new Result(); var owner = getOwner() as Player; ArgumentNullException.ThrowIfNull(owner); // 1. 파티 존재 여부 체크 if (null != m_party) { var err_msg = $"Failed to create party !!! : already party - {m_party.getPartyGuid()}"; result.setFail(ServerErrorCode.AlreadyPartyMember, err_msg); Log.getLogger().error(err_msg); return result; } // 2. 파티 생성 var party_guid = Guid.NewGuid().ToString(); await setPersonalParty(party_guid); return await Task.FromResult(result); } public async Task leaveParty() { var result = new Result(); var log_invokers = new List(3); var owner = getOwner() as Player; ArgumentNullException.ThrowIfNull(owner); // 1. 파티 상태 체크 var party_guid = m_party?.getPartyGuid(); if (string.IsNullOrEmpty(party_guid)) { var err_msg = "Failed to get party !!! - not in party"; result.setFail(ServerErrorCode.NotParty, err_msg); Log.getLogger().error(err_msg); return result; } // 2. 해당 파티 정보 얻기 var global_party = GameServerApp.getServerLogic().findGlobalEntity(); var global_party_action = global_party?.getEntityAction(); ArgumentNullException.ThrowIfNull(global_party_action); var party = global_party_action.getGlobalPartyDetail(party_guid); if (null == party) return result; var party_info = await global_party_action.getPartyLeaderGuidAndMemberCount(party_guid); var party_log_data = PartyBusinessLogHelper.toPartyLogData(party_guid, false); party_log_data.PartyMemberCount -= 1; var party_business_log = new PartyBusinessLog(party_log_data); log_invokers.Add(party_business_log); // 3. 파티장인 경우, 리더 전환 if (party_info.leader_guid == owner.getUserGuid() && party_info.member_count > 2) { // 3-1. 소환 취소 요청 var party_member_action = party.getEntityAction(); ArgumentNullException.ThrowIfNull(party_member_action); var cancel_summon = await party_member_action.cancelAllSummonAsync(); if (cancel_summon.result.isFail()) return cancel_summon.result; // 3-2. 파티장 위임 var party_action = party.getEntityAction(); ArgumentNullException.ThrowIfNull(party_action); (result, var change_leader_guid) = await party_action.changePartyLeader(); if (result.isFail()) return result; var party_leader_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(party_guid, change_leader_guid, PartyMemberActionType.PartyLeader); var party_leader_member_business_log = new PartyMemberBusinessLog(party_leader_member_log_data); log_invokers.Add(party_leader_member_business_log); } var party_member_log_data = PartyBusinessLogHelper.toPartyMemberLogData(party_guid, owner.getUserGuid(), PartyMemberActionType.LeaveParty); var party_member_business_log = new PartyMemberBusinessLog(party_member_log_data); log_invokers.Add(party_member_business_log); // 4. 파티 탈퇴 처리 result = await global_party_action.leaveParty(party_guid, owner.getUserGuid(), BoolType.False); if (result.isFail()) return result; // 5. 개인 파티 정리 await clearPersonalParty(); // 6. Business Log 기록 BusinessLogger.collectLogs(new LogActionEx(LogActionType.LeaveParty), owner, log_invokers); return result; } }