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 onInit() { var result = new Result(); return await Task.FromResult(result); } public override void onClear() { return; } public async Task loadFriendFolder() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var server_logic = GameServerApp.getServerLogic(); var batch = new QueryBatchEx(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(); 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(); 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(); var friends = friend_agent_action.getFriends(); friends.TryGetValue(friendGuid, out var friend); NullReferenceCheckHelper.throwIfNull(friend, () => $"friend is null !!!"); var friend_attribute = friend.getEntityAttribute(); 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(); 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 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(); NullReferenceCheckHelper.throwIfNull(friend_agent_action, () => $"friend_agent_action is null !!!"); var friends = friend_agent_action.getFriends(); //폴더명 수정 var friend_folder_Attribute = owner.getEntityAttribute(); 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 caches = new(); //관련 친구 데이터 수정 foreach (var friend in friends) { var friend_attribbute = friend.Value.getEntityAttribute(); 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(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 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(); 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(); 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(); 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(); 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; } } }