291 lines
11 KiB
C#
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;
|
|
}
|
|
} |