328 lines
13 KiB
C#
328 lines
13 KiB
C#
using Google.Protobuf;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class AcceptQuestVariable
|
|
{
|
|
public QuestBaseInfo? m_quest_base_info_nullable { get; set; } = null;
|
|
public bool m_is_mail_quest { get; set; } = false;
|
|
public ServerCommon.Quest? m_new_quest_nullable { get; set; } = null;
|
|
public MetaAssets.EQuestType m_quest_type { get; set; } = MetaAssets.EQuestType.NONE;
|
|
public Int32 m_quest_cost { get; set; } = 0;
|
|
|
|
//public CommonResult m_common_result { get; set; } = new();
|
|
public List<UInt32> assignable_quests { get; set; } = new();
|
|
|
|
|
|
public AcceptQuestVariable()
|
|
{
|
|
m_quest_base_info_nullable = null;
|
|
m_is_mail_quest = false;
|
|
m_quest_type = MetaAssets.EQuestType.NONE;
|
|
m_new_quest_nullable = null;
|
|
}
|
|
|
|
public AcceptQuestVariable(QuestBaseInfo metaInfo, bool isMailQuest, ServerCommon.Quest quest, Int32 questCost = 0)
|
|
{
|
|
m_quest_base_info_nullable = metaInfo;
|
|
m_is_mail_quest = isMailQuest;
|
|
m_new_quest_nullable = quest;
|
|
|
|
if (false == EnumHelper.tryParse(metaInfo.QuestType, out MetaAssets.EQuestType quest_type))
|
|
{
|
|
m_quest_type = MetaAssets.EQuestType.NONE;
|
|
}
|
|
else m_quest_type = quest_type;
|
|
|
|
m_quest_cost = questCost;
|
|
}
|
|
|
|
}
|
|
|
|
public class QuestAcceptAction : EntityActionBase
|
|
{
|
|
public QuestAcceptAction(EntityBase owner)
|
|
: base(owner)
|
|
{}
|
|
|
|
public override async Task<Result> onInit()
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
var result = new Result();
|
|
|
|
return result;
|
|
}
|
|
|
|
public override void onClear()
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
public async Task<Result> acceptQuestConditionCheck(UInt32 questId, AcceptQuestVariable acceptQuestVar)
|
|
{
|
|
var owner = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!");
|
|
var quest_action = owner.getEntityAction<QuestAction>();
|
|
var quest_mail_action = owner.getEntityAction<QuestMailAction>();
|
|
var end_quest_action = owner.getEntityAction<EndQuestAction>();
|
|
NullReferenceCheckHelper.throwIfNull(quest_action);
|
|
NullReferenceCheckHelper.throwIfNull(quest_mail_action);
|
|
NullReferenceCheckHelper.throwIfNull(end_quest_action);
|
|
|
|
|
|
|
|
//해당 퀘스트 정보 불러오기
|
|
(var result, var quest_meta_all_base_info) = await QuestMetaManager.It.getQuestMeta(questId);
|
|
if (result.isFail()) return result;
|
|
var quest_base_info = quest_meta_all_base_info.m_quest_base_info;
|
|
|
|
acceptQuestVar.m_quest_base_info_nullable = quest_base_info;
|
|
NullReferenceCheckHelper.throwIfNull(acceptQuestVar.m_quest_base_info_nullable, () => $"acceptQuestVar.m_quest_base_info_nullable is null !!!");
|
|
if (false == EnumHelper.tryParse(acceptQuestVar.m_quest_base_info_nullable.QuestType, out MetaAssets.EQuestType quest_type))
|
|
{
|
|
result.setFail(ServerErrorCode.ServerLogicError, $"QuestType Parse Failed : {acceptQuestVar.m_quest_base_info_nullable.QuestType}");
|
|
return result;
|
|
}
|
|
acceptQuestVar.m_quest_type = quest_type;
|
|
|
|
//현재 보유중인 퀘스트인지 체크
|
|
quest_action.getQuest(quest_type, questId, out var existedQuest);
|
|
if (existedQuest is not null)
|
|
{
|
|
result.setFail(ServerErrorCode.QuestAlreadyExist, $"Quest Already Exist quest Type : {acceptQuestVar.m_quest_base_info_nullable.QuestType}, questId : {questId}");
|
|
return result;
|
|
}
|
|
|
|
|
|
//메일로 받는 경우 메일 가지고 있는지 체크
|
|
acceptQuestVar.m_is_mail_quest = acceptQuestVar.m_quest_base_info_nullable.AssignType.Equals(MetaAssets.EAssignType.MAIL.ToString());
|
|
if (acceptQuestVar.m_is_mail_quest)
|
|
{
|
|
result = quest_mail_action.hasQuestMail(quest_type, questId, true);
|
|
if (result.isFail()) return result;
|
|
}
|
|
|
|
//이미 완료한 퀘스트 인지 체크
|
|
result = end_quest_action.endQuestCheck(quest_type, questId, 0);
|
|
if (result.isFail()) return result;
|
|
|
|
|
|
//내가 들고 있는 퀘스트의 전체 타입 수를 정리 하고 이미 퀘스트가 꽉차서 받을 수 없으면 에러 처리
|
|
result = quest_action.assignableQuestCheckByQuestType(acceptQuestVar.m_quest_type);
|
|
if (result.isFail()) return result;
|
|
|
|
return result;
|
|
}
|
|
|
|
public (Result, AcceptQuestVariable) acceptQuestByNpcDialogue(QuestBaseInfo questMetaInfo)
|
|
{
|
|
var owner = getOwner() as Player;
|
|
ArgumentNullException.ThrowIfNull(owner);
|
|
|
|
var new_quest = new ServerCommon.Quest(owner, owner.getUserGuid());
|
|
ArgumentNullException.ThrowIfNull(new_quest);
|
|
|
|
var quest_attribute = new_quest.getEntityAttribute<QuestAttribute>();
|
|
ArgumentNullException.ThrowIfNull(quest_attribute);
|
|
AcceptQuestVariable acceptQuestVar = new(questMetaInfo, false, new_quest);
|
|
|
|
var result = newQuestAssign(ref acceptQuestVar);
|
|
|
|
if (result.isFail()) { return (result, acceptQuestVar); }
|
|
|
|
return (result, acceptQuestVar);
|
|
}
|
|
|
|
public async Task<(Result, AcceptQuestVariable?)> questAccept(UInt32 questId)
|
|
{
|
|
var owner = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(owner);
|
|
|
|
var quest_action = owner.getEntityAction<QuestAction>();
|
|
NullReferenceCheckHelper.throwIfNull(quest_action);
|
|
|
|
(var result, var quest_meta_all_base_info) = await QuestMetaManager.It.getQuestMeta(questId);
|
|
if (result.isFail()) return (result, null);
|
|
var quest_base_info = quest_meta_all_base_info.m_quest_base_info;
|
|
NullReferenceCheckHelper.throwIfNull(quest_base_info, () => $"quest_base_info is null !!!");
|
|
|
|
var new_quest = new ServerCommon.Quest(owner, owner.getUserGuid());
|
|
|
|
AcceptQuestVariable acceptQuestVar = new(quest_base_info, false, new_quest);
|
|
result = newQuestAssign(ref acceptQuestVar);
|
|
if (result.isFail()) return (result, null);
|
|
|
|
return (result, acceptQuestVar);
|
|
}
|
|
|
|
public Result makeNewQuestAssignInfo(ref AcceptQuestVariable acceptQuestVar, Int32 cost = 0)
|
|
{
|
|
var result = new Result();
|
|
var owner = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(owner);
|
|
|
|
var quest_meta = acceptQuestVar.m_quest_base_info_nullable;
|
|
NullReferenceCheckHelper.throwIfNull(quest_meta, () => $"quest_meta is null !!!");
|
|
acceptQuestVar.m_new_quest_nullable = new ServerCommon.Quest(owner, owner.getUserGuid());
|
|
|
|
var quest_attribute = acceptQuestVar.m_new_quest_nullable.getEntityAttribute<QuestAttribute>();
|
|
ArgumentNullException.ThrowIfNull(quest_attribute);
|
|
|
|
DateTime nowDt = DateTimeHelper.Current;
|
|
|
|
quest_attribute.QuestId = quest_meta.QuestId;
|
|
quest_attribute.QuestType = acceptQuestVar.m_quest_type;
|
|
quest_attribute.UgqInfo.QuestRevision = quest_meta.QuestRevision;
|
|
quest_attribute.UgqInfo.QuestCost = cost;
|
|
quest_attribute.UgqInfo.UqgState = quest_meta.UgqState;
|
|
quest_attribute.QuestAssignTime = nowDt;
|
|
quest_attribute.CurrentTaskNum = 1;
|
|
quest_attribute.CurrentTaskComplete = 0;
|
|
quest_attribute.TaskStartTime = nowDt;
|
|
quest_attribute.QuestCompleteTime = nowDt;
|
|
quest_attribute.IsComplete = 0;
|
|
quest_attribute.HasTimer = 0;
|
|
quest_attribute.TimerCompleteTime = nowDt;
|
|
quest_attribute.CompletedIdxStrings = new();
|
|
|
|
if (false == quest_meta.QuestTaskGroupList.TryGetValue(quest_attribute.CurrentTaskNum, out var quest_task_info))
|
|
{
|
|
result.setFail(ServerErrorCode.QuestInvalidValue, $"questEventInfo InvalidData questId = {quest_attribute.QuestId}, info.CurrentTaskNum : {quest_attribute.CurrentTaskNum}");
|
|
return result;
|
|
}
|
|
|
|
quest_attribute.ActiveEvents.AddRange(QuestManager.It.getActiveEventStrings(quest_attribute, quest_task_info));
|
|
|
|
if (quest_task_info.HasCounter)
|
|
{
|
|
quest_attribute.HasCounter = (quest_task_info.HasCounter ? 1 : 0);
|
|
quest_attribute.MinCounter = quest_task_info.MinCounter;
|
|
quest_attribute.MaxCounter = quest_task_info.MaxCounter;
|
|
quest_attribute.CurrentCounter = quest_task_info.MinCounter;
|
|
}
|
|
if (quest_task_info.HasTimer)
|
|
{
|
|
quest_attribute.HasCounter = (quest_task_info.HasCounter ? 1 : 0);
|
|
quest_attribute.TimerCompleteTime = nowDt.AddSeconds(quest_task_info.RemainTime);
|
|
}
|
|
|
|
if (quest_task_info.HasAssignableQuest)
|
|
{
|
|
acceptQuestVar.assignable_quests.AddRange(quest_task_info.AssignableQuestIds);
|
|
|
|
}
|
|
quest_attribute.newEntityAttribute();
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
public async Task<Result> reAssignQuest(UInt32 questId, UInt32 questRevision)
|
|
{
|
|
(var result, var quest) = await questAcceptWithTransaction(questId, questRevision, 0);
|
|
return result;
|
|
}
|
|
|
|
|
|
public async Task<(Result, ServerCommon.Quest?)> questAcceptWithTransaction(UInt32 questId, UInt32 questRevision, int recursiveCount)
|
|
{
|
|
var result = new Result();
|
|
if (recursiveCount > 10)
|
|
{
|
|
var err_msg = $"recursiveCount > 10 !!! : {recursiveCount}";
|
|
Log.getLogger().error(err_msg);
|
|
result.setFail(ServerErrorCode.ServerLogicError, err_msg);
|
|
return (result, null);
|
|
}
|
|
recursiveCount += 1;
|
|
|
|
var player = getOwner() as Player;
|
|
ArgumentNullException.ThrowIfNull(player);
|
|
|
|
var quest_action = player.getEntityAction<QuestAction>();
|
|
ArgumentNullException.ThrowIfNull(quest_action);
|
|
|
|
(result, var quest_meta_all_base_info) = await QuestMetaManager.It.getQuestMeta(player, questId, questRevision);
|
|
if (result.isFail()) return (result, null);
|
|
var quest_base_info = quest_meta_all_base_info.m_quest_base_info;
|
|
NullReferenceCheckHelper.throwIfNull(quest_base_info, () => $"quest_base_info is null !!!");
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
NullReferenceCheckHelper.throwIfNull(server_logic);
|
|
var new_quest = new ServerCommon.Quest(player, player.getUserGuid());
|
|
NullReferenceCheckHelper.throwIfNull(new_quest);
|
|
AcceptQuestVariable acceptQuestVar = new(quest_base_info, false, new_quest);
|
|
|
|
var fn_quest_accept = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
result = newQuestAssign(ref acceptQuestVar);
|
|
if (result.isFail()) return result;
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.None, server_logic.getDynamoDbClient());
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLog(new QuestAcceptBusinessLog(questId, questRevision, acceptQuestVar.m_quest_type));
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail()) return result;
|
|
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "QuestAcceptWithTran", fn_quest_accept);
|
|
if (result.isFail())
|
|
{
|
|
var err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return (result, null);
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(acceptQuestVar.m_new_quest_nullable, () => $"acceptQuestVar.m_new_quest_nullable is null !!!");
|
|
|
|
quest_action.addNewQuest(questId, acceptQuestVar.m_new_quest_nullable);
|
|
await player.send_GS2C_NTF_QUEST_UPDATE(questId, questRevision, new(), true);
|
|
await QuestManager.It.QuestCheck(player, new QuestMail(EQuestEventTargetType.QUEST, EQuestEventNameType.ACTIVED, ""));
|
|
|
|
var quest_mail_action = player.getEntityAction<QuestMailAction>();
|
|
ArgumentNullException.ThrowIfNull(quest_mail_action);
|
|
quest_mail_action.GS2C_NTF_DELETE_QUEST_MAIL_NOTI(questId);
|
|
|
|
|
|
foreach(var additional_quest_id in acceptQuestVar.assignable_quests)
|
|
{
|
|
await questAcceptWithTransaction(additional_quest_id, 0, recursiveCount);
|
|
}
|
|
|
|
return (result, new_quest);
|
|
|
|
}
|
|
|
|
|
|
public Result newQuestAssign(ref AcceptQuestVariable acceptQuestVar)
|
|
{
|
|
var owner = getOwner() as Player;
|
|
ArgumentNullException.ThrowIfNull(owner);
|
|
//퀘스트 객체 데이터 채우기
|
|
var result = makeNewQuestAssignInfo(ref acceptQuestVar);
|
|
if (result.isFail()) return result;
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
}
|