using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; using PARTY_GUID = System.String; using USER_GUID = System.String; namespace GameServer.PacketHandler; [PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.ReplyInvitePartyReq), typeof(ReplyInvitePartyPacketHandler), typeof(GameLoginListener))] public class ReplyInvitePartyPacketHandler : PacketRecvHandler { private static void send_S2C_ACK_REPLAY_INVITE_PARTY(Player owner, Result result) { var ack_packet = new ClientToGame { Response = new ClientToGameRes { ErrorCode = result.ErrorCode, ReplyInvitePartyRes = new() } }; GameServerApp.getServerLogic().onSendPacket(owner, ack_packet); } public override async Task onProcessPacket(ISession entityWithSession, IMessage recvMessage) { Log.getLogger().info($"{nameof(ReplyInvitePartyPacketHandler)}.{nameof(onProcessPacket)}: - {recvMessage}"); var result = new Result(); string err_msg; var entity_player = entityWithSession as Player; NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!"); // 1. 기본 정보 체크 var request = (recvMessage as ClientToGame)?.Request.ReplyInvitePartyReq; if (null == request) { err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ReplyInvitePartyReq)}"; result.setFail(ServerErrorCode.InvalidArgument, err_msg); Log.getLogger().error(result.toBasicString()); send_S2C_ACK_REPLAY_INVITE_PARTY(entity_player, result); return result; } // 2. 조건 체크 result = await checkReplayInvitePartyAsync(entity_player, request.InvitePartyGuid); if (result.isFail()) return result; // 3. 파티 초대 응답 로직 체크 result = await replyInvitePartyAsync(entity_player, request.InvitePartyGuid, request.Result); return result; } private async Task checkReplayInvitePartyAsync(Player entity_player, PARTY_GUID invite_party_guid) { var result = new Result(); string err_msg; // 1. 초대 수신 시간 체크 var invite_recv_time = await entity_player.getEntityAction() .getPartyInvitePartyRecvTime(invite_party_guid); if (null == invite_recv_time) { err_msg = $"Failed to find invite party recv !!! : {invite_party_guid}"; result.setFail(ServerErrorCode.NotFoundPartyInvite, err_msg); Log.getLogger().error(err_msg); return result; } // 2. 파티 가입 여부 체크 var login_cache_request = PartyHelper.getOwnUserLoginCacheRequest(entity_player); NullReferenceCheckHelper.throwIfNull(login_cache_request, () => $"login_cache_request is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}"); var loginCache = login_cache_request.getLoginCache(); NullReferenceCheckHelper.throwIfNull(loginCache, () => $"loginCache is null !!! - party_guid : {invite_party_guid} -"); if (string.IsNullOrEmpty(loginCache.PartyGuid)) return result; var global_party = GameServerApp.getServerLogic().findGlobalEntity(); NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}"); var party = global_party.getParty(loginCache.PartyGuid); NullReferenceCheckHelper.throwIfNull(party, () => $"party is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}"); // 3. 파티원 수가 여러명인지 체크 var party_member_action = party.getEntityAction(); NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - party_guid : {invite_party_guid} - {entity_player.toBasicString()}"); if (party_member_action.getMemberCount() > 1) { err_msg = $"Failed to reply invite party !!! : already party member - party_guid : {invite_party_guid} - {entity_player.getUserGuid()} "; result.setFail(ServerErrorCode.AlreadyPartyMember, err_msg); Log.getLogger().error(err_msg); return result; } return result; } private async Task replyInvitePartyAsync(Player entity_player, PARTY_GUID party_guid, BoolType reply_invite) { var result = new Result(); string err_msg; // 1. 파티 정보 조회 var global_party_action = GameServerApp.getServerLogic().findGlobalEntity() ?.getEntityAction(); NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global_party_action is null !!! - {entity_player.toBasicString()}"); var party_info = await global_party_action.getPartyLeaderGuidAndMemberCount(party_guid); if (PARTY_GUID.IsNullOrEmpty(party_info.leader_guid)) { err_msg = $"Failed to find party info !!! : {party_guid}"; result.setFail(ServerErrorCode.NotFoundParty, err_msg); Log.getLogger().error(result.toBasicString()); return result; } // 2. Invite 승인 로직 처리 if (reply_invite == BoolType.True) { result = await acceptInvitePartyAsync(entity_player, party_guid); if (result.isFail()) { send_S2C_ACK_REPLAY_INVITE_PARTY(entity_player, result); return result; } } // 3. leader 에게 통보 result = await sendReplyInvitePartyResultAsync(entity_player, party_guid, party_info.leader_guid, reply_invite); send_S2C_ACK_REPLAY_INVITE_PARTY(entity_player, result); // 4. Business Log 기록 writeBusinessLog(entity_player, party_guid, reply_invite); return result; } private async Task acceptInvitePartyAsync(Player entity_player, PARTY_GUID party_guid) { var result = new Result(); var global_party = GameServerApp.getServerLogic().findGlobalEntity(); NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}"); var global_party_action = global_party.getEntityAction(); NullReferenceCheckHelper.throwIfNull(global_party_action, () => $"global_party_action is null !!! - {entity_player.toBasicString()}"); // 0. 기존 요청 정보 정리 result = await clearMyInvitePartySendAsync(entity_player); if (result.isFail()) return result; // 1. user 정보 수정 result = await setInvitePartyToUserAsync(entity_player, party_guid); if (result.isFail()) return result; // 2. party join 처리 var party_member = PartyHelper.makePartyMember(entity_player.getUserGuid(), entity_player.getUserNickname()); result = await global_party_action.joinParty(party_guid, party_member); if (result.isFail()) { // 2-1. user 정보 롤백 result = await setInvitePartyToUserAsync(entity_player, string.Empty); } return result; } private async Task clearMyInvitePartySendAsync(Player entity_player) { var result = new Result(); // 1. 파티 정보 조회 var personal_party_action = entity_player.getEntityAction(); var personal_party = personal_party_action.getPersonalParty(); if (null == personal_party) return result; var global_party = GameServerApp.getServerLogic().findGlobalEntity(); NullReferenceCheckHelper.throwIfNull(global_party, () => $"global_party is null !!! - {entity_player.toBasicString()}"); var party = global_party.getParty(personal_party.getPartyGuid()); if (null == party) return result; // 2. 파티 인원수 체크 var party_member_action = party.getEntityAction(); NullReferenceCheckHelper.throwIfNull(party_member_action, () => $"party_member_action is null !!! - {entity_player.toBasicString()}"); if (party_member_action.getMemberCount() > 1) { var err_msg = $"Failed to reply invite party !!! : already party member - {party.PartyGuid}"; result.setFail(ServerErrorCode.AlreadyPartyMember, err_msg); Log.getLogger().error(err_msg); return result; } // 3. 파티 destroy var global_party_acton = global_party.getEntityAction(); NullReferenceCheckHelper.throwIfNull(global_party_acton, () => $"global_party_acton is null !!! - {entity_player.toBasicString()}"); result = await global_party_acton.destroyParty(party.PartyGuid, false); if (result.isFail()) return result; // 4. user 정보 정리 result = await personal_party_action.clearPersonalParty(); return result; } private async Task setInvitePartyToUserAsync(Player entity_player, PARTY_GUID party_guid) { // 1. 파티 정보 설정 var personal_party_action = entity_player.getEntityAction(); var result = await personal_party_action.setPersonalPartyGuid(party_guid); if (result.isFail()) return result; // 2. 파티 설정 await personal_party_action.setPersonalParty(party_guid); return result; } private async Task sendReplyInvitePartyResultAsync(Player entity_player, PARTY_GUID party_guid, USER_GUID leader_guid, BoolType replay_invite) { var result = new Result(); // 1. party leader 세션 체크 var leader_login_cache = await PartyHelper.getOtherUserLoginCache(entity_player, leader_guid); if (null == leader_login_cache) { var err_msg = $"Failed to get party leader session !!! - {leader_guid}"; result.setFail(ServerErrorCode.NotFoundParty, err_msg); Log.getLogger().error(err_msg); return result; } // 2. invite 응답 결과 전송 var message_to_leader = new ServerMessage { ReplyInvitePartyNoti = new ServerMessage.Types.ReplyInvitePartyNoti() { InvitePartyGuid = party_guid, InviteUserGuid = entity_player.getUserGuid(), InviteUserNickname = entity_player.getUserNickname(), Result = replay_invite } }; var rabbit_mq = GameServerApp.getServerLogic().getRabbitMqConnector() as RabbitMqConnector; NullReferenceCheckHelper.throwIfNull(rabbit_mq, () => $"rabbit_mq is null !!!"); rabbit_mq.SendMessage(leader_login_cache.CurrentServer, message_to_leader); // 3. 파티 초대 Recv 메시지 삭제 var party_recv_action = entity_player.getEntityAction(); result = await party_recv_action.deleteInvitePartyRecv(party_guid); return result; } private void writeBusinessLog(Player player, string partyGuid, BoolType isInviteAccept) { PartyMemberBusinessLog party_member_business_log; // 1. 파티 초대 응답 기록 var party_member_log = PartyBusinessLogHelper.toPartyMemberLogData(partyGuid, player.getUserGuid(), PartyMemberActionType.None); if (BoolType.True != isInviteAccept) { party_member_log.PartyMemberActionType = PartyMemberActionType.InviteReject; party_member_business_log = new PartyMemberBusinessLog(party_member_log); BusinessLogger.collectLog(player, party_member_business_log); return; } party_member_log.PartyMemberActionType = PartyMemberActionType.InviteAccept; party_member_business_log = new PartyMemberBusinessLog(party_member_log); BusinessLogger.collectLog(player, party_member_business_log); // 2. 파티 정보 기록 var log_invokers = new List(2); var party_log_data = PartyBusinessLogHelper.toPartyLogData(partyGuid, false); var party_business_log = new PartyBusinessLog(party_log_data); log_invokers.Add(party_business_log); // 3. 파티 가입 기록 party_member_log.PartyMemberActionType = PartyMemberActionType.JoinParty; party_member_business_log = new PartyMemberBusinessLog(party_member_log); log_invokers.Add(party_member_business_log); BusinessLogger.collectLogs(new LogActionEx(LogActionType.JoinParty), player, log_invokers); } }