Files
caliverse_server/GameServer/Contents/Friend/Action/FriendInviteMyhomeAction.cs
2025-05-01 07:20:41 +09:00

291 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using ServerCore;
using ServerBase;
using ServerCommon;
using static ServerMessage.Types;
namespace GameServer;
public class MyhomeInviteInfo
{
public string SenderId { get; set; }
public string SenderGuid { get; set; }
public string SenderNickName { get; set; }
public DateTime ExpireTime { get; set; }
public DateTime ReplyExpireTime { get; set; }
public string UniqueKey { get; set; }
public int ReplyValue { get; set; } = 0;
public IndunLocation MyhomeLocation { get; set; } = new();
public MyhomeInviteInfo(string senderId, string senderGuid, string senderNickname, IndunLocation location, DateTime expireTime, DateTime replyExpireTime, string uniqueKey)
{
SenderId = senderId;
SenderGuid = senderGuid;
SenderNickName = senderNickname;
MyhomeLocation = location;
ExpireTime = expireTime;
ReplyExpireTime = replyExpireTime;
ReplyValue = 0;
UniqueKey = uniqueKey;
}
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
public class FriendInviteMyhomeAction : EntityActionBase
{
public FriendInviteMyhomeAction(Player owner)
: base(owner)
{
}
public override async Task<Result> onInit()
{
var result = new Result();
return await Task.FromResult(result);
}
public override void onClear()
{
return;
}
public async Task<(Result, List<FriendErrorMember>, List<ReceiveInviteMyHomeNoti>) > inviteFriendToMyhome(List<FriendNickNameInfo> infos)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var location_attribute = owner.getEntityAttribute<LocationAttribute>();
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"location_attribute is null !!!");
var myhome_location = location_attribute.CurrentIndunLocation;
var instance_meta_Id = myhome_location.InstanceMetaId;
var result = isCurrentLocationMyHome(instance_meta_Id);
if (result.isFail()){ return (result, new(), new()); }
DateTime now = DateTime.UtcNow;
string unique_key = now.ToString();
var expire_time = now.AddMilliseconds(MetaHelper.GameConfigMeta.FriendIntiveCoolTime * 1000);
var reply_expire_time = now.AddMilliseconds(MetaHelper.GameConfigMeta.FriendInviteReplyTime * 1000);
MyhomeInviteInfo invite_info = new MyhomeInviteInfo(owner.getAccountId(), owner.getUserGuid(), owner.getUserNickname(), myhome_location, expire_time, reply_expire_time, unique_key);
List<FriendErrorMember> fail_infos = new();
List<FriendNickNameInfo> cond_check_success_infos = new();
foreach (var info in infos)
{
var cond_result = await conditionCheck(info);
if (cond_result.isFail())
{
var fail = FriendAgentAction.makeFriendMemberError(cond_result.getErrorCode(), info.TargetGuid);
fail_infos.Add(fail);
}
else
{
cond_check_success_infos.Add(info);
}
}
List<FriendNickNameInfo> cache_check_success_infos = new();
foreach (var info in cond_check_success_infos)
{
var cache_cond_result = await checkFriendsInviteCache(info, now);
if (cache_cond_result.isFail())
{
var fail = FriendAgentAction.makeFriendMemberError(cache_cond_result.getErrorCode(), info.TargetGuid);
fail_infos.Add(fail);
}
else
{
cache_check_success_infos.Add(info);
}
}
List<ReceiveInviteMyHomeNoti> success_guids = new();
foreach (var info in cache_check_success_infos)
{
var add_result = await addFriendsInviteCache(info, invite_info);
if (add_result.isFail())
{
var fail = FriendAgentAction.makeFriendMemberError(add_result.getErrorCode(), info.TargetGuid);
fail_infos.Add(fail);
}
else
{
ReceiveInviteMyHomeNoti notiInfo = makeInviteMyhomeNoti(owner, info.TargetGuid, info.TargetNickName, invite_info);
success_guids.Add(notiInfo);
}
}
return (result, fail_infos, success_guids);
}
private ReceiveInviteMyHomeNoti makeInviteMyhomeNoti(Player owner, string targetGuid, string targetNickname, MyhomeInviteInfo inviteInfo)
{
ReceiveInviteMyHomeNoti info = new();
info.InviterMyHomeId = inviteInfo.MyhomeLocation.InstanceRoomId;
info.ExpireTime = Timestamp.FromDateTime(inviteInfo.ExpireTime);
info.ReplyExpireTime = Timestamp.FromDateTime(inviteInfo.ReplyExpireTime);
info.UniqueKey = inviteInfo.UniqueKey;
info.BaseInfo = new();
info.BaseInfo.ReceiverGuid = targetGuid;
info.BaseInfo.ReceiverNickName = targetNickname;
info.BaseInfo.ReceiverId = string.Empty;//내가 초대하려는 유저의 아이디.
info.BaseInfo.SenderGuid = inviteInfo.SenderGuid;
info.BaseInfo.SenderNickName = inviteInfo.SenderNickName;
info.BaseInfo.SenderId = owner.getAccountId(); //내 아이디
return info;
}
private async Task<Result> addFriendsInviteCache(FriendNickNameInfo info, MyhomeInviteInfo inviteInfo)
{
var result = new Result();
var server_logic = GameServerApp.getServerLogic();
CharacterStorage characterStorage = new CharacterStorage();
characterStorage.Init(server_logic.getRedisDb(), string.Empty);
ServerErrorCode error_code = await characterStorage.AddReceivedInviteInfo(info.TargetGuid, inviteInfo.ToString());
if (error_code != ServerErrorCode.Success)
{
result.setFail(error_code);
return result;
}
return result;
}
private async Task<Result> checkFriendsInviteCache(FriendNickNameInfo info, DateTime now)
{
var result = new Result();
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var server_logic = GameServerApp.getServerLogic();
CharacterStorage characterStorage = new CharacterStorage();
characterStorage.Init(server_logic.getRedisDb(), string.Empty);
//내가 초대 하려고 하는 유저가 받은 초대 정보
var invited_infos = await characterStorage.GetReceivedInviteInfo(info.TargetGuid);
if (invited_infos.Count > 0)
{
foreach (var invited_info in invited_infos)
{
var data = JsonConvert.DeserializeObject<MyhomeInviteInfo>(invited_info);
if (data is null) continue;
//data 가 기본적으로 만료시간을 전부 지나면 삭제 처리
if (now > data.ExpireTime)
{
characterStorage.RemoveReceivedInviteInfo(info.TargetGuid, invited_info);
continue;
}
//내가 보낸 정보가 남아있는 상태에서 보낸 시간이 아직 안지났으면 에러 처리
if (data.SenderGuid.Equals(owner.getUserGuid()) && now <= data.ExpireTime)
{
result.setFail(ServerErrorCode.FriendInviteExpireTimeRemain);
break;
}
//내가 보낸 정보가 아닌 데이터인데 수락해야되는 시간이 남아 있는경우
if (!data.SenderGuid.Equals(owner.getUserGuid()) && now <= data.ReplyExpireTime)
{
//수락 시간이 남아 있는데 거절한 상태가 아니면
if (data.ReplyValue == (int)InviteFriendReplyType.Refuse) continue;
result.setFail(ServerErrorCode.FriendInviteWaitingOtherInvite);
break;
}
}
}
return result;
}
private async Task<Result> conditionCheck(FriendNickNameInfo info)
{
string target_guid = info.TargetGuid;
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var server_logic = GameServerApp.getServerLogic();
var login_cache_request = new LoginCacheOtherUserRequest(player, server_logic.getRedisConnector(), target_guid);
var result = await login_cache_request.fetchLogin();
var friend_cache = login_cache_request.getLoginCache();
if (result.isFail())
{
var err_msg = $"friend Login Cache error : target_guid - {target_guid}";
result.setFail(ServerErrorCode.TargetUserNotLogIn, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (friend_cache is null)
{
result.setFail(ServerErrorCode.FriendInfoOffline);
return result;
}
if (friend_cache.State == PlayerStateType.DontDistrub)
{
result.setFail(ServerErrorCode.FriendInviteDontDisturbState);
return result;
}
if (friend_cache.InstanceRoomId.Contains(ServerCommon.Constant.PREFIX_MYHOME_INSTANCE_ROOM_ID))
{
var err_msg = $"friend another myhome : friend_guid - {target_guid}, my_guid - {player.getUserGuid()}, currentRommonIntanceId - {friend_cache.InstanceRoomId}";
result.setFail(ServerErrorCode.FriendIsInAnotherMyhome, err_msg);
//Log.getLogger().error(result.toBasicString());
return result;
}
return result;
}
public Result isCurrentLocationMyHome(Int32 instancMetaId)
{
var result = new Result();
if (!MetaData.Instance._IndunTable.TryGetValue(instancMetaId, out var indun_data))
{
string err_msg = $"Not Found IndunData. instanceMetaId:{instancMetaId}";
result.setFail(ServerErrorCode.NotExistInstanceRoom, err_msg);
Log.getLogger().error(err_msg);
return result;
}
if (indun_data.ContentsType != ContentsType.MyHome)
{
string err_msg = $"my pos is not myhome InstanceRoom owner : {getOwner().toBasicString()}, intance_room : {instancMetaId}";
result.setFail(ServerErrorCode.FriendInviteMyPosIsNotMyHome, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
}