1426 lines
57 KiB
C#
1426 lines
57 KiB
C#
using System.Collections.Concurrent;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
using GameServer.PacketHandler;
|
|
|
|
|
|
using META_ID = System.UInt32;
|
|
using MAIL_GUID = System.String;
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class MailAction : EntityActionBase
|
|
{
|
|
private ConcurrentDictionary<MAIL_GUID, Mail> m_sent_mails = new();
|
|
private ConcurrentDictionary<MAIL_GUID, Mail> m_received_mails = new();
|
|
|
|
private ConcurrentDictionary<MailType, List<MAIL_GUID>> m_client_received_mailkey = new();
|
|
private bool m_isReceivedSystemMetaMail = false;
|
|
private bool m_isNewReceivedMail = false;
|
|
|
|
public MailAction(Player owner)
|
|
: base(owner)
|
|
{
|
|
}
|
|
|
|
public override async Task<Result> onInit()
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
var result = new Result();
|
|
|
|
foreach (var mailtype in EnumHelper.getValues<MailType>())
|
|
{
|
|
m_client_received_mailkey.TryAdd(mailtype, new List<MAIL_GUID>());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public override void onClear()
|
|
{
|
|
m_sent_mails.Clear();
|
|
m_received_mails.Clear();
|
|
foreach(var value in m_client_received_mailkey.Values)
|
|
{
|
|
value.Clear();
|
|
}
|
|
return;
|
|
}
|
|
|
|
public bool isNewReceivedMail()
|
|
{
|
|
return m_isNewReceivedMail;
|
|
}
|
|
|
|
public bool isNewSystemMail()
|
|
{
|
|
return m_isReceivedSystemMetaMail;
|
|
}
|
|
|
|
public async Task<(Result, List<string>)> getReceivedProductMailOrderIds()
|
|
{
|
|
var order_id_list = new List<string>();
|
|
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
(result, var mail_list) = await getReceivedMailDoc(player.getUserGuid());
|
|
if (result.isFail())
|
|
{
|
|
return (result, order_id_list);
|
|
}
|
|
|
|
foreach (var mail in mail_list)
|
|
{
|
|
var mail_attrib = mail.getAttrib<MailAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_attrib, () => $"MailAttrib is null !! - player:{player.toBasicString()}");
|
|
|
|
if (mail_attrib.packageOrderId != string.Empty)
|
|
{
|
|
order_id_list.Add(mail_attrib.packageOrderId);
|
|
}
|
|
}
|
|
return (result, order_id_list);
|
|
}
|
|
|
|
public async Task<Result> AddMailFromDocs<TDoc>(List<TDoc> mailDocs)
|
|
where TDoc : MailDoc
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
ConcurrentDictionary<MAIL_GUID, Mail> mails = typeof(TDoc) == typeof(ReceivedMailDoc) ? m_received_mails : m_sent_mails;
|
|
|
|
foreach(var mail_doc in mailDocs)
|
|
{
|
|
(result, var mail) = await Mail.createMailFromDoc(player, mail_doc);
|
|
if(result.isFail() || null == mail)
|
|
{
|
|
err_msg = $"failed to copy from doc !! - {mail_doc.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
|
|
continue;
|
|
}
|
|
|
|
var mail_attribute = mail.getEntityAttribute<MailAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_attribute, () => $"MailAttribute is null !! - player:{player.toBasicString()}");
|
|
|
|
if (mails.TryAdd(mail_attribute.MailGuid, mail) == false)
|
|
{
|
|
err_msg = $"Failed to get mail attribute : {nameof(MailAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
return result;
|
|
}
|
|
|
|
if(m_isNewReceivedMail == false && typeof(TDoc) == typeof(ReceivedMailDoc) && mail_attribute.IsRead == false)
|
|
{
|
|
m_isNewReceivedMail = true;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> checkSystemMail()
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
result = await ProcessReceiveSystemMail();
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> ProcessReceiveSystemMail()
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var fn_receive_system_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_profile_attribute = player.getEntityAttribute<MailProfileAttribute>();
|
|
if (mail_profile_attribute == null)
|
|
{
|
|
err_msg = $"Failed to get mail profile attribute : {nameof(MailProfileAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
return result;
|
|
}
|
|
|
|
|
|
//운영툴 운영에따라 ID가 순서가 꼬일수도 있다. LastSystemMailId 로 가져오면 문제가 될수 있을듯
|
|
//int lastSystemMailId = mail_profile_attribute.LastSystemMailId;
|
|
var received_system_mails = mail_profile_attribute.ReceivedSystemMails;
|
|
var systemMailList = server_logic.getSystemMailManager().GetSystemMail(received_system_mails);
|
|
|
|
var receivedMailDocs = new List<DynamoDbDocBase>();
|
|
|
|
foreach (var systemMail in systemMailList)
|
|
{
|
|
var system_mail_attribute = systemMail.getEntityAttribute<SystemMetaMailAttribute>();
|
|
if (system_mail_attribute == null)
|
|
{
|
|
err_msg = $"Failed to get system mail attribute : {nameof(SystemMetaMailAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
return result;
|
|
}
|
|
received_system_mails.TryAdd(system_mail_attribute.MailId, DateTimeHelper.Current);
|
|
|
|
var language_type = player.getLanguageType();
|
|
|
|
var sender_nickname = StringRuleHelper.getString(language_type, system_mail_attribute.SenderNickName);
|
|
var title = StringRuleHelper.getString(language_type, system_mail_attribute.Title);
|
|
var text = StringRuleHelper.getString(language_type, system_mail_attribute.Text);
|
|
|
|
(result, var receivedMailDoc) = await Mail.createSystemMail( player.getUserGuid(), player.getUserNickname(), sender_nickname
|
|
, title, text, new List<string>(), false
|
|
, system_mail_attribute.ItemList, MetaHelper.GameConfigMeta.SystemMailStoragePeriod);
|
|
if (result.isFail() || null == receivedMailDoc)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
receivedMailDocs.Add(receivedMailDoc);
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailLogInfo(receivedMailDoc);
|
|
invokers.Add(new MailBusinessLog(task_log_data));
|
|
}
|
|
|
|
if (receivedMailDocs.Count > 0)
|
|
{
|
|
//mail_profile_attribute.LastSystemMailId = lastSystemMailId;
|
|
mail_profile_attribute.modifiedEntityAttribute(true);
|
|
|
|
foreach(var base_doc in receivedMailDocs)
|
|
{
|
|
var mail_doc = base_doc as MailDoc;
|
|
if (mail_doc == null)
|
|
continue;
|
|
|
|
var task_mail_log_data = MailBusinessLogHelper.toMailLogInfo(mail_doc);
|
|
invokers.Add(new MailBusinessLog(task_mail_log_data));
|
|
}
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailProfileLogInfo(mail_profile_attribute);
|
|
invokers.Add(new MailProfileBusinessLog(task_log_data));
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.MailGetSystemMail
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQEntityWrite(receivedMailDocs));
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
m_isNewReceivedMail = true;
|
|
}
|
|
|
|
m_isReceivedSystemMetaMail = false;
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "ReceiveSystemMail", fn_receive_system_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> ProcessGetMail(MailType mailType)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
var package_action = player.getEntityAction<PackageAction>();
|
|
NullReferenceCheckHelper.throwIfNull(package_action, () => $"package_action is null !!! - {player.toBasicString()}");
|
|
|
|
if (mailType == MailType.ReceivedMail)
|
|
{
|
|
await package_action.tryOrderNewProductList();
|
|
}
|
|
|
|
var user_land_auction_action = player.getEntityAction<UserLandAuctionAction>();
|
|
NullReferenceCheckHelper.throwIfNull(user_land_auction_action, () => $"user_land_auction_action is null !!! - {player.toBasicString()}");
|
|
await user_land_auction_action.updateRefundBidPriceAll();
|
|
|
|
if (m_isReceivedSystemMetaMail == true)
|
|
{
|
|
result = await ProcessReceiveSystemMail();
|
|
if(result.isFail())
|
|
{
|
|
GetMailPacketHandler.send_S2C_ACK_GET_MAIL(player, result, null, mailType, 0);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
await ProcessMailSendTime();
|
|
|
|
var mailList = await getNewMailList(mailType);
|
|
|
|
var mail_profile_attribute = player.getEntityAttribute<MailProfileAttribute>();
|
|
if (mail_profile_attribute == null)
|
|
{
|
|
err_msg = $"Failed to get mail profile attribute : {nameof(MailProfileAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
GetMailPacketHandler.send_S2C_ACK_GET_MAIL(player, result, mailList, mailType, mail_profile_attribute.SendMailCount);
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> ProcessMailSendTime()
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
if (checkMailSendTime() == true)
|
|
{
|
|
var fn_update_mail_send_time = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_profile_attribute = getOwner().getEntityAttribute<MailProfileAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_profile_attribute, () => $"mail_profile_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
updateMailSendTime(mail_profile_attribute);
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailProfileLogInfo(mail_profile_attribute);
|
|
invokers.Add(new MailProfileBusinessLog(task_log_data));
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.MailInitSendCount
|
|
, server_logic.getDynamoDbClient());
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "UpdateMailSendTime", fn_update_mail_send_time);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> ReadReceivedMail(string mail_guid)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
if (m_received_mails.TryGetValue(mail_guid, out var received_mail) == false)
|
|
{
|
|
err_msg = $"Failed to TryGetValue() !!!, Not found Mail : reqMailGuid:{mail_guid} - {player.toBasicString()}";
|
|
result.setFail(ServerErrorCode.MailNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
ReadMailPacketHandler.send_S2C_ACK_READ_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
var fn_read_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_attribute = received_mail.getEntityAttribute<MailAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_attribute, () => $"mail_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
mail_attribute.IsRead = true;
|
|
mail_attribute.modifiedEntityAttribute();
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailLogInfo(mail_attribute);
|
|
invokers.Add(new MailBusinessLog(task_log_data));
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>( player, LogActionType.MailRead
|
|
, server_logic.getDynamoDbClient() );
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
ReadMailPacketHandler.send_S2C_ACK_READ_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
ReadMailPacketHandler.send_S2C_ACK_READ_MAIL(player, result);
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "ReadMail", fn_read_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> GetItemsReceivedMail(string mail_guid)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var account_attribute = player.getEntityAttribute<AccountAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
if (m_received_mails.TryGetValue(mail_guid, out var received_mail) == false)
|
|
{
|
|
err_msg = $"Failed to ReadReceivedMail. Not found mail : mail_guid {mail_guid}";
|
|
result.setFail(ServerErrorCode.MailNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_attribute = received_mail.getEntityAttribute<MailAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_attribute, () => $"mail_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
if (mail_attribute.IsGetItem == true || mail_attribute.ItemList.Count == 0)
|
|
{
|
|
err_msg = $"Item is empty. mail_guid : {mail_attribute.MailGuid}";
|
|
result.setFail(ServerErrorCode.MailAlreadyTaken, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
if (mail_attribute.packageOrderId != string.Empty)
|
|
{
|
|
result = await UpdateBillingStateType(account_attribute, mail_attribute.packageOrderId, BillingStateType.opening, invokers);
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
var fn_get_item_received_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
|
|
var mail_attribute = received_mail.getEntityAttribute<MailAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_attribute, () => $"mail_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
foreach (var itemData in mail_attribute.ItemList)
|
|
{
|
|
result = await TakeMailItems(itemData);
|
|
if (result.isFail())
|
|
return result;
|
|
}
|
|
|
|
mail_attribute.IsGetItem = true;
|
|
mail_attribute.modifiedEntityAttribute();
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailLogInfo(mail_attribute);
|
|
invokers.Add(new MailBusinessLog(task_log_data));
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.MailTaken
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
var found_transaction_runner = player.findTransactionRunner(TransactionIdType.PrivateContents);
|
|
if (null == found_transaction_runner)
|
|
{
|
|
var err_msg = $"Not found TransactionRunner !!! : {toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().warn(err_msg);
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
if(mail_attribute.packageOrderId != string.Empty)
|
|
{
|
|
//상태를 바꾸는데 실패해도 DB처리는 끝났기 때문에 실패해도 처리하지 않는다.
|
|
await UpdateBillingStateType(account_attribute, mail_attribute.packageOrderId, BillingStateType.opened, new() );
|
|
}
|
|
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, found_transaction_runner.getCommonResult());
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "GetItemsReceivedMail", fn_get_item_received_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> UpdateBillingStateType(AccountAttribute account_attribute, string order_id, BillingStateType billingStateType, List<ILogInvoker> invokers)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
var jwt = account_attribute.SsoAccountAuthJWT.ToString();
|
|
var account_id = account_attribute.AccountId;
|
|
|
|
(result, bool isUpdated) = await BillingServerConnector.AbleToChangeBillingState(jwt, account_id.ToString(), order_id, billingStateType);
|
|
if (result.isFail() || isUpdated == true)
|
|
return result;
|
|
|
|
//BillingServer에 상태 변경
|
|
var stateList = new List<BillingStateList>() { new BillingStateList() { order_id = order_id, state = billingStateType.ToString() } };
|
|
var billingChangeState = new BillingChangeState() { account_id = account_id.ToString(), state_list = stateList };
|
|
(result, var status_message) = await BillingServerConnector.UpdateBillingState(billingChangeState, jwt);
|
|
if (result.isFail())
|
|
{
|
|
var log_action = new LogActionEx(LogActionType.ProductOpenFailed);
|
|
var task_failed_state_log_data = PackageBusinessLogHelper.toStateLogInfo(order_id, billingStateType, status_message);
|
|
invokers.Add(new PackageStateBusinessLog(task_failed_state_log_data));
|
|
BusinessLogger.collectLogs(log_action, player, invokers);
|
|
return result;
|
|
}
|
|
|
|
if(billingStateType == BillingStateType.opened)
|
|
{
|
|
var log_action = new LogActionEx(LogActionType.ProductOpenSuccess);
|
|
var log_data = PackageBusinessLogHelper.toStateLogInfo(order_id, billingStateType, status_message);
|
|
invokers.Add(new PackageStateBusinessLog(log_data));
|
|
BusinessLogger.collectLogs(log_action, player, invokers);
|
|
return result;
|
|
}
|
|
|
|
var task_state_log_data = PackageBusinessLogHelper.toStateLogInfo(order_id, billingStateType, status_message);
|
|
invokers.Add(new PackageStateBusinessLog(task_state_log_data));
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> TakeMailItems(ServerCommon.MailItem mail_item)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
var inventory_action = player.getEntityAction<InventoryActionBase>();
|
|
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!! - {player.toBasicString()}");
|
|
|
|
if (MetaData.Instance._ItemTable.TryGetValue((int)mail_item.ItemId, out var itemMetaData) == false)
|
|
{
|
|
err_msg = $"Failed to find Item meta Id. meta_id : {mail_item.ItemId}";
|
|
result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
if (itemMetaData.TypeLarge == EItemLargeType.PRODUCT)
|
|
{
|
|
result = await TakeProductItem(mail_item);
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
}
|
|
else if (itemMetaData.TypeLarge == EItemLargeType.CURRENCY)
|
|
{
|
|
result = await TakeCurrencyItem(itemMetaData.TypeSmall, mail_item.Count);
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( false == itemMetaData.isCreatableItem() )
|
|
{
|
|
err_msg = $"Cannet be Stored Item !!! : IsUiOnly:{itemMetaData.IsUiOnly}, LargeType:{itemMetaData.TypeLarge}, SmallType:{itemMetaData.TypeSmall} - {mail_item.ItemId}";
|
|
result.setFail(ServerErrorCode.ItemCanNotBeStored, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
(result, var new_item_list) = await inventory_action.tryTakalbleToBag((META_ID)mail_item.ItemId, (ushort)mail_item.Count);
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> TakeProductItem(ServerCommon.MailItem mail_item)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
var inventory_action = player.getEntityAction<InventoryActionBase>();
|
|
NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!! - {player.toBasicString()}");
|
|
|
|
if (MetaData.Instance._ProductMetaDataById.TryGetValue((int)mail_item.ProductId, out var itemList) == false)
|
|
{
|
|
err_msg = $"Failed to find Item meta Id from ProductData. meta_id : {mail_item.ProductId}";
|
|
result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
List<ItemMetaList>? itemMetaList;
|
|
if(mail_item.isRepeatProduct == true)
|
|
itemMetaList = itemList.Repeat_List.ToList();
|
|
else
|
|
itemMetaList = itemList.First_List.ToList();
|
|
|
|
foreach (var item in itemMetaList)
|
|
{
|
|
if (MetaData.Instance._ItemTable.TryGetValue(item.Id, out var itemMetaData) == false)
|
|
{
|
|
err_msg = $"Failed to find Item meta Id. meta_id : {item.Id}";
|
|
result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
if (itemMetaData.TypeLarge == EItemLargeType.PRODUCT)
|
|
{
|
|
err_msg = $"Failed to find Item meta Id. meta_id : {item.Id}";
|
|
result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
else if (itemMetaData.TypeLarge == EItemLargeType.CURRENCY)
|
|
{
|
|
result = await TakeCurrencyItem(itemMetaData.TypeSmall, (item.Value * mail_item.Count));
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
(result, var new_item_list) = await inventory_action.tryTakalbleToBag((META_ID)item.Id, (ushort)(item.Value * mail_item.Count));
|
|
if (result.isFail())
|
|
{
|
|
GetItemsMailPacketHandler.send_S2C_ACK_GET_ITEMS_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<Result> TakeCurrencyItem(EItemSmallType type, double amount)
|
|
{
|
|
var result = new Result();
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
var money_action = player.getEntityAction<MoneyAction>();
|
|
NullReferenceCheckHelper.throwIfNull(money_action, () => $"money_action is null !!! - {player.toBasicString()}");
|
|
|
|
var currencyType = MetaData.Instance.CurrencyItemSmallTypeToCurrencyType(type);
|
|
result = await money_action.changeMoney(currencyType, amount);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<Result> DeleteMail(MAIL_GUID mail_guid, MailType mailType)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
ConcurrentDictionary<MAIL_GUID, Mail> mails;
|
|
|
|
switch (mailType)
|
|
{
|
|
case MailType.SentMail: mails = m_sent_mails; break;
|
|
case MailType.ReceivedMail: mails = m_received_mails; break;
|
|
default:
|
|
{
|
|
err_msg = $"Failed to ReadReceivedMail. Not found mail : mail_guid {mail_guid}";
|
|
result.setFail(ServerErrorCode.MailInvalidMailType, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
if (mails.TryGetValue(mail_guid, out var mail) == false)
|
|
{
|
|
err_msg = $"Failed to ReadReceivedMail. Not found mail : mail_guid {mail_guid}";
|
|
result.setFail(ServerErrorCode.MailNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
var fn_delete_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_attribute = mail.getEntityAttribute<MailAttribute>();
|
|
if (mail_attribute == null)
|
|
{
|
|
err_msg = $"Failed to get mail attribute : {nameof(MailAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
var billingStateType = BillingStateType.none;
|
|
|
|
if (mail_attribute.packageOrderId != string.Empty)
|
|
{
|
|
var account_attribute = player.getEntityAttribute<AccountAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(account_attribute, () => $"account_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
var jwt = account_attribute.SsoAccountAuthJWT.ToString();
|
|
var account_id = account_attribute.AccountId;
|
|
|
|
(result, billingStateType) = await BillingServerConnector.GetBillingState(jwt, account_id.ToString(), mail_attribute.packageOrderId);
|
|
if (billingStateType == BillingStateType.none)
|
|
{
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
if(billingStateType == BillingStateType.refund_request || billingStateType == BillingStateType.refund)
|
|
{
|
|
result.setFail(ServerErrorCode.BillingStateTypeRefund);
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
if ( billingStateType != BillingStateType.canceled
|
|
&& false == mail_attribute.isDeletableMail()
|
|
)
|
|
{
|
|
err_msg = $"Failed to Delete Mail. Mail Item is exist : {nameof(MailAttribute)}";
|
|
result.setFail(ServerErrorCode.MailCantDeleteIfItemExists, err_msg);
|
|
Log.getLogger().warn(result.toBasicString());
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
mail_attribute.deleteEntityAttribute();
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailLogInfo(mail_attribute);
|
|
invokers.Add(new MailBusinessLog(task_log_data));
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.MailDestroy
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
if(mails.TryRemove(mail_guid, out var deleted_mail) == false)
|
|
{
|
|
Log.getLogger().error("Mail remove failed.");
|
|
}
|
|
|
|
if (m_client_received_mailkey.TryGetValue(mailType, out var client_received_mailkey_list) == false)
|
|
{
|
|
client_received_mailkey_list = new();
|
|
m_client_received_mailkey.TryAdd(mailType, client_received_mailkey_list);
|
|
}
|
|
|
|
client_received_mailkey_list.Remove(mail_guid);
|
|
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "DeleteMail", fn_delete_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private async Task<List<Mail>> getNewMailList(MailType mailType)
|
|
{
|
|
var mail_list = new List<Mail>();
|
|
var new_mail_list = new List<Mail>();
|
|
|
|
if (m_client_received_mailkey.TryGetValue(mailType, out var client_received_mailkey_list) == false)
|
|
{
|
|
client_received_mailkey_list = new();
|
|
m_client_received_mailkey.TryAdd(mailType, client_received_mailkey_list);
|
|
}
|
|
|
|
switch (mailType)
|
|
{
|
|
case MailType.ReceivedMail: mail_list = await getReceivedMailList(); break;
|
|
case MailType.SentMail: mail_list = getSendedMailList(); break;
|
|
default: return mail_list;
|
|
}
|
|
|
|
int mailCount = 0;
|
|
foreach (var mail in mail_list)
|
|
{
|
|
++mailCount;
|
|
|
|
if (mailCount > ServerCommon.Constant.MAX_READ_MAIL_DB_COUNT)
|
|
{
|
|
break;
|
|
}
|
|
|
|
var mail_attribute = mail.getEntityAttribute<MailAttribute>();
|
|
if(mail_attribute == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(client_received_mailkey_list.Any(guid => guid == mail_attribute.MailGuid) == true)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
new_mail_list.Add(mail);
|
|
client_received_mailkey_list.Add(mail_attribute.MailGuid);
|
|
}
|
|
|
|
return new_mail_list;
|
|
}
|
|
|
|
private async Task<List<Mail>> getReceivedMailList()
|
|
{
|
|
var result = new Result();
|
|
var result_mails = new List<Mail>();
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
if (m_isNewReceivedMail == false)
|
|
{
|
|
foreach (var receivedMail in m_received_mails)
|
|
{
|
|
result_mails.Add(receivedMail.Value);
|
|
}
|
|
return result_mails;
|
|
}
|
|
|
|
(result, var read_docs) = await getReceivedMailDoc(player.getUserGuid());
|
|
if (result.isFail())
|
|
{
|
|
return result_mails;
|
|
}
|
|
|
|
m_isNewReceivedMail = false;
|
|
m_received_mails.Clear();
|
|
|
|
foreach (var read_doc in read_docs)
|
|
{
|
|
(result, var mail) = await Mail.createMailFromDoc(player, read_doc);
|
|
if(mail == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var mail_attribute = mail.getEntityAttribute<MailAttribute>();
|
|
if(mail_attribute == null)
|
|
{
|
|
continue;
|
|
}
|
|
m_received_mails.TryAdd(mail_attribute.MailGuid, mail);
|
|
result_mails.Add(mail);
|
|
}
|
|
|
|
result_mails.Sort((x, y) => {
|
|
var x_mail_attribute = x.getEntityAttribute<MailAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(x_mail_attribute, () => $"x MailAttribute is null !! - player:{player.toBasicString()}");
|
|
|
|
var y_mail_attribute = y.getEntityAttribute<MailAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(y_mail_attribute, () => $"y MailAttribute is null !! - player:{player.toBasicString()}");
|
|
|
|
return y_mail_attribute.CreateTime.CompareTo(x_mail_attribute.CreateTime);
|
|
});
|
|
|
|
return result_mails;
|
|
}
|
|
|
|
private async Task<(Result, List<ReceivedMailDoc>)> getReceivedMailDoc(string userGuid)
|
|
{
|
|
var err_msg = string.Empty;
|
|
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var dynamo_db_client = server_logic.getDynamoDbClient();
|
|
|
|
var received_mail_docs = new List<ReceivedMailDoc>();
|
|
|
|
var doc = new ReceivedMailDoc(userGuid);
|
|
var event_tid = Guid.NewGuid().ToString("N");
|
|
var query_config = dynamo_db_client.makeQueryConfigForReadByPKOnly(doc.getPK());
|
|
(var result, var read_docs) = await dynamo_db_client.simpleQueryDocTypesWithQueryOperationConfig<ReceivedMailDoc>(query_config);
|
|
if(result.isSuccess())
|
|
{
|
|
foreach(var recv_mail_doc in read_docs)
|
|
{
|
|
var mail_attrib = recv_mail_doc.getAttrib<MailAttrib>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_attrib, () => $"mail_attrib is null !!! - userGuid:{userGuid}");
|
|
|
|
if (DateTimeHelper.Current > mail_attrib.ExpireTime)
|
|
{
|
|
var to_delete_result = await dynamo_db_client.simpleDeleteDocumentWithDocType(recv_mail_doc, event_tid);
|
|
if(to_delete_result.isFail())
|
|
{
|
|
err_msg = $"Failed to simpleDeleteDocumentWithDocType() !!!, can't received mail : Mail:{mail_attrib.toBasicString()} - userGuid:{userGuid}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
else
|
|
{
|
|
err_msg = $"Mail deleted with expired retention period !!! : deletedMail:{mail_attrib.toBasicString()} - userGuid:{userGuid}";
|
|
Log.getLogger().info(err_msg);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
received_mail_docs.Add(recv_mail_doc);
|
|
}
|
|
}
|
|
|
|
return (result, received_mail_docs);
|
|
}
|
|
|
|
private List<Mail> getSendedMailList()
|
|
{
|
|
var newMailEntity = new List<Mail>();
|
|
foreach(var sentMail in m_sent_mails)
|
|
{
|
|
newMailEntity.Add(sentMail.Value);
|
|
}
|
|
|
|
return newMailEntity;
|
|
}
|
|
|
|
public async Task<Result> trySendMail(string toNickName, string to_user_guid, string title, string mailText)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
if(to_user_guid == player.getUserGuid())
|
|
{
|
|
result.setFail(ServerErrorCode.MailCantSendSelf, err_msg);
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
var fn_send_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_profile_attribute = player.getEntityAttribute<MailProfileAttribute>();
|
|
if (mail_profile_attribute == null)
|
|
{
|
|
err_msg = $"Failed to get mail profile attribute : {nameof(MailProfileAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
if (checkMailSendTime() == true)
|
|
{
|
|
updateMailSendTime(mail_profile_attribute);
|
|
}
|
|
|
|
if (mail_profile_attribute.SendMailCount >= ServerCommon.Constant.MAX_MAILSEND_COUNT)
|
|
{
|
|
err_msg = $"Send Mail Over The Max Count. !!!, can't true state - {getOwner().toBasicString()}";
|
|
result.setFail(ServerErrorCode.MailMaxSendCountExceed, err_msg);
|
|
Log.getLogger().warn(result.toBasicString());
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
(result, var read_docs) = await getReceivedMailDoc(to_user_guid);
|
|
if(read_docs.Count >= ServerCommon.Constant.MAX_READ_MAIL_DB_COUNT)
|
|
{
|
|
err_msg = $"Target Received Mail Over The Max Count. !!!, target guid - {to_user_guid}";
|
|
result.setFail(ServerErrorCode.MailMaxTargetReceivedCountExceed, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
// 2. mail_profile_attribute 변경
|
|
mail_profile_attribute.SendMailCount += 1;
|
|
mail_profile_attribute.modifiedEntityAttribute();
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailProfileLogInfo(mail_profile_attribute);
|
|
invokers.Add(new MailProfileBusinessLog(task_log_data));
|
|
|
|
// 3. 보낸 메일
|
|
(result, var sent_mail) = await Mail.createSendMail(player, toNickName, to_user_guid, title, mailText);
|
|
if (result.isFail() || sent_mail == null)
|
|
{
|
|
err_msg = $"Create Mail Failed. !!! - {getOwner().toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
var send_mail_attribute = sent_mail.getEntityAttribute<MailAttribute>();
|
|
if (send_mail_attribute == null)
|
|
{
|
|
err_msg = $"Failed to get mail attribute : {nameof(MailAttribute)}";
|
|
result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
var task_send_log_data = MailBusinessLogHelper.toMailLogInfo(send_mail_attribute);
|
|
invokers.Add(new MailBusinessLog(task_send_log_data));
|
|
|
|
// 4. 받은 메일 저장하는 document 생성
|
|
var received_mail_doc = await MailHelper.CreateReceivedMailBySendMail(to_user_guid, send_mail_attribute.MailGuid, send_mail_attribute);
|
|
if (null == received_mail_doc)
|
|
{
|
|
err_msg = $"Failed to send mail : createReceivedMailBySendMail - to_user_guid:{to_user_guid}, send_mail_guid:{send_mail_attribute.MailGuid}";
|
|
result.setFail(ServerErrorCode.MailSystemError, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>( player, LogActionType.MailSend
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQEntityWrite(received_mail_doc));
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return result;
|
|
}
|
|
|
|
m_sent_mails.TryAdd(send_mail_attribute.MailGuid, sent_mail);
|
|
|
|
var player_manager = server_logic.getPlayerManager();
|
|
if (player_manager.tryGetUserByPrimaryKey(to_user_guid, out var found_user) == true)
|
|
{
|
|
var found_user_mail_action = found_user.getEntityAction<MailAction>();
|
|
found_user_mail_action.NewReceivedMail();
|
|
}
|
|
else
|
|
{
|
|
var login_cache_request = new LoginCacheOtherUserRequest(player, server_logic.getRedisConnector(), to_user_guid);
|
|
await login_cache_request.fetchLogin();
|
|
var login_cache = login_cache_request.getLoginCache();
|
|
if (login_cache != null)
|
|
{
|
|
MailNotifyHelper.send_GS2GS_NTF_NEW_MAIL(login_cache.CurrentServer, to_user_guid);
|
|
}
|
|
}
|
|
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, sent_mail);
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "SendMail", fn_send_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<(Result, ReceivedMailDoc?)> tryMakeNewSystemMail(List<ServerCommon.MailItem> newMailItems, string systemMailMetaKey, Int64 TTL_Period, string packageOrderId)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
if (MetaData.Instance.SystemMailMetaData.TryGetValue(systemMailMetaKey, out var systemMailMetaData) == false)
|
|
{
|
|
result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg);
|
|
return (result, null);
|
|
}
|
|
|
|
(result, var mail_doc) = await Mail.createSystemMailWithMeta(player.getUserGuid(), player.getUserNickname(), systemMailMetaData, newMailItems, TTL_Period, packageOrderId);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Create Mail Failed. !!! : {result.toBasicString()} - {getOwner().toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, mail_doc);
|
|
}
|
|
|
|
public async Task<(Result, ReceivedMailDoc?)> tryMakeNewSystemMail(List<ServerCommon.MailItem> newMailItems, string systemMailMetaKey, DateTime expireDate, string packageOrderId)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
if (MetaData.Instance.SystemMailMetaData.TryGetValue(systemMailMetaKey, out var systemMailMetaData) == false)
|
|
{
|
|
result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg);
|
|
return (result, null);
|
|
}
|
|
|
|
(result, var mail_doc) = await Mail.createSystemMailWithMeta( player.getUserGuid(), player.getUserNickname()
|
|
, systemMailMetaData, newMailItems
|
|
, expireDate, packageOrderId);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Create Mail Failed. !!! : {result.toBasicString()} - {getOwner().toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
SendMailPacketHandler.send_S2C_ACK_SEND_MAIL(player, result, null);
|
|
return (result, null);
|
|
}
|
|
|
|
return (result, mail_doc);
|
|
}
|
|
|
|
private bool checkMailSendTime()
|
|
{
|
|
var mail_profile_attribute = getOwner().getOriginEntityAttribute<MailProfileAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_profile_attribute, () => $"mail_profile_attribute is null !!! - {getOwner().toBasicString()}");
|
|
|
|
if (mail_profile_attribute.SendMailUpdateDay < DateTime.UtcNow.Date.AddHours(MetaHelper.GameConfigMeta.SentMailNumsResetTime).Ticks) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
private void updateMailSendTime(MailProfileAttribute mail_profile_attribute)
|
|
{
|
|
if (mail_profile_attribute.SendMailUpdateDay < DateTime.UtcNow.Date.AddHours(MetaHelper.GameConfigMeta.SentMailNumsResetTime).Ticks)
|
|
{
|
|
mail_profile_attribute.SendMailCount = 0;
|
|
mail_profile_attribute.SendMailUpdateDay = DateTime.UtcNow.Date.AddHours(MetaHelper.GameConfigMeta.SentMailNumsResetTime).Ticks;
|
|
mail_profile_attribute.modifiedEntityAttribute(true);
|
|
}
|
|
}
|
|
|
|
public void NewReceivedMail()
|
|
{
|
|
setNewReceivedMail();
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
player.send_S2C_NTF_NEW_MAIL();
|
|
}
|
|
|
|
public void setNewReceivedMail()
|
|
{
|
|
m_isNewReceivedMail = true;
|
|
}
|
|
|
|
public void NewReceivedSystemMail()
|
|
{
|
|
setNewReceivedSystemMetaMail();
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
|
|
player.send_S2C_NTF_NEW_SYSTEM_MAIL_MAIL();
|
|
}
|
|
|
|
public void setNewReceivedSystemMetaMail()
|
|
{
|
|
m_isReceivedSystemMetaMail = true;
|
|
}
|
|
|
|
//---치트
|
|
public async Task CheatMailSendUpdateDay()
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var fn_cheat_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
var mail_profile_attribute = getOwner().getEntityAttribute<MailProfileAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(mail_profile_attribute, () => $"mail_profile_attribute is null !!! - {player.toBasicString()}");
|
|
|
|
mail_profile_attribute.SendMailCount = 0;
|
|
mail_profile_attribute.SendMailUpdateDay = DateTime.UtcNow.Date.Ticks;
|
|
mail_profile_attribute.modifiedEntityAttribute(true);
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailProfileLogInfo(mail_profile_attribute);
|
|
invokers.Add(new MailProfileBusinessLog(task_log_data));
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.MailInitSendCount
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "Cheat.MailInitSendCount", fn_cheat_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return;
|
|
}
|
|
//중단
|
|
public async Task CheatSetRemainedTime(bool isSendMail, int remainedMin)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var fn_cheat_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var mails = isSendMail == true ? m_sent_mails : m_received_mails;
|
|
|
|
foreach (var mail in mails)
|
|
{
|
|
var mail_attribute = mail.Value.getEntityAttribute<MailAttribute>();
|
|
|
|
//mail_attribute.ExpireTime = remainedMin
|
|
}
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.CheatCommandResetMailCount
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
|
|
}
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
DeleteMailPacketHandler.send_S2C_ACK_DELETE_MAIL(player, result);
|
|
return result;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "Cheat.MailRemainedTime", fn_cheat_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
public async Task<Result> cheatSendMailToMe(int count, bool permanentMail)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var player = getOwner() as Player;
|
|
NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!");
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
|
|
var fn_send_mail = async delegate ()
|
|
{
|
|
var result = new Result();
|
|
var invokers = new List<ILogInvoker>();
|
|
|
|
(result, var read_docs) = await getReceivedMailDoc(player.getUserGuid());
|
|
if (read_docs.Count >= ServerCommon.Constant.MAX_READ_MAIL_DB_COUNT)
|
|
{
|
|
result.setFail(ServerErrorCode.MailMaxTargetReceivedCountExceed, err_msg);
|
|
return result;
|
|
}
|
|
|
|
DateTime now = DateTimeHelper.Current;
|
|
var expireDate = now.AddSeconds(MetaHelper.GameConfigMeta.SendMailStoragePeriod);
|
|
|
|
if (permanentMail == true)
|
|
expireDate = DateTimeHelper.MaxTime;
|
|
|
|
var receive_mail_doc_list = new List<DynamoDbDocBase>();
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
var mail_items = new List<ServerCommon.MailItem>() { new ServerCommon.MailItem() { ItemId = (META_ID)15300313, Count = 1 } };
|
|
|
|
(result, var received_mail_doc) = await Mail.createSystemMail( player.getUserGuid(), player.getUserNickname()
|
|
, "QATeam", "Cheat Test Mail", "QA Team Fighting."
|
|
, new List<string>(), false, mail_items, expireDate, "");
|
|
if (received_mail_doc == null)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
receive_mail_doc_list.Add(received_mail_doc);
|
|
|
|
var task_log_data = MailBusinessLogHelper.toMailLogInfo(received_mail_doc);
|
|
invokers.Add(new MailBusinessLog(task_log_data));
|
|
}
|
|
|
|
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.CheatCommandSendMail
|
|
, server_logic.getDynamoDbClient(), true);
|
|
{
|
|
batch.addQuery(new DBQEntityWrite(receive_mail_doc_list));
|
|
}
|
|
|
|
batch.appendBusinessLogs(invokers);
|
|
|
|
result = await QueryHelper.sendQueryAndBusinessLog(batch);
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
NewReceivedMail();
|
|
return result;
|
|
};
|
|
|
|
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "Cheat.SendMail", fn_send_mail);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|