using GameServer.Contents.Room; using Google.Protobuf.WellKnownTypes; using Grpc.Core; using Nettention.Proud; using Newtonsoft.Json; using ServerCommon; using ServerCommon.BusinessLogDomain; using ServerCore; using ServerBase; using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata.Ecma335; using System.Text; using System.Threading.Tasks; namespace GameServer { public class FriendReplyInviteMyhomeRefference { public FriendReplyInviteMyhomeRefference(Int32 replyValue) { m_reply_datetime = DateTimeHelper.Current; m_reply_value = replyValue; } public Int32 m_reply_value { get; set; } = 0; public DateTime m_reply_datetime { get; set; } = DateTimeHelper.Current; public LoginCacheOtherUserRequest? m_invitor_login_cache_nullable { get; set; } = null; public string m_invitor_guid { get; set; } = string.Empty; //public bool m_is_replyable { get; set; } = false; //지금 응답 가능한 상태인에대한 bool 값 true가 되어야 응답이 가능한상태 public string m_accepted_invite_info { get; set; } = string.Empty; //수락한 초대 정보 public CharacterStorage? m_storage_nullable { get; set; } = null; //private string m_otp = string.Empty; //private string m_friend_myhome_server_address = string.Empty; //private Int32 m_friend_myhome_server_port = 0; public ServerConnectInfo? m_server_connect_info_nullable { get; set; } = null; } public class FriendReplyInviteMyhomeAction : EntityActionBase { public FriendReplyInviteMyhomeAction(EntityBase owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public override void onClear() { return; } public Result acceptReply(FriendReplyInviteMyhomeRefference replyRef) { var result = new Result(); result = removeInviteInfo(replyRef); if (result.isFail()) return result; return result; } public async Task checkReplyableAboutInvite(string roomId, string invitorId, FriendReplyInviteMyhomeRefference reply_ref) { var result = new Result(); //초대한 유저가 온라인인지 체크 (result, var invitor_login_cache) = await invitorOnlineCheck(invitorId); if (result.isFail()) return result; reply_ref.m_invitor_login_cache_nullable = invitor_login_cache; NullReferenceCheckHelper.throwIfNull(reply_ref.m_invitor_login_cache_nullable, () => $"reply_ref.m_invitor_login_cache_nullable is null !!!"); var login_cache = reply_ref.m_invitor_login_cache_nullable.getLoginCache(); NullReferenceCheckHelper.throwIfNull(login_cache, () => $"login_cache is null !!!"); reply_ref.m_invitor_guid = login_cache.UserGuid; reply_ref.m_storage_nullable = getStorage(); //나를 초대한 모든 정보 가져오기 var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var all_received_invites = await reply_ref.m_storage_nullable.GetReceivedInviteInfo(owner.getUserGuid()); result = await replyableCheck(all_received_invites, reply_ref); if (result.isFail()) return result; return result; } private CharacterStorage getStorage() { var server_logic = GameServerApp.getServerLogic(); CharacterStorage storage = new CharacterStorage(); storage.Init(server_logic.getRedisDb(), string.Empty); return storage; } private async Task replyableCheck(List receivedInvites, FriendReplyInviteMyhomeRefference reply_ref) { var result = new Result(); var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); bool is_replyable = false; foreach (var received_invite in receivedInvites) { var origin_data = JsonConvert.DeserializeObject(received_invite); if (origin_data is null) continue; var update_data = JsonConvert.DeserializeObject(received_invite); if (update_data is null) continue; //data 가 기본적으로 만료시간을 전부 지나면 삭제 처리 if (reply_ref.m_reply_datetime > origin_data.ExpireTime) { NullReferenceCheckHelper.throwIfNull(reply_ref.m_storage_nullable, () => $"reply_ref.m_storage_nullable is null !!!"); reply_ref.m_storage_nullable.RemoveReceivedInviteInfo(owner.getUserGuid(), received_invite); continue; } //내가 받은 정보가 아닌 데이터인데 수락해야되는 시간이 남아 있는경우 정상 로직이므로 true처리 if (origin_data.SenderGuid.Equals(reply_ref.m_invitor_guid) && reply_ref.m_reply_datetime <= origin_data.ReplyExpireTime) { is_replyable = true; if (reply_ref.m_reply_value == (int)InviteFriendReplyType.Refuse) { //거절인경우 정보 업데이트 해줘야된다. update_data.ReplyValue = (int)InviteFriendReplyType.Refuse; NullReferenceCheckHelper.throwIfNull(reply_ref.m_storage_nullable, () => $"reply_ref.m_storage_nullable is null !!!"); await reply_ref.m_storage_nullable.UpdateReceivedInviteInfo(owner.getUserGuid(), origin_data.ToString(), update_data.ToString()); } else if (reply_ref.m_reply_value == (int)InviteFriendReplyType.DontDisturb) { //방해 금지인 경우만 삭제 처리 해준다. NullReferenceCheckHelper.throwIfNull(reply_ref.m_storage_nullable, () => $"reply_ref.m_storage_nullable is null !!!"); reply_ref.m_storage_nullable.RemoveReceivedInviteInfo(owner.getUserGuid(), received_invite); } else if (reply_ref.m_reply_value == (int)InviteFriendReplyType.Accept) { reply_ref.m_accepted_invite_info = received_invite; } break; } } if (false == is_replyable) { result.setFail(ServerErrorCode.FriendInviteAlreadyExpire); return result; } return result; } private async Task<(Result, LoginCacheOtherUserRequest?)> invitorOnlineCheck(string invitorId) { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var server_logic = GameServerApp.getServerLogic(); (var result, var account_doc) = await AccountBaseDoc.findUserGuidFromAccountId(invitorId); if(result.isFail()) { return (result, null); } NullReferenceCheckHelper.throwIfNull(account_doc, () => $"ownaccount_docer is null !!!"); var account_attrib = account_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(account_attrib, () => $"account_attrib is null !!!"); var invitor_guid = account_attrib.UserGuid; var login_cache_request = new LoginCacheOtherUserRequest(owner, server_logic.getRedisConnector(), invitor_guid); await login_cache_request.fetchLogin(); if (login_cache_request is null) { var info_msg = $"login_cache_request is null, invitorId : {invitorId}, invitor_guid : {invitor_guid}"; result.setFail(ServerErrorCode.FriendInfoOffline, info_msg); Log.getLogger().info(result.toBasicString()); return (result, null); } return (result, login_cache_request); } public Result removeInviteInfo(FriendReplyInviteMyhomeRefference replyRef) { var result = new Result(); var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); NullReferenceCheckHelper.throwIfNull(replyRef.m_storage_nullable, () => $"replyRef.m_storage_nullable is null !!!"); replyRef.m_storage_nullable.RemoveReceivedInviteInfo(owner.getUserGuid(), replyRef.m_accepted_invite_info); return result; } public async Task joinFriendMyhomeFromInvite(string roomId, FriendReplyInviteMyhomeRefference replyRef) { await Task.Delay(3000); var result = new Result(); var err_msg = string.Empty; var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var game_zone_move_action = owner.getEntityAction(); (result, var server_connection_info) = await game_zone_move_action.tryJoinFriendMyhomeInstance(roomId); if (result.isFail()) { err_msg = $"Failed to tryJoinFriendMyhomeInstance() !!! : {result.toBasicString()}"; Log.getLogger().error(err_msg); return result; } replyRef.m_server_connect_info_nullable = server_connection_info; return result; } } }