Files
caliverse_server/GameServer/Ticker/NormalQuestCheckTicker.cs
2025-05-01 07:20:41 +09:00

254 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerCore; using ServerBase;
using ServerCommon;
namespace GameServer;
public class NormalQuestCheckTicker : EntityTicker
{
public NormalQuestCheckTicker(double onTickIntervalMilliseconds, CancellationTokenSource? cts)
: base(EntityType.NormalQuestCheckTicker, onTickIntervalMilliseconds, cts)
{
}
public async Task onTaskTick_old()
{
Stopwatch? stopwatch = null;
var event_tid = string.Empty;
var server_logic = GameServerApp.getServerLogic();
ArgumentNullException.ThrowIfNull(server_logic);
var server_config = server_logic.getServerConfig();
ArgumentNullException.ThrowIfNull(server_config);
if (true == server_config.PerformanceCheckEnable)
{
event_tid = System.Guid.NewGuid().ToString("N");
stopwatch = Stopwatch.StartNew();
}
//여기에 Transaction 걸기
await QuestManager.It.questTimerEventCheck();
await QuestManager.It.questNormalActiveCheck();
if (null != stopwatch)
{
var elapsed_msec = stopwatch.ElapsedMilliseconds;
stopwatch.Stop();
Log.getLogger().debug($"{GetType()} Ticker Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{elapsed_msec}, TickIntervalMSec:{getOnTickIntervalMilliseconds()}");
}
}
public override async Task onTaskTick()
{
Stopwatch? stopwatch = null;
var event_tid = string.Empty;
var server_logic = GameServerApp.getServerLogic();
ArgumentNullException.ThrowIfNull(server_logic);
var server_config = server_logic.getServerConfig();
ArgumentNullException.ThrowIfNull(server_config);
if (true == server_config.PerformanceCheckEnable)
{
event_tid = System.Guid.NewGuid().ToString("N");
stopwatch = Stopwatch.StartNew();
}
//await QuestManager.It.questTimerEventCheck(); 의 대안
var timer_check_user = QuestManager.It.getTimerCheckUser();
List<string> delete_checker = new();
ArgumentNullException.ThrowIfNull(timer_check_user, $"timer_check_user is null !!!");
var player_manager = server_logic.getPlayerManager();
ArgumentNullException.ThrowIfNull(player_manager, $"player_manager is null !!!");
foreach (string user_guid in timer_check_user)
{
if (false == player_manager.tryGetUserByPrimaryKey(user_guid, out var player))
{
delete_checker.Add(user_guid);
continue;
}
var user_create_or_load_action = player.getEntityAction<UserCreateOrLoadAction>();
ArgumentNullException.ThrowIfNull(user_create_or_load_action,
$"user_create_or_load_action is null !!! - {player.toBasicString()}");
if (false == user_create_or_load_action.isCompletedLoadUser())
{
continue;
}
var fn_transaction_runner = async delegate()
{
var result = await QuestManager.It.QuestCheckWithoutTransaction(player, new QuestTimer(EQuestEventTargetType.TIMER, EQuestEventNameType.ENDED));
ArgumentNullException.ThrowIfNull(result, $"result is null !!!");
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.QuestTaskUpdate, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
var err_msg = $"Failed to sendQueryAndBusinessLog() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
return result;
};
var result = await player.runTransactionRunnerSafelyWithTransGuid(player.getUserGuid(), TransactionIdType.PrivateContents, "QuestTimerCheckTick", fn_transaction_runner);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
}
QuestManager.It.deleteTimerCheckUser(delete_checker);
//questNormalActiveCheck() 의 대안
delete_checker = new();
DateTime now_dt = DateTimeHelper.Current;
foreach (var user_guid in QuestManager.It.m_normal_quest_check_users.Keys)
{
if (false == player_manager.tryGetUserByPrimaryKey(user_guid, out var player))
{
delete_checker.Add(user_guid);
continue;
}
var user_create_or_load_action = player.getEntityAction<UserCreateOrLoadAction>();
ArgumentNullException.ThrowIfNull(user_create_or_load_action,
$"user_create_or_load_action is null !!! - {player.toBasicString()}");
if (false == user_create_or_load_action.isCompletedLoadUser())
{
continue;
}
var fn_transaction_runner = async delegate()
{
var repeat_quest_attribute = player.getEntityAttribute<RepeatQuestAttribute>();
NullReferenceCheckHelper.throwIfNull(repeat_quest_attribute, () => $"repeat_quest_attribute is null !!!");
if (repeat_quest_attribute.m_is_checking == 0) return new();
if (now_dt < repeat_quest_attribute.m_next_allocate_time) return new();
//플레이어 정보는 퀘스트 메일 보내기 전에 로드 된다. 메일이 로드 안되어 있으면 리턴 할수 있도록 처리 해줘야된다.
var quest_mail_action = player.getEntityAction<QuestMailAction>();
if (false == quest_mail_action.isMailLoadedAll()) return new();
HashSet<UInt32> my_current_normal_mail_set = await quest_mail_action.getNormalMailSet();
int normal_mail_count = my_current_normal_mail_set.Count;
HashSet<UInt32> assignable_mail_set = await QuestManager.It.getAssignableMailSet(player, my_current_normal_mail_set);
//체크 대상이라 여기 들어왔는데 메일이 넘치면 미체크 대상으로 처리
if (MetaHelper.GameConfigMeta.MaxQuestSendMail <= normal_mail_count || assignable_mail_set.Count == 0)
{
QuestManager.It.m_normal_quest_check_users.TryRemove(player.getUserGuid(), out _);
return new();
}
//여기까지 왔으면 메일 보낼게 있다는 얘기이므로 전송한다.
var assignable_quest_id = QuestManager.It.getAssignableQuestMailId(assignable_mail_set);
ArgumentNullException.ThrowIfNull(assignable_quest_id, $"assignable_quest_id is null !!!");
//여기서 normalMailSet + 1 의 개수가 최대 개수를 넘으면 비활성화 처리
var check_value = QuestManager.It.questCheckUserAssignableQuestMaxCheck(player, my_current_normal_mail_set);
ArgumentNullException.ThrowIfNull(check_value, $"check_value is null !!!");
(var result, var quest_mail, var quest_mail_log_invoker) = await quest_mail_action.sendQuestMail(assignable_quest_id);
if (result.isFail())
{
return result;
}
repeat_quest_attribute.m_next_allocate_time = repeat_quest_attribute.m_next_allocate_time.AddMinutes(MetaHelper.GameConfigMeta.CooltimeNormalQuestSendMail);
if (false == check_value)
{
repeat_quest_attribute.m_is_checking = 0;
}
repeat_quest_attribute.modifiedEntityAttribute();
var server_logic = GameServerApp.getServerLogic();
ArgumentNullException.ThrowIfNull(server_logic, $"server_logic is null !!!");
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.QuestMailSend, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
batch.appendBusinessLog(new RepeatQuestBusinessLog(repeat_quest_attribute.m_next_allocate_time, repeat_quest_attribute.m_is_checking));
batch.appendBusinessLog(quest_mail_log_invoker);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
var err_msg = $"Failed to sendQueryAndBusinessLog() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
await quest_mail_action.addNewQuestMails(new List<ServerCommon.QuestMail>() { quest_mail });
await quest_mail_action.send_NTF_RECEIVED_QUEST_MAIL(player, new List<UInt32>() { assignable_quest_id });
await QuestManager.It.QuestCheckWithoutTransaction(player, new QuestMail(EQuestEventTargetType.MAIL, EQuestEventNameType.RECEIVED, ""));
return result;
};
var result = await player.runTransactionRunnerSafelyWithTransGuid(player.getUserGuid(), TransactionIdType.PrivateContents, "mailAndUpdateRepeatQuestInfo", fn_transaction_runner);
if (result.isFail())
{
var err_msg = $"Failed to runTransactionRunnerSafelyWithTransGuid() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
continue;
}
}
foreach (var delete_user in delete_checker)
{
QuestManager.It.m_normal_quest_check_users.TryRemove(delete_user, out _);
Log.getLogger()
.debug($"setNormalMailTimer m_normal_quest_check_users remove accountId : {delete_user}");
}
if (null != stopwatch)
{
var elapsed_msec = stopwatch.ElapsedMilliseconds;
stopwatch.Stop();
Log.getLogger().debug($"{GetType()} Ticker Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{elapsed_msec}, TickIntervalMSec:{getOnTickIntervalMilliseconds()}");
}
}
public override string toBasicString()
{
return $"{this.getTypeName()}";
}
public override string toSummaryString()
{
return $"{this.getTypeName()}";
}
}