초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
using Newtonsoft.Json;
using ServerCommon;
using ServerCommon.Cache;
using ServerCore; using ServerBase;
using System.Collections.Concurrent;
namespace GameServer
{
public class FriendAction : EntityActionBase
{
public FriendAction(Friend owner)
: base(owner)
{
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
return result;
}
public override void onClear()
{
return;
}
}
}

View File

@@ -0,0 +1,295 @@
using Nettention.Proud;
using Newtonsoft.Json;
using ServerCommon;
using ServerCommon.Cache;
using ServerCore; using ServerBase;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameServer;
public class FriendAgentAction : EntityActionBase
{
private ConcurrentDictionary<string, Friend> m_friends = new();
public FriendAgentAction(Player owner)
: base(owner)
{
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
return result;
}
public override void onClear()
{
m_friends.Clear();
}
public async Task<Result> loadFriends()
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var server_logic = GameServerApp.getServerLogic();
var batch = new QueryBatchEx<QueryRunnerWithDocument>(owner, LogActionType.None, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQFriendsReadAll(owner.getUserGuid()));
}
var result = await QueryHelper.sendQueryAndBusinessLog(batch);
return result;
}
public async Task<Result> setFriendsFromDoc(FriendDoc doc)
{
var result = new Result();
var owner = getOwner();
Friend friend = new Friend(owner);
var attribute = friend.getEntityAttribute<FriendAttribute>();
if (attribute is null)
{
var err_msg = $"Fail to get FriendAttribute";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (false == doc.getAttribWrappers().TryGetValue(typeof(FriendAttrib), out var to_copy_doc_attrib))
{
var err_msg = $"Fail to get FriendAttrib";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var attrib_base = to_copy_doc_attrib.getAttribBase();
var doc_attrib = attrib_base as FriendAttrib;
if (doc_attrib is null)
{
var err_msg = $"Fail to get FriendAttrib";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var player = owner as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
attribute.UserGuid = player.getUserGuid();
attribute.FriendGuid = doc_attrib.FriendGuid;
attribute.CreateTime = doc_attrib.CreateTime;
attribute.FolderName = doc_attrib.FolderName;
attribute.IsNew = doc_attrib.IsNew;
if (doc_attrib.FriendGuid.Equals(string.Empty))
{
var err_msg = $"FriendGuid is Empty, {toBasicString()}";
result.setFail(ServerErrorCode.FriendInfoNotExist, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (doc_attrib.FriendGuid.Equals(attribute.UserGuid))
{
var err_msg = $"FriendGuid and UserGuid is Equals, {toBasicString()}";
result.setFail(ServerErrorCode.FriendInfoNotExist, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
(result, var nickname_attrib) = await NicknameDoc.findNicknameFromGuid(doc_attrib.FriendGuid);
if(result.isFail())
{
return result;
}
NullReferenceCheckHelper.throwIfNull(nickname_attrib, () => $"nickname_attrib is null !!!");
attribute.Nickname = nickname_attrib.Nickname;
m_friends.AddOrUpdate(doc_attrib.FriendGuid, friend, (key, oldValue) => friend);
return result;
}
public async Task<List<FriendInfo>> getFriendsInfo()
{
return await convertFriendsToProtoFriendInfo();
}
public async Task<List<FriendInfo>> convertFriendsToProtoFriendInfo()
{
List<FriendInfo> friend_infos = new();
foreach (var friend in m_friends)
{
FriendInfo info = new();
(var result, var friend_attibute) = getFriendAttribFromAttribute(friend.Value);
if (result.isFail())
{
continue;
}
NullReferenceCheckHelper.throwIfNull(friend_attibute, () => $"friend_attibute is null !!!");
info.Guid = friend_attibute.FriendGuid;
info.FolderName = friend_attibute.FolderName;
info.IsNew = friend_attibute.IsNew;
info.NickName = await getFriendNickname(friend_attibute.FriendGuid);
friend_infos.Add(info);
}
return friend_infos;
}
private async Task<string> getFriendNickname(string friendGuid)
{
var (result, attrib) = await NicknameDoc.findNicknameFromGuid(friendGuid);
if (result.isFail())
{
Log.getLogger().error($"User : {friendGuid} has not Exist NicknameDoc");
return "notexistnickname";
}
NullReferenceCheckHelper.throwIfNull(attrib, () => $"attrib is null !!!");
return attrib.Nickname;
}
private (Result, FriendAttribute?) getFriendAttribFromAttribute(Friend friend)
{
var result = new Result();
var attribute = friend.getEntityAttribute<FriendAttribute>();
if (attribute is null)
{
var err_msg = $"Fail to get FriendAttribute, owner : {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
return (result, attribute);
}
public async Task<(Result, FriendRequestCache?)> sendedRequestExistCheck(FriendReqCacheRequest cache, string friendGuid)
{
var result = new Result();
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var received_requests = await cache.getSendedFriendRequests();
var send_friend_action = owner.getEntityAction<SendFriendRequestAction>();
NullReferenceCheckHelper.throwIfNull(send_friend_action, () => $"send_friend_action is null !!! - {owner.toBasicString()}");
//내가 요청 보낸 정보가 없으면 리턴..
(var is_sended, var req_cache) = send_friend_action.isSendedRequest(received_requests, friendGuid);
if (false == is_sended)
{
string err_msg = $"requeat info not exist send guid : {owner.getUserGuid()}, friend_guid : {friendGuid}, {toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestNotExistInfo, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
return (result, req_cache);
}
public async Task<(Result, FriendRequestCache?)> receivedRquestsExitstCheck(FriendReqCacheRequest cache, string friendGuid)
{
var result = new Result();
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var received_requests = await cache.getReceivedFriendRequests();
var send_friend_action = owner.getEntityAction<SendFriendRequestAction>();
NullReferenceCheckHelper.throwIfNull(send_friend_action, () => $"send_friend_action is null !!! - {owner.toBasicString()}");
//요청 받은 정보가 없으면 리턴..
//상대방이 먼저 취소한경우 여기에 해당
(var is_received, var req_cache) = send_friend_action.isReceivedRequest(received_requests, friendGuid);
if (false == is_received)
{
string err_msg = $"requeat info not exist receive guid : {owner.getUserGuid()}, friend_guid : {friendGuid}, {toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestNotExistInfo, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
return (result, req_cache);
}
public Result friendMaxCountCheck()
{
var result = new Result();
if (MetaHelper.GameConfigMeta.MaxFriendsNum <= m_friends.Values.Count)
{
var err_msg = $"my friend count already max count owner : {getOwner().toBasicString()}, friendCount : {m_friends.Values.Count}";
result.setFail(ServerErrorCode.FriendInfoMyCountAlreadyMaxCount, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
return result;
}
public Result raiseErrorIfExistFriend(string friendGuid)
{
var result = new Result();
if (m_friends.ContainsKey(friendGuid))
{
var err_msg = $"already exist friend : {friendGuid}, friendGuids : {JsonConvert.SerializeObject(m_friends.Keys)}, owner : {getOwner().toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestAlreadyFriend, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
return result;
}
public bool isFriend(string friendGuid)
{
return m_friends.ContainsKey(friendGuid);
}
public ConcurrentDictionary<string, Friend> getFriends() => m_friends;
public FriendAttribute? getFriendAttribute(string friendGuid)
{
if (!m_friends.TryGetValue(friendGuid, out var friend))
return null;
var friend_attribute = friend.getEntityAttribute<FriendAttribute>();
return friend_attribute;
}
public Friend? getFriend(string friendGuid)
{
m_friends.TryGetValue(friendGuid, out var friend);
return friend;
}
public static FriendErrorMember makeFriendMemberError(ServerErrorCode errorCode, string guid)
{
FriendErrorMember errormember = new();
errormember.ErrorCode = errorCode;
errormember.Guid = guid;
return errormember;
}
public void deleteFriend(string friendGuid)
{
m_friends.TryRemove(friendGuid, out _);
}
}

View File

@@ -0,0 +1,472 @@
using Amazon.S3.Model;
using Newtonsoft.Json;
using ServerCommon;
using ServerCommon.Cache;
using ServerCore; using ServerBase;
namespace GameServer
{
public enum FriendFolderorderType
{
ALPHABETICAL = 1,
STATEFUL = 2,
}
public class FriendFolderAction : EntityActionBase
{
public FriendFolderAction(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> loadFriendFolder()
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var server_logic = GameServerApp.getServerLogic();
var batch = new QueryBatchEx<QueryRunnerWithDocument>(owner, LogActionType.None
, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQFriendFoldersReadAll(owner.getUserGuid()));
}
var result = await QueryHelper.sendQueryAndBusinessLog(batch);
return result;
}
public ServerCommon.FriendFolder? getFriendFolder(string folderName)
{
var player = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!");
var friend_folder_attribute = player.getEntityAttribute<FriendFolderAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_folder_attribute, () => $"friend_folder_attribute is null !!!");
friend_folder_attribute.m_folders.TryGetValue(folderName, out var folder);
return folder;
}
public Result addFriendFolder(string folderName)
{
var friend_folder_attribute = getFriendFolderAttribute();
var result = raiseErrorIfExistFolder(friend_folder_attribute, folderName);
if (result.isFail()) return result;
result = maxFolderNameLengthCheck(folderName);
if (result.isFail()) return result;
result = folderCountCheck(friend_folder_attribute);
if (result.isFail()) return result;
var folder = makeFriendFolder(folderName);
if (false == friend_folder_attribute.m_folders.TryAdd(folderName, folder))
{
var err_msg = $"folderInfo.Folders.TryAdd Error folderName : {folderName}, folder : {JsonConvert.SerializeObject(folder)}";
result.setFail(ServerErrorCode.FolderCreateFail, err_msg);
Log.getLogger().error(err_msg);
}
friend_folder_attribute.modifiedEntityAttribute();
return result;
}
public Result holdFriendFolder(string folderName)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var friend_folder_attribute = owner.getEntityAttribute<FriendFolderAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_folder_attribute, () => $"friend_folder_attribute is null !!!");
var result = raiseErrorIfNotExistFolder(friend_folder_attribute, folderName);
if (result.isFail()) return result;
result = folderHoldCountCheck(friend_folder_attribute);
if (result.isFail()) return result;
result = holdFriendFolder(friend_folder_attribute, folderName);
if (result.isFail()) return result;
return result;
}
public Result releaseFriendFolder(string folderName)
{
var friend_folder_attribute = getFriendFolderAttribute();
var result = raiseErrorIfNotExistFolder(friend_folder_attribute, folderName);
if (result.isFail()) return result;
result = releaseFriendFolder(friend_folder_attribute, folderName);
if (result.isFail()) return result;
return result;
}
public Result changeFriendFolderLocation(string myGuid, string friendGuid, string folderName)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var friend_folder_attribute = getFriendFolderAttribute();
var result = raiseErrorIfNotExistFolder(friend_folder_attribute, folderName);
if (result.isFail()) return result;
var friend_agent_action = owner.getEntityAction<FriendAgentAction>();
var friends = friend_agent_action.getFriends();
friends.TryGetValue(friendGuid, out var friend);
NullReferenceCheckHelper.throwIfNull(friend, () => $"friend is null !!!");
var friend_attribute = friend.getEntityAttribute<FriendAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_attribute, () => $"friend_attribute is null !!!");
friend_attribute.modifiedEntityAttribute();
//폴더명이 동일하면 그냥 성공했다고 리턴 처리
if (true == friend_attribute.FolderName.Equals(folderName))
{
return result;
}
friend_attribute.FolderName = folderName;
return result;
}
public Result renameFriendFolderConditionCheck(string oldFolderName, string newFolderName)
{
var owner = getOwner();
var friend_folder_action = owner.getEntityAction<FriendFolderAction>();
NullReferenceCheckHelper.throwIfNull(friend_folder_action, () => $"friend_folder_action is null !!!");
var folder_folder_attribute = friend_folder_action.getFriendFolderAttribute();
var result = raiseErrorIfNotExistFolder(folder_folder_attribute, oldFolderName);
if (result.isFail()) return result;
result = raiseErrorIfExistFolder(folder_folder_attribute, newFolderName);
if (result.isFail()) return result;
result = raiseErrorIfDefaultFolder(oldFolderName);
if (result.isFail()) return result;
result = maxFolderNameLengthCheck(newFolderName);
if (result.isFail()) return result;
return result;
}
public async Task<Result> renameFriendFolder(string userGuid, string oldFolderName, string newFolderName)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var folder = getFriendFolder(oldFolderName);
var friend_agent_action = owner.getEntityAction<FriendAgentAction>();
NullReferenceCheckHelper.throwIfNull(friend_agent_action, () => $"friend_agent_action is null !!!");
var friends = friend_agent_action.getFriends();
//폴더명 수정
var friend_folder_Attribute = owner.getEntityAttribute<FriendFolderAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_folder_Attribute, () => $"friend_folder_Attribute is null !!!");
var result = new Result();
if (false == friend_folder_Attribute.m_folders.TryRemove(oldFolderName, out var folderValue))
{
var err_msg = $"friend_folder_attrib not exist folderName : {oldFolderName}, attrib : {JsonConvert.SerializeObject(friend_folder_Attribute)}";
result.setFail(ServerErrorCode.FolderNameNotExist, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
ServerCommon.FriendFolder new_folder = copyFriendFolder(folderValue);
new_folder.FolderName = newFolderName;
friend_folder_Attribute.m_folders.TryAdd(newFolderName, new_folder);
friend_folder_Attribute.modifiedEntityAttribute();
List<FriendInterlockCacheRequest> caches = new();
//관련 친구 데이터 수정
foreach (var friend in friends)
{
var friend_attribbute = friend.Value.getEntityAttribute<FriendAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_attribbute, () => $"friend_attribbute is null !!!");
if (friend_attribbute.FolderName.Equals(oldFolderName))
{
IFriendInterlockAction action = new RenameFriendFolderInterlockAction(owner, userGuid, friend_attribbute, newFolderName);
(result, var lock_cache) = await action.doInterLockAndGetCache();
if (result.isFail())
{
//여기서 에러나도 수정 transaction 은 진행되야 되기 때문에 continue 처리
Log.getLogger().error($"RenameFriendFolderInterlockAction error userGuid : /*owner.getUserGuid()트랜잭션안에서 이거 호출하면 안됨*/" +
$" , friend_attribbute : {JsonConvert.SerializeObject(friend_attribbute)}, newFolderName : {newFolderName}");
continue;
}
if (lock_cache != null)
{
caches.Add(lock_cache);
}
}
}
var server_logic = GameServerApp.getServerLogic();
var batch = new QueryBatchEx<QueryRunnerWithDocument>(owner, LogActionType.RenameFriendFolder, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
foreach (var cache in caches)
{
await cache.removeFirstCache();
}
return result;
}
public async Task<Result> deleteFriendFolder(string myGuid, string folderName)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var friend_folder_attribute = getFriendFolderAttribute();
var result = raiseErrorIfDefaultFolder(folderName);
if (result.isFail()) return result;
result = raiseErrorIfDefaultFolder(folderName);
if (result.isFail()) return result;
// 삭제하려는 폴더가 없으면 그냥 성공 처리
if (false == isFolderNameExist(friend_folder_attribute, folderName))
{
return new();
}
//폴더 삭제 처리
friend_folder_attribute.m_folders.TryRemove(folderName, out var folder);
friend_folder_attribute.modifiedEntityAttribute();
//db 업데이트 처리
//폴더 삭제 처리, 친구 리스트 돌면서 폴더명 기본으로 바꿔주기
var server_logic = GameServerApp.getServerLogic();
var friend_agent_action = owner.getEntityAction<FriendAgentAction>();
NullReferenceCheckHelper.throwIfNull(friend_agent_action, () => $"friend_agent_action is null !!!");
var friends = friend_agent_action.getFriends();
foreach (var friend in friends)
{
var friend_attribute = friend.Value.getEntityAttribute<FriendAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_attribute, () => $"friend_attribute is null !!!");
if (friend_attribute.FolderName.Equals(folderName))
{
IFriendInterlockAction interlock_action = new DeleteFriendFolderInterlockAction(owner, myGuid, friend_attribute);
result = await interlock_action.doInterlockAction();
if (result.isFail()) return result;
friend_attribute.modifiedEntityAttribute();
}
}
return result;
}
private ServerCommon.FriendFolder makeFriendFolder(string folderName)
{
ServerCommon.FriendFolder folder = new ServerCommon.FriendFolder();
folder.FolderName = folderName;
DateTime dt = DateTimeHelper.Current;
folder.CreateTime = dt;
folder.HoldTime = dt;
folder.IsHold = 0;
return folder;
}
private ServerCommon.FriendFolder copyFriendFolder(ServerCommon.FriendFolder folder)
{
ServerCommon.FriendFolder new_folder = new ServerCommon.FriendFolder();
new_folder.FolderName = folder.FolderName;
new_folder.CreateTime = folder.CreateTime;
new_folder.HoldTime = folder.HoldTime;
new_folder.IsHold = folder.IsHold;
return new_folder;
}
private Result holdFriendFolder(FriendFolderAttribute friendFolderAttribute, string folderName)
{
var result = new Result();
if (false == friendFolderAttribute.m_folders.TryGetValue(folderName, out var folder))
{
string err_msg = $"friend_folder_attrib tryGet Error folderName : {folderName}, attrib : {JsonConvert.SerializeObject(friendFolderAttribute)}";
result.setFail(ServerErrorCode.ServerLogicError, err_msg);
Log.getLogger().error(err_msg);
return result;
}
folder.IsHold = 1;
friendFolderAttribute.modifiedEntityAttribute();
return result;
}
private Result releaseFriendFolder(FriendFolderAttribute friend_folder_attribute, string folderName)
{
var result = new Result();
if (false == friend_folder_attribute.m_folders.TryGetValue(folderName, out var folder))
{
string err_msg = $"friend_folder_attrib tryGet Error folderName : {folderName}, folderAttrib : {JsonConvert.SerializeObject(friend_folder_attribute)} ";
result.setFail(ServerErrorCode.ServerLogicError, err_msg);
Log.getLogger().error(err_msg);
return result;
}
folder.IsHold = 0;
friend_folder_attribute.modifiedEntityAttribute();
return result;
}
public Result changeOrderType(Int32 orderType)
{
var result = new Result();
switch (orderType)
{
case (Int32)FriendFolderorderType.ALPHABETICAL:
case (Int32)FriendFolderorderType.STATEFUL:
break;
default:
var err_msg = $"FolderOdertypeInvalid OrderType = {orderType}";
result.setFail(ServerErrorCode.FolderOdertypeInvalid, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var friend_folder_attribute = owner.getEntityAttribute<FriendFolderAttribute>();
NullReferenceCheckHelper.throwIfNull(friend_folder_attribute, () => $"friend_folder_attribute is null !!!");
friend_folder_attribute.m_folder_order_type = (short)orderType;
friend_folder_attribute.modifiedEntityAttribute();
return result;
}
public FriendFolderAttribute getFriendFolderAttribute()
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var attribute = owner.getEntityAttribute<FriendFolderAttribute>();
NullReferenceCheckHelper.throwIfNull(attribute, () => $"attribute is null !!!");
return attribute;
}
private Result raiseErrorIfExistFolder(FriendFolderAttribute friendFolderAttribute, string folderName)
{
var result = new Result();
if (true == isFolderNameExist(friendFolderAttribute, folderName))
{
var err_msg = $"{folderName} is already exist but origin folders : {JsonConvert.SerializeObject(friendFolderAttribute)}";
result.set(ServerErrorCode.FolderNameAlreadyExist, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
private Result raiseErrorIfNotExistFolder(FriendFolderAttribute friendFolderAttribute, string folderName)
{
var result = new Result();
if (false == isFolderNameExist(friendFolderAttribute, folderName))
{
var err_msg = $"recved folderName is {folderName} but origin folders : {JsonConvert.SerializeObject(friendFolderAttribute)}";
result.set(ServerErrorCode.FolderNameNotExist, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
private bool isFolderNameExist(FriendFolderAttribute friendFolderAttribute, string makeFolderName)
{
return friendFolderAttribute.m_folders.ContainsKey(makeFolderName);
}
private Result raiseErrorIfDefaultFolder(string folderName)
{
var result = new Result();
if (folderName.Equals(ServerCommon.Constant.FRIEND_FOLDER_DEFUALT_NAME))
{
result.set(ServerErrorCode.FolderReNameCannotDefault, $"folderName is {folderName}");
return result;
}
return result;
}
private Result maxFolderNameLengthCheck(string folderName)
{
var result = new Result();
if (folderName.Length > MetaHelper.GameConfigMeta.FriendFolderNameMaxLength)
{
result.set(ServerErrorCode.FolderNameExceededLength, $"folderName is {folderName}");
return result;
}
return result;
}
private Result folderCountCheck(FriendFolderAttribute friendFolderAttribute)
{
var result = new Result();
if (friendFolderAttribute.m_folders.Count >= MetaHelper.GameConfigMeta.FriendFolderMaxCount)
{
var err_msg = $"folderInfo.Folders.Count is {friendFolderAttribute.m_folders.Count}, Server Max Count = {MetaHelper.GameConfigMeta.FriendFolderMaxCount}";
result.set(ServerErrorCode.FolderCountExceed, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
private Result folderHoldCountCheck(FriendFolderAttribute friendFolderAttribue)
{
var result = new Result();
int holdCount = 0;
foreach (var folder in friendFolderAttribue.m_folders.Values)
{
if (folder.IsHold == 1) holdCount++;
}
if (holdCount >= MetaHelper.GameConfigMeta.FriendFolderMaxHoldCount)
{
var err_msg = $"folderInfo.Folders.Hold_Count is {holdCount}, Server Max Hold Count = {MetaHelper.GameConfigMeta.FriendFolderMaxHoldCount}";
result.set(ServerErrorCode.FolderNameAlreadyMaxHoldCount, err_msg);
Log.getLogger().error(err_msg);
return result;
}
return result;
}
}
}

View File

@@ -0,0 +1,291 @@
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;
}
}

View File

@@ -0,0 +1,244 @@
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<Result> 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<Result> 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<Result> replyableCheck(List<string> 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<MyhomeInviteInfo>(received_invite);
if (origin_data is null) continue;
var update_data = JsonConvert.DeserializeObject<MyhomeInviteInfo>(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<AccountBaseAttrib>();
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<Result> 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<GameZoneMoveAction>();
(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;
}
}
}

View File

@@ -0,0 +1,146 @@
using Nettention.Proud;
using OtpNet;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using ServerCore; using ServerBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static ClientToLoginMessage.Types;
namespace GameServer
{
public class KickFriendsFromMyHomeAction : EntityActionBase
{
public KickFriendsFromMyHomeAction(EntityBase owner)
: base(owner)
{
}
public override Task<Result> onInit()
{
var result = new Result();
return Task.FromResult(result);
}
public override void onClear()
{
return;
}
public async Task<Result> setKickableFriendsInfo(KickFriendResult kickFriendResult)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => "Player is null !!!");
var location_attribute = owner.getEntityAttribute<LocationAttribute>();
NullReferenceCheckHelper.throwIfNull(location_attribute, () => $"LocationAttribute is null !!! - player:{owner.toBasicString()}");
var myhome_action = owner.getEntityAction<FriendInviteMyhomeAction>();
NullReferenceCheckHelper.throwIfNull(myhome_action, () => $"FriendInviteMyhomeAction is null !!! - player:{owner.toBasicString()}");
var myhome_location = location_attribute.CurrentIndunLocation;
var instance_room_Id = myhome_location.InstanceRoomId;
var instance_meta_Id = myhome_location.InstanceMetaId;
var result = myhome_action.isCurrentLocationMyHome(instance_meta_Id);
if (result.isFail()) return result;
InstanceRoomStorage room_storage = new InstanceRoomStorage();
room_storage.Init(GameServerApp.getServerLogic().getRedisDb(), string.Empty);
InstanceRoomInfo? instance_room = await room_storage.GetInstanceRoomInfo(instance_room_Id);
if (instance_room == null)
{
string err_msg = $"{owner.getAccountId()} Not found InstanceRoomInfo. InstanceRoomId:{instance_room_Id}";
result.setFail(ServerErrorCode.NotExistInstanceRoom, err_msg);
return result;
}
List<string> room_members = await room_storage.GetInstanceRoomMemberList(instance_room.roomId);
foreach (string member in room_members)
{
if (member.Equals(owner.getAccountId())) continue;
kickFriendResult.getNeedNotiMembers().Add(member);
}
if (kickFriendResult.getNeedNotiMembers().Count == 0)
{
string err_msg = $"Room member count is zero. InstanceRoomId:{instance_room_Id}";
result.setFail(ServerErrorCode.FriendKickMemberNotExist, err_msg);
return result;
}
return result;
}
public async Task<Result> sendKickNoti(KickFriendResult kickFriendResult)
{
//noti 보내야한다.
await Task.Delay(3000);
var result = new Result();
var server_logic = GameServerApp.getServerLogic();
var plyaer_manager = server_logic.getPlayerManager();
foreach (var member in kickFriendResult.getNeedNotiMembers())
{
if(false == plyaer_manager.tryGetUserByPrimaryKey(member, out var player))
{
string err_msg = $"Not found player. member:{member}";
Log.getLogger().warn(err_msg);
continue;
}
//noti 전송
send_GS2C_NTF_SERVER_INFO_BY_FRIEND_KICKED_NOTI(player);
}
return result;
}
private bool send_GS2C_NTF_SERVER_INFO_BY_FRIEND_KICKED_NOTI(Player player)
{
ClientToGame msg = new ClientToGame();
msg.Message = new ClientToGameMessage();
msg.Message.ServerInfoByFriendKickedNoti = new();
msg.Message.ServerInfoByFriendKickedNoti.ServerInfo = new ServerConnectInfo
{
ServerAddr = string.Empty,
ServerPort = 0,
Otp = string.Empty
};
if (false == GameServerApp.getServerLogic().onSendPacket(player, msg)) return false;
return true;
}
public void kickFriendsFromMyHome()
{
string err_msg = $"need code implement !!!!";
Log.getLogger().error(err_msg);
}
}
public class KickFriendResult
{
List<string> m_need_noti_members = new();
List<FriendErrorMember> m_error_member = new();
public List<FriendErrorMember> getErrorMembers()
{
return m_error_member;
}
public List<string> getNeedNotiMembers()
{
return m_need_noti_members;
}
}
}

View File

@@ -0,0 +1,114 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace GameServer;
public class ReplyReceivedFriendRequestAction : EntityActionBase
{
public ReplyReceivedFriendRequestAction(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> replyReceivedFriendRequest(string myGuid, string targetGuid, int replyType)
{
var result = new Result();
switch (replyType)
{
case (int)FriendRequestReplyType.Accept:
result = await addFriend(myGuid, targetGuid);
if (result.isFail())
{
Log.getLogger().error("replyReceivedFriendRequest addFriend error");
return result;
}
break;
case (int)FriendRequestReplyType.Refuse:
result = await refuseFriend(myGuid, targetGuid);
if (result.isFail())
{
Log.getLogger().error("replyReceivedFriendRequest refuseFriend error");
return result;
}
break;
}
return result;
}
private async Task<Result> addFriend(string myGuid, string friendGuid)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var friend_agent_action = owner.getEntityAction<FriendAgentAction>();
var result = friend_agent_action.friendMaxCountCheck();
if (result.isFail()) return result;
result = friend_agent_action.raiseErrorIfExistFriend(friendGuid);
if (result.isFail()) return result;
var server_logic = GameServerApp.getServerLogic();
var friend_request_cache = new FriendReqCacheRequest(owner, myGuid, friendGuid, server_logic.getRedisConnector());
//요청이 존재하는지 체크하면서 해당 요청 가져온다.
(result, var req) = await friend_agent_action.receivedRquestsExitstCheck(friend_request_cache, friendGuid);
if (result.isFail() || req is null) return result;
//요청 만료시간이 지나버린경우
DateTime now = DateTimeHelper.Current;
var expire_time = req.m_request_time.AddSeconds(MetaHelper.GameConfigMeta.SentFriendRequestValidTime);
if (now > expire_time)
{
var err_msg = $"friendRequestList expired targetGuid = {friendGuid}, m_request_time = {req.m_request_time}, expire_time : {expire_time}, now : {now}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.AddFriendAlreadyExpired, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
result = await friend_request_cache.deleteFriendByReply();
if (result.isFail()) return result;
return result;
}
private async Task<Result> refuseFriend(string myGuidm, string friendGuid)
{
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var server_logic = GameServerApp.getServerLogic();
FriendReqCacheRequest cache = new FriendReqCacheRequest(owner, myGuidm, friendGuid, server_logic.getRedisConnector());
var result = await cache.refuseFriendRequest();
return result;
}
}

View File

@@ -0,0 +1,127 @@
using Google.Protobuf.WellKnownTypes;
using ServerCommon;
using ServerCommon.Cache;
using ServerCore; using ServerBase;
namespace GameServer
{
//친구 요청에 관한 것만 여기 모은다.
public class SendFriendRequestAction : EntityActionBase
{
public SendFriendRequestAction(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> addRequestToCache(string nickname, string friendGuid)
{
var result = new Result();
var owner = getOwner() as Player;
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
var my_guid = owner.getUserGuid();
//나한테 요청 보낼 수 없다.
if (friendGuid.Equals(my_guid))
{
var err_msg = $"Can't Send To Self myGuid = {my_guid} targetGuid : {friendGuid}, {toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestCantSendToSelf, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var friend_agent_action = owner.getEntityAction<FriendAgentAction>();
//이미 친구인 경우
result = friend_agent_action.raiseErrorIfExistFriend(friendGuid);
if(result.isFail()) return result;
//친구 맥스 초과
result = friend_agent_action.friendMaxCountCheck();
if (result.isFail()) return result;
//'내가 차단한 유저라 보낼수 없다'
var block_action = owner.getEntityAction<BlockUserAgentAction>();
if (true == block_action.isBlockUser(friendGuid))
{
var err_msg = $"Can't Send To Block User myGuid = {my_guid} targetGuid : {friendGuid}, {toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestCannotSendBlockUser, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var server_logic = GameServerApp.getServerLogic();
var friend_request_cache = new FriendReqCacheRequest(owner, my_guid, friendGuid, server_logic.getRedisConnector());
//이미 요청 보냈다
var sended_reqs = await friend_request_cache.getSendedFriendRequests();
(var is_sended, var req) = isSendedRequest(sended_reqs, friendGuid);
if (true == is_sended)
{
//이미 요청 보낸것이므로 예외 처리
string err_msg = $"requeat friend already send guid : {my_guid}, friend_guid : {friendGuid}, {toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestAlreadySend, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
//이미 요청 받았다
var received_reqs = await friend_request_cache.getReceivedFriendRequests();
(var is_received, var _) = isReceivedRequest(received_reqs, friendGuid);
if (true == is_received)
{
//이미 요청 받은것이므로 예외 처리
string err_msg = $"requeat friend already receive guid : {my_guid}, friend_guid : {friendGuid}, {toBasicString()}";
result.setFail(ServerErrorCode.FriendRequestAlreadyReceive, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
//lock
DateTime now = DateTime.UtcNow;
IFriendInterlockAction interlock_action = new SendFriendRequestInterlockAction(owner, owner.getUserGuid(), friendGuid, now);
result = await interlock_action.doInterlockAction();
if(result.isFail()) return result;
return result;
}
public (bool, FriendRequestCache?) isSendedRequest(List<FriendRequestCache> sended_reqs, string friendGuid)
{
foreach (var req in sended_reqs)
{
if (req.m_receiver_guid.Equals(friendGuid))
{
return (true, req);
}
}
return (false, null);
}
public (bool, FriendRequestCache?) isReceivedRequest(List<FriendRequestCache> received_reqs, string friendGuid)
{
foreach (var req in received_reqs)
{
if (req.m_sender_guid.Equals(friendGuid))
{
return (true, req);
}
}
return (false, null);
}
}
}