using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using ServerCore; using ServerBase; using ServerCommon; using MetaAssets; using UGQDatabase.Models; using static ClientToGameRes.Types; namespace GameServer; public class UgqAssignAction : EntityActionBase { public UgqAssignAction(EntityBase owner) : base(owner) { } public override void onClear() { return; } public override async Task onInit() { await Task.CompletedTask; var result = new Result(); return result; } public async Task<(Result, ClientToGameRes.Types.GS2C_ACK_UGQ_ASSIGN)> ugqAssign(UInt32 questId, UInt32 questRevision) { //Ugq 정보 호출해서 가져온다. questID로만 가져와서 처리 var player = getOwner() as Player; ArgumentNullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var user_guid = player.getUserGuid(); var server_logic = GameServerApp.getServerLogic(); var ugq_api_manager = server_logic.GetUqgApiManager(); var ack = new ClientToGameRes.Types.GS2C_ACK_UGQ_ASSIGN(); //해당 퀘스트에 대한 정보를 가지고 있는지 체크 var quest_action = player!.getEntityAction(); var owned_ugq_quests = quest_action.getUgqQuests(); var result = new Result(); foreach (var owned_quest in owned_ugq_quests) { var owned_quest_attribute = owned_quest.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(owned_quest_attribute, () => $"owned_quest_attribute is null !!! - {player.toBasicString()}"); if (owned_quest_attribute.QuestId == questId && owned_quest_attribute.UgqInfo.QuestRevision > 0) { result.setFail(ServerErrorCode.UgqAlreadyOwnedOldRevisionQuest, $"Ugq already owned, requestQuest : {questId}, {questRevision}, ownedQuest : {owned_quest_attribute.QuestId}, {owned_quest_attribute.UgqInfo.QuestRevision}"); return (result, ack); } } //호출했는데 Revision 에 해당하는 퀘스트가 사라졌을 수도 있다. (오너가 비활성화 처리 ) 이때 에러 처리 var ugq_info_action = player!.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugq_info_action, () => $"ugq_info_action is null !!! - {player.toBasicString()}"); result = await ugq_info_action.ugqLatestRevisionCheck(questId, questRevision); if (result.isFail()) return (result, ack); (result, var quest_meta_all_base_info) = await QuestMetaManager.It.getQuestMeta(player, questId, questRevision, QuestContentState.Live); if (result.isFail()) return (result, ack); var game_quest_data = quest_meta_all_base_info.m_quest_data_entity; NullReferenceCheckHelper.throwIfNull(game_quest_data, () => $"game_quest_data is null !!! - {player.toBasicString()}"); var quest_base_info = quest_meta_all_base_info.m_quest_base_info; NullReferenceCheckHelper.throwIfNull(quest_base_info, () => $"quest_base_info is null !!! - {player.toBasicString()}"); if (true == game_quest_data.Shutdown) { result.setFail(ServerErrorCode.UgqQuestShutdowned, $"Quest is shutdowned : {questId}, {questRevision}"); return (result, ack); } if (player.getUserGuid().Equals(game_quest_data.UserGuid)) { result.setFail(ServerErrorCode.UgqAssignCannotOwnedQuest, $"owned Ugq cannot assign : {questId}, {questRevision}"); return (result, ack); } var new_quest = new ServerCommon.Quest(player, player.getUserGuid()); var accept_quest_var = new AcceptQuestVariable(quest_base_info, false, new_quest); var fn_ugc_quest_assign = async delegate () { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var user_guid = player.getUserGuid(); var grade = game_quest_data.GradeType; var account_attribute = player!.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {player.toBasicString()}"); var batch = new QueryBatchEx(player, LogActionType.UgqAssign, server_logic.getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); batch.addQuery(new QueryFinal()); } var language_type = account_attribute.LanguageType; var cost = UgqMetaHelper.getUgqCost(grade); var end_quest_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(end_quest_action, () => $"end_quest_action is null !!! - {player.toBasicString()}"); var has_end_quest = end_quest_action.hasEndQuest(questId, questRevision); if (cost > 0 && has_end_quest == false) { //등급별 UgqUsageFeeType 가져온다. var currency_type = UgqMetaHelper.getUgqUsageFeeType(grade); var money_action = player.getEntityAction(); var change_result = await money_action.changeMoney(currency_type, -cost); if (change_result.isFail()) return change_result; accept_quest_var.m_quest_cost = cost; } //퀘스트 정보 만들어서 저장 var quest_accept_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(end_quest_action, () => $"quest_accept_action is null !!! - {player.toBasicString()}"); var result = quest_accept_action.newQuestAssign(ref accept_quest_var); if (result.isFail()) return result; ArgumentNullReferenceCheckHelper.throwIfNull(accept_quest_var, () => $"accept_quest_var is null !!! - {player.toBasicString()}"); batch.appendBusinessLog(new UgqAssignBusinessLog(questId, questRevision)); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) return result; ArgumentNullReferenceCheckHelper.throwIfNull(accept_quest_var.m_new_quest_nullable, () => $"accept_quest_var.m_new_quest_nullable is null !!! - {player.toBasicString()}"); var quest_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(quest_action, () => $"quest_action is null !!! - {player.toBasicString()}"); quest_action.addNewQuest(questId, accept_quest_var.m_new_quest_nullable); var found_transaction_runner = player.findTransactionRunner(TransactionIdType.PrivateContents); NullReferenceCheckHelper.throwIfNull(found_transaction_runner, () => $"found_transaction_runner is null !!! - {player.toBasicString()}"); var common_result = found_transaction_runner.getCommonResult(); //여기서 데이터 만든다 ack.QuestMetaInfos.AddRange(game_quest_data.QuestScriptMetas); ack.Quests.AddRange(await QuestMetaHelper.makeQuestInfoData(new List { accept_quest_var.m_new_quest_nullable })); ack.UgqGameQuestDataForClients.AddRange(new List() { game_quest_data.UgqGameQuestDataForClient }); ack.CommonResult = common_result; return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "UgqQuestAssign", fn_ugc_quest_assign); if (result.isFail()) { var err_msg = $"Failed to runTransactionRunnerSafely : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, ack); } var account_attribute = player!.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {player.toBasicString()}"); var language_type = account_attribute.LanguageType; //퀘스트 assign 후 api 서버 쪽으로 set-quest-accepted 전달 var api_result = await ugq_api_manager.setUgqQuestAccepted(user_guid, questId, questRevision, language_type); //임시 테스트 를 위해서 TestQeustData를 가져온다. if(api_result.isFail()) { //로그만 남긴다. Log.getLogger().error($"Failed to setUgqQuestAccepted : {api_result.toBasicString()} - {player.toBasicString()}"); } return (result, ack); } public async Task<(Result, GS2C_ACK_UGQ_REASSIGN?, UInt32 newQuestRevision)> ugqReAssign(UInt32 questId, UInt32 questRevision) { var ack = new GS2C_ACK_UGQ_REASSIGN(); //api server에서 최신 정보를 가져온다. var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var ugq_api_manager = server_logic.GetUqgApiManager(); var quest_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(quest_action, () => $"quest_action is null !!! - {player.toBasicString()}"); var account_attribute = player!.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {player.toBasicString()}"); var language_type = account_attribute.LanguageType; var result = quest_action.getQuest(EQuestType.UGQ, questId, out var old_quest); if (result.isFail()) return (result, null, 0); NullReferenceCheckHelper.throwIfNull(old_quest, () => $"old_quest is null !!! - {player.toBasicString()}"); (result, var new_quest_data) = await ugq_api_manager.getUgqLatestQuestData(questId, language_type); if (result.isFail()) return (result, null, 0); NullReferenceCheckHelper.throwIfNull(new_quest_data, () => $"new_quest_data is null !!! - {player.toBasicString()}"); (result, var new_quest_meta_all_base_info) = await QuestMetaManager.It.getQuestMeta(player, questId, (UInt32)new_quest_data.Revision, QuestContentState.Live); if (result.isFail()) return (result, ack, 0); NullReferenceCheckHelper.throwIfNull(new_quest_meta_all_base_info, () => $"new_quest_meta_all_base_info is null !!! - {player.toBasicString()}"); var new_game_quest_data = new_quest_meta_all_base_info.m_quest_data_entity; var new_quest_base_info = new_quest_meta_all_base_info.m_quest_base_info; NullReferenceCheckHelper.throwIfNull(new_quest_base_info, () => $"new_quest_base_info is null !!! - {player.toBasicString()}"); var new_quest = new ServerCommon.Quest(player, player.getUserGuid()); var fn_transaction_runner = async delegate () { var result = new Result(); var old_quest_attribute = old_quest.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(old_quest_attribute, () => $"old_quest_attribute is null !!! - {player.toBasicString()}"); old_quest_attribute.deleteEntityAttribute(); var new_accept_quest_var = new AcceptQuestVariable(new_quest_base_info, false, new_quest); new_accept_quest_var.m_quest_cost = 0; new_accept_quest_var.m_quest_type = EQuestType.UGQ; var quest_accept_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(quest_accept_action, () => $"quest_accept_action is null !!! - {player.toBasicString()}"); result = quest_accept_action.newQuestAssign(ref new_accept_quest_var); var batch = new QueryBatchEx(player, LogActionType.UgqReAssign, server_logic.getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } batch.appendBusinessLog(new UgqReAssignBusinessLog(questId, (UInt32)new_quest_data.Revision)); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } NullReferenceCheckHelper.throwIfNull(new_accept_quest_var.m_new_quest_nullable, () => $"new_accept_quest_var.m_new_quest_nullable is null !!! - {player.toBasicString()}"); var quest_type = EnumHelper.convertEnumTypeAndValueStringToEnum(new_quest_base_info.QuestType, EQuestType.NORMAL); var quest_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(quest_action, () => $"quest_action is null !!! - {player.toBasicString()}"); quest_action.deleteQuest(quest_type, questId); quest_action.addNewQuest(questId, new_accept_quest_var.m_new_quest_nullable); return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "UgqReAssign", fn_transaction_runner); if (result.isFail()) { var err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return (result, null, 0); } //여기서 데이터 만든다 //ack.QuestMetaInfos.AddRange(new_game_quest_data.QuestScriptMetas); //ack.Quests.AddRange(await QuestMetaHelper.makeQuestInfoData(new List { new_quest })); //ack.UgqGameQuestDataForClients.AddRange(new List() { new_game_quest_data.UgqGameQuestDataForClient }); ack.DeletedComposedQuestId = QuestHelper.convertQuestIdAndRevisionToUgqQuestId(questId, questRevision); return (result, ack, (UInt32)new_quest_data.Revision); } }