271 lines
11 KiB
C#
271 lines
11 KiB
C#
|
|
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<Result> 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<QuestMailAction>();
|
|
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<QuestMailAction>();
|
|
|
|
//메일 지급 가능한 퀘스트 체크
|
|
var my_normal_mail_cnt = (await quest_mail_action.getNormalMailSet()).Count;
|
|
HashSet<UInt32> 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<RepeatQuestAction>();
|
|
|
|
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<QueryRunnerWithDocument>( 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<QuestAction>();
|
|
|
|
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<QuestAttribute>();
|
|
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<RewardMetaData> reward_meta_datas = new List<RewardMetaData>();
|
|
//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<EndQuestAction>();
|
|
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 <UgqDailyRewardCountAttribute>();
|
|
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<UgqDailyRewardCountAttribute>();
|
|
|
|
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;
|
|
|
|
}
|
|
}
|