using ServerBase; using ServerCore; using ServerCommon; using MetaAssets; using static ClientToGameMessage.Types; using Guid = System.Guid; namespace GameServer; internal class QuestRewardAction : EntityActionBase { public QuestRewardAction(EntityBase owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public async Task processAfterReward(QuestRewardHandler questRewardHandler) { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var quest_base_info = questRewardHandler.m_quest_meta_info; ArgumentNullReferenceCheckHelper.throwIfNull(quest_base_info, () => $"quest_base_info is null !!!"); var assignable_quests = quest_base_info.AssignableQuestsAfterEnd; var quest_mail_action = player.getEntityAction(); await quest_mail_action.questMailSendOrForceAcceptWithTransaction(questRewardHandler, assignable_quests); //api 서버에 ugq complete 전송 var server_logic = GameServerApp.getServerLogic(); var ugq_api_manager = server_logic.GetUqgApiManager(); var quest_id = questRewardHandler.m_quest_id; var quest_revision = questRewardHandler.m_quest_revision; if (questRewardHandler.m_ugq_game_data is not null && questRewardHandler.m_is_repeat_ugq_quest == false) { var cost = questRewardHandler.m_ugq_game_data.Cost; var api_result = await ugq_api_manager.setUgqQuestCompleted(player.getUserGuid(), quest_id, quest_revision, cost, player.getLanguageType()); if (api_result.isFail()) { //로그만 남긴다. Log.getLogger().error($"Failed to setUgqQuestCompleted : {api_result.toBasicString()} - {player.toBasicString()}"); } } } public async Task normalQuestCheckInitialize() { var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var quest_mail_action = owner.getEntityAction(); //메일 지급 가능한 퀘스트 체크 var my_normal_mail_cnt = (await quest_mail_action.getNormalMailSet()).Count; HashSet assignable_mail_set = await quest_mail_action.getAssignableMailSet(); //메일 보낼 수 있는 퀘스트가 없으면 return; if (assignable_mail_set.Count < 1) { return; } //메일 보낼 수 있는 퀘스트가 있지만 이미 메일이 꽉찼으면 활성화 안해준다. if (MetaHelper.GameConfigMeta.MaxQuestSendMail <= my_normal_mail_cnt) return; //이미 리프레시 체크 중인 유저는 그냥 리턴 if (QuestManager.It.m_normal_quest_check_users.ContainsKey(owner.getUserGuid())) return; var repeat_quest_action = owner.getEntityAction(); DateTime nowDT = DateTime.UtcNow; var nextTime = nowDT.AddMinutes(MetaHelper.GameConfigMeta.CooltimeNormalQuestSendMail); var fn_quest_task_update = async delegate () { var result = new Result(); Int32 is_checking = 1; repeat_quest_action.setRepeatQuestInfo(nextTime, is_checking); var server_logic = GameServerApp.getServerLogic(); var batch = new QueryBatchEx( owner , LogActionType.QuestMainRepeatTimeInit , server_logic.getDynamoDbClient() ); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } batch.appendBusinessLog(new RepeatQuestBusinessLog(nextTime, is_checking)); result = await QueryHelper.sendQueryAndBusinessLog(batch); return result; }; var result = await owner.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "RepeatQuestInfoUpdate", fn_quest_task_update); if (result.isFail()) { string err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); } //여기서, 활성화 되고 체킹중인 유저에 대해서 QuestManager 에 추가(Initialize 시점이니 여기서 셋팅) QuestManager.It.m_normal_quest_check_users.TryAdd(owner.getUserGuid(), 1); } public Result questRewardConditionCheck(ref QuestRewardHandler questRewardHandler) { var result = new Result(); var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var quest_action = owner.getEntityAction(); var quest_id = questRewardHandler.m_quest_id; var quest_revision = questRewardHandler.m_quest_revision; var quest = questRewardHandler.m_quest; ArgumentNullReferenceCheckHelper.throwIfNull(quest, () => $"quest is null !!!"); var quest_attribute = quest.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(quest_attribute, () => $"quest_attribute is null !!!"); if (quest_attribute.IsComplete == 0) { var err_msg = $"Quest Not Completed QuestID : {quest_id}, owner : {owner.toBasicString()}"; result.setFail(ServerErrorCode.QuestNotComplete, err_msg); Log.getLogger().error(result.toBasicString()); return result; } //대체 보상있는 경우 해당 보상정보로 변경 if (quest_attribute.ReplacedRewardGroupId != 0) questRewardHandler.m_replaced_reward_group_id = quest_attribute.ReplacedRewardGroupId; List reward_meta_datas = new List(); //Meta에 보상 정보 없는 경우 에러 처리 if (false == MetaData.Instance._RewardMetaTable.TryGetValue(questRewardHandler.m_replaced_reward_group_id, out var rewardList)) { //ugq에서 m_replaced_reward_group_id 이 0일 수 있다... 일단 여기에 넣고 나중에 reward 관련 일반화 다시 해야될듯... if (questRewardHandler.m_replaced_reward_group_id == 0) { reward_meta_datas = new(); } else { var err_msg = $"_RewardDataTable not exist info rewardGroupId = {questRewardHandler.m_replaced_reward_group_id}, owner : {owner.toBasicString()}"; result.setFail(ServerErrorCode.RewardInfoNotExist, err_msg); Log.getLogger().error(result.toBasicString()); return result; } } else { reward_meta_datas.AddRange(rewardList); //endquest가 존재(반복진행)하고 퀘스트가 ugq이면 보상 그룹은 0으로 처리...아 이것도 코드 바꾸고 싶다... var end_quest_action = owner.getEntityAction(); var end_quest = end_quest_action.getEndQuest(quest_id, quest_revision); bool is_already_cleared_ugq = (end_quest is not null && end_quest.isUgq() == true); if (is_already_cleared_ugq) { questRewardHandler.m_is_repeat_ugq_quest = true; questRewardHandler.m_replaced_reward_group_id = 0; reward_meta_datas = new(); } dailyRewardCountCheck(ref questRewardHandler, is_already_cleared_ugq); } foreach (var reward in reward_meta_datas) { questRewardHandler.m_rewards.Add(reward.Reward); } return result; } private void dailyRewardCountCheck(ref QuestRewardHandler questRewardHandler, bool isAlreadyClearedUgq) { if (isAlreadyClearedUgq) return; if (questRewardHandler.m_ugq_game_data is null) return; ArgumentNullReferenceCheckHelper.throwIfNull(questRewardHandler.m_quest_meta_info, () => $"questRewardHandler.m_quest_meta_info is null !!!"); if (questRewardHandler.m_quest_meta_info.QuestRevision == 0) return; //ugq daily 반복보상 체크 var ugq_daily_reward_count_attribute = getOwner().getEntityAttribute (); NullReferenceCheckHelper.throwIfNull(ugq_daily_reward_count_attribute, () => $"ugq_daily_reward_count_attribute is null !!!"); int max_cnt = 10; var bonus_cnt= ugq_daily_reward_count_attribute.getDailyRewardByGrade(questRewardHandler.m_ugq_game_data.GradeType); (max_cnt, questRewardHandler.m_ugq_daily_bonus_gold) = UgqMetaHelper.getUgqDailyRewardMaxCountByGrade(questRewardHandler.m_ugq_game_data.GradeType); if (bonus_cnt < max_cnt) { questRewardHandler.m_has_ugq_daily_reward = true; RewardMutable reward_mutable = new RewardMutable(); reward_mutable.Currency = new CurrencyRewardMutable() { Id = (int)CurrencyType.Gold, Value = questRewardHandler.m_ugq_daily_bonus_gold }; MetaAssets.Reward reward_gold = new MetaAssets.Reward(reward_mutable); questRewardHandler.m_rewards.Add(reward_gold); } } public override void onClear() { return; } public Result setUgqDailyRewardCountFromDoc(UgqDailyRewardCountDoc doc) { var result = new Result(); var owner = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(owner, () => $"owner is null !!!"); var ugq_daily_reward_attribute = owner.getEntityAttribute(); if (ugq_daily_reward_attribute is null) { var err_msg = $"Fail to get ugq_daily_reward_attribute"; result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg); return result; } if (false == doc.getAttribWrappers().TryGetValue(typeof(UgqDailyRewardCountAttrib), out var to_copy_doc_attrib)) { var err_msg = $"Fail to get UgqDailyRewardCountAttrib"; result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg); return result; } var attrib_base = to_copy_doc_attrib.getAttribBase(); var doc_attrib = attrib_base as UgqDailyRewardCountAttrib; if (doc_attrib is null) { var err_msg = $"Fail to get UgqDailyRewardCountAttrib"; result.setFail(ServerErrorCode.EntityAttributeNotFound, err_msg); return result; } foreach (var reward_cnt in doc_attrib.m_ugq_daily_reward_count) { ugq_daily_reward_attribute.m_ugq_daily_reward_count.AddOrUpdate(reward_cnt.Key, reward_cnt.Value, (key, oldValue) => reward_cnt.Value); } ugq_daily_reward_attribute.m_next_refresh_time = doc_attrib.m_next_refresh_time; ugq_daily_reward_attribute.m_ugq_daily_reward_count_doc_nullable = doc; return result; } }