Files
2025-05-01 07:20:41 +09:00

294 lines
14 KiB
C#

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<Result> 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<QuestAction>();
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<QuestAttribute>();
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<UgqInfoAction>();
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<AccountAttribute>();
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {player.toBasicString()}");
var batch = new QueryBatchEx<QueryRunnerWithDocument>(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<EndQuestAction>();
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<MoneyAction>();
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<QuestAcceptAction>();
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<QuestAction>();
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<ServerCommon.Quest> { accept_quest_var.m_new_quest_nullable }));
ack.UgqGameQuestDataForClients.AddRange(new List<UgqGameQuestDataForClient>() { 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<AccountAttribute>();
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<QuestAction>();
NullReferenceCheckHelper.throwIfNull(quest_action, () => $"quest_action is null !!! - {player.toBasicString()}");
var account_attribute = player!.getEntityAttribute<AccountAttribute>();
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<QuestAttribute>();
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<QuestAcceptAction>();
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<QueryRunnerWithDocument>(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<QuestAction>();
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<ServerCommon.Quest> { new_quest }));
//ack.UgqGameQuestDataForClients.AddRange(new List<UgqGameQuestDataForClient>() { new_game_quest_data.UgqGameQuestDataForClient });
ack.DeletedComposedQuestId = QuestHelper.convertQuestIdAndRevisionToUgqQuestId(questId, questRevision);
return (result, ack, (UInt32)new_quest_data.Revision);
}
}