초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,557 @@

using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using META_ID = System.UInt32;
namespace GameServer;
public class PackageAction : EntityActionBase
{
private List<PackageRepeat> m_repeat_packages = new ();
public PackageAction(Player owner)
: base(owner)
{
}
public override void onClear()
{
m_repeat_packages.Clear();
return;
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
return result;
}
public void addPackage(PackageRepeat packageRepeat)
{
m_repeat_packages.Add(packageRepeat);
}
public async Task<Result> InsertPackageLastOrderRecodeDoc()
{
var result = new Result();
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
var package_last_order_recode_attribute = player.getEntityAttribute<PackageLastOrderRecodeAttribute>();
NullReferenceCheckHelper.throwIfNull(package_last_order_recode_attribute, () => $"package_last_order_recode_attribute is null !!! - {player.toBasicString()}");
var package_last_order_recode_doc = package_last_order_recode_attribute.getOriginDocBase<PackageLastOrderRecodeAttribute>();
if (package_last_order_recode_doc == null)
{
var server_logic = GameServerApp.getServerLogic();
var dynamo_db_client = server_logic.getDynamoDbClient();
ArgumentNullException.ThrowIfNull(dynamo_db_client);
result = await dynamo_db_client.simpleInsertDocumentWithDocType(new PackageLastOrderRecodeDoc(player.getUserGuid()));
if (result.isFail())
{
var err_msg = $"Failed to simpleUpsertDocumentWithDocType<PackageLastOrderRecodeDoc> !!! - {player.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
}
return result;
}
public async Task<Result> AddPackageFromDocs(List<PackageRepeatDoc> packageDocs)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
foreach (var package_repeat_doc in packageDocs)
{
(result, var package_repeat) = await PackageRepeat.createPackageRepeatFromDoc(player, package_repeat_doc);
if (result.isFail()) return result;
NullReferenceCheckHelper.throwIfNull(package_repeat, () => $"package_repeat is null !!! - {player.toBasicString()}");
m_repeat_packages.Add(package_repeat);
}
return result;
}
public async Task<(Result, PackageRepeat?, List<DynamoDbDocBase>?)> tryOrderNewProduct(string order_guid, META_ID product_meta_id, DateTime buyDateTime, List<ILogInvoker> invokers)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
if (MetaData.Instance._ProductMetaDataById.TryGetValue((int)product_meta_id, out var productMetaData) == false)
{
err_msg = $"Failed to find product meta Id. meta_id : {product_meta_id}";
result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null, null);
}
(result, var new_package_repeat, var receivedMailDocs) = await newGiveProduct(productMetaData, order_guid, buyDateTime);
if (result.isFail()) return (result, null, null);
foreach (var receivedMailDoc in receivedMailDocs)
{
var mail_doc = receivedMailDoc as MailDoc;
ArgumentNullException.ThrowIfNull(mail_doc);
var task_mail_log_data = MailBusinessLogHelper.toMailLogInfo(mail_doc);
ArgumentNullException.ThrowIfNull(task_mail_log_data);
invokers.Add(new MailBusinessLog(task_mail_log_data));
}
var task_state_log_data = PackageBusinessLogHelper.toStateLogInfo(order_guid, BillingStateType.received, string.Empty);
ArgumentNullException.ThrowIfNull(task_state_log_data);
invokers.Add(new PackageStateBusinessLog(task_state_log_data));
if (new_package_repeat != null)
{
var package_repeat_attribute = new_package_repeat.getEntityAttribute<PackageRepeatAttribute>();
ArgumentNullException.ThrowIfNull(package_repeat_attribute);
var task_repeat_log_data = PackageBusinessLogHelper.toRepeatLogInfo(package_repeat_attribute);
invokers.Add(new PackageRepeatBusinessLog(task_repeat_log_data));
}
var package_lastorder_recode_attribute = player.getEntityAttribute<PackageLastOrderRecodeAttribute>();
ArgumentNullException.ThrowIfNull(package_lastorder_recode_attribute);
package_lastorder_recode_attribute.LastOrderGuid = order_guid;
package_lastorder_recode_attribute.LastBuyTime = buyDateTime;
package_lastorder_recode_attribute.modifiedEntityAttribute();
return (result, new_package_repeat, receivedMailDocs);
}
public async Task<Result> tryOrderNewProductList()
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
var server_logic = GameServerApp.getServerLogic();
ArgumentNullException.ThrowIfNull(server_logic);
var mail_action = player.getEntityAction<MailAction>();
ArgumentNullException.ThrowIfNull(mail_action);
var account_attribute = player.getEntityAttribute<AccountAttribute>();
ArgumentNullException.ThrowIfNull(account_attribute);
var package_lastorder_recode_attribute = player.getEntityAttribute<PackageLastOrderRecodeAttribute>();
ArgumentNullException.ThrowIfNull(package_lastorder_recode_attribute);
var jwt = account_attribute.SsoAccountAuthJWT.ToString();
var account_id = account_attribute.AccountId;
if(jwt == string.Empty)
return result;
//BillingServer에 구매내역 조회
var billingPurchaseRequest = new BillingPurchaseRequest() { account_id = account_id.ToString(), order_id = package_lastorder_recode_attribute.LastOrderGuid };
(result, var billingPurchaseInfo) = await BillingServerConnector.GetBillingPurchaseInfos(billingPurchaseRequest, jwt);
if (result.isFail())
return result;
NullReferenceCheckHelper.throwIfNull(billingPurchaseInfo, () => $"billingPurchaseInfo is null !!! - {player.toBasicString()}");
if (billingPurchaseInfo.data.Count == 0)
return result;
(result, var order_id_list) = await mail_action.getReceivedProductMailOrderIds();
if (result.isFail())
return result;
var fn_give_product = async delegate ()
{
var result = new Result();
var invokers = new List<ILogInvoker>();
var new_package_repeats = new List<PackageRepeat>();
var received_mail_docs = new List<DynamoDbDocBase>();
var last_order_product_meta_id = 0;
var last_order_id = "";
var last_order_buy_time = DateTime.UtcNow;
var now = DateTime.UtcNow;
foreach (var order_info in billingPurchaseInfo.data)
{
if (EnumHelper.tryParse<BillingStateType>(order_info.state, out var state) == false)
{
result.setFail(ServerErrorCode.BillingInvalidStateType, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
if (state != BillingStateType.paid)
continue;
last_order_buy_time = DateTimeOffset.FromUnixTimeSeconds(order_info.buyDateTime).UtcDateTime;
if(int.TryParse(order_info.product_meta_id, out last_order_product_meta_id) == false)
{
result.setFail(ServerErrorCode.BillingFailedParseProductMetaIdType, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
bool isAlreadyReceivedMail = false;
foreach (var order_id in order_id_list)
{
if(order_info.order_id == order_id)
{
isAlreadyReceivedMail = true;
var stateList = new List<BillingStateList>() { new BillingStateList() { order_id = order_info.order_id, state = BillingStateType.received.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())
break;
break;
}
}
if(isAlreadyReceivedMail == true)
{
continue;
}
(result, var new_package_repeat, var receivedMailDocs) = await tryOrderNewProduct(order_info.order_id, (META_ID)last_order_product_meta_id, now, invokers);
if (result.isFail())
{
return result;
}
NullReferenceCheckHelper.throwIfNull(receivedMailDocs, () => $"receivedMailDocs is null !!!");
if (new_package_repeat != null)
{
new_package_repeats.Add(new_package_repeat);
}
received_mail_docs.AddRange(receivedMailDocs);
last_order_id = order_info.order_id;
}
if(received_mail_docs.Count == 0)
{
return result;
}
var task_log_data = PackageBusinessLogHelper.toLastOrderRecodeLogInfo(last_order_id, (META_ID)last_order_product_meta_id, last_order_buy_time, now);
ArgumentNullException.ThrowIfNull(task_log_data, $"task_log_data is null !!!");
invokers.Add(new PackageLastOrderRecordBusinessLog(task_log_data));
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.ProductGive
, server_logic.getDynamoDbClient(), true);
{
batch.addQuery(new DBQEntityWrite(received_mail_docs));
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
batch.appendBusinessLogs(invokers);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail())
{
return result;
}
//BillingServer에 상태값 갱신
foreach (var order_info in billingPurchaseInfo.data)
{
(result, var isUpdated) = await BillingServerConnector.AbleToChangeBillingState(jwt, account_id.ToString(), order_info.order_id, BillingStateType.received);
if (result.isFail() || isUpdated == true)
continue;
var stateList = new List<BillingStateList>() { new BillingStateList() { order_id = order_info.order_id, state = BillingStateType.received.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())
continue;
}
foreach (var new_package_repeat in new_package_repeats)
{
m_repeat_packages.Add(new_package_repeat);
}
mail_action.NewReceivedMail();
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "give_product", fn_give_product);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
return result;
}
public async Task<Result> UpdateTick()
{
return await UpdateRepeatProduct();
}
public async Task<Result> UpdateRepeatProduct()
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
var server_logic = GameServerApp.getServerLogic();
if (m_repeat_packages.Count == 0)
return result;
ArgumentNullException.ThrowIfNull(server_logic, $"server_logic is null !!!");
if (isUpdateRepeatProduct() == false)
return result;
var fn_update_give_product = async delegate ()
{
var result = new Result();
var err_msg = string.Empty;
var invokers = new List<ILogInvoker>();
var mail_docs = new List<DynamoDbDocBase>();
var remove_packages = new List<PackageRepeat>();
var mail_action = player.getEntityAction<MailAction>();
ArgumentNullException.ThrowIfNull(mail_action);
var copy_packages = m_repeat_packages.ToList();
foreach (var package in copy_packages)
{
var package_attribute = package.getEntityAttribute<PackageRepeatAttribute>();
ArgumentNullException.ThrowIfNull(package_attribute);
if (MetaData.Instance._ProductMetaDataById.TryGetValue((int)package_attribute.ProductMetaId, out var productMetaData) == false)
{
err_msg = $"Failed to find product meta Id. meta_id : {package_attribute.ProductMetaId}";
result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
(result, var receivedMailDocs, bool isDeleteRepeat) = await updateGiveProduct(productMetaData, package_attribute, package_attribute.OrderGuid, invokers);
if (result.isFail()) return result;
mail_docs.AddRange(receivedMailDocs);
if (isDeleteRepeat == true)
{
remove_packages.Add(package);
}
var task_log_data = PackageBusinessLogHelper.toRepeatLogInfo(package_attribute);
invokers.Add(new PackageRepeatBusinessLog(task_log_data));
}
if (mail_docs.Count == 0)
{
return result;
}
var batch = new QueryBatchEx<QueryRunnerWithDocument>(player, LogActionType.ProductGive
, server_logic.getDynamoDbClient());
{
batch.addQuery(new DBQEntityWrite(mail_docs));
batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner());
}
batch.appendBusinessLogs(invokers);
result = await QueryHelper.sendQueryAndBusinessLog(batch);
if (result.isFail()) return result;
foreach (var remove_package in remove_packages)
{
m_repeat_packages.Remove(remove_package);
}
mail_action.NewReceivedMail();
return result;
};
result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "update_give_product", fn_update_give_product);
if (result.isFail())
{
err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}";
Log.getLogger().error(err_msg);
}
return result;
}
private async Task<(Result, PackageRepeat?, List<DynamoDbDocBase>)> newGiveProduct(ProductMetaData productMetaData, string order_guid, DateTime buyDateTime)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
var mail_action = player.getEntityAction<MailAction>();
ArgumentNullException.ThrowIfNull(mail_action);
var receivedMailDocs = new List<DynamoDbDocBase>();
if(productMetaData.ItemID_First != 0)
{
var expireDate = DateTimeHelper.MaxTime;
if (productMetaData.Storage_Period_First != 0)
expireDate = buyDateTime.AddMinutes(productMetaData.Storage_Period_First);
var mail_Items = new List<ServerCommon.MailItem>() { new ServerCommon.MailItem() { ItemId = (META_ID)productMetaData.ItemID_First, Count = 1, ProductId = (META_ID)productMetaData.Id, isRepeatProduct = false } };
(result, var firstReceivedMailDoc) = await mail_action.tryMakeNewSystemMail(mail_Items, productMetaData.SystemMail_First, expireDate, order_guid);
if (result.isFail()) return (result, null, receivedMailDocs);
NullReferenceCheckHelper.throwIfNull(firstReceivedMailDoc, () => $"firstReceivedMailDoc is null !!!");
receivedMailDocs.Add(firstReceivedMailDoc);
}
var nowTime = DateTime.UtcNow;
var next_give_time = buyDateTime;
var repeat_count = productMetaData.Mail_Repeat_Count;
var left_count = productMetaData.Mail_Repeat_Count;
for (int i = 0; i < repeat_count; ++i)
{
if (nowTime < next_give_time)
{
break;
}
var expireDate = DateTimeHelper.MaxTime;
if (productMetaData.Storage_Period_Repeat != 0)
expireDate = next_give_time.AddMinutes(productMetaData.Storage_Period_Repeat);
var mail_Items = new List<ServerCommon.MailItem>() { new ServerCommon.MailItem() { ItemId = (META_ID)productMetaData.ItemID_Repeat, Count = 1, ProductId = (META_ID)productMetaData.Id, isRepeatProduct = true } };
(result, var receivedMailDoc) = await mail_action.tryMakeNewSystemMail(mail_Items,productMetaData.SystemMail_Repeat, expireDate, order_guid);
if (result.isFail()) return (result, null, receivedMailDocs);
NullReferenceCheckHelper.throwIfNull(receivedMailDoc, () => $"receivedMailDoc is null !!!");
receivedMailDocs.Add(receivedMailDoc);
--left_count;
next_give_time = next_give_time.AddMinutes(productMetaData.Mail_Repeat_Interval);
}
if (left_count <= 0)
{
return (result, null, receivedMailDocs);
}
(result, var package) = await PackageRepeat.createPackageRepeat(player, order_guid, (META_ID)productMetaData.Id, left_count, next_give_time);
if (result.isFail())
{
return (result, null, receivedMailDocs);
}
return (result, package, receivedMailDocs);
}
public bool isUpdateRepeatProduct()
{
var copy_packages = m_repeat_packages.ToList();
var nowTime = DateTime.UtcNow;
foreach (var package in copy_packages)
{
var package_attribute = package.getEntityAttribute<PackageRepeatAttribute>();
ArgumentNullException.ThrowIfNull(package_attribute);
if (nowTime < package_attribute.NextGiveTime)
continue;
return true;
}
return false;
}
private async Task<(Result, List<DynamoDbDocBase>, bool isDeleteRepeat)> updateGiveProduct(ProductMetaData productMetaData, PackageRepeatAttribute package_attribute, string order_guid, List<ILogInvoker> invokers)
{
var result = new Result();
var err_msg = string.Empty;
var player = getOwner() as Player;
ArgumentNullException.ThrowIfNull(player);
var receivedMailDocs = new List<DynamoDbDocBase>();
var nowTime = DateTime.UtcNow;
var next_give_time = package_attribute.NextGiveTime;
var repeat_count = package_attribute.LeftCount;
var left_count = package_attribute.LeftCount;
for (int i = 0; i < repeat_count; ++i)
{
if (nowTime < next_give_time)
break;
--left_count;
var expireDate = DateTimeHelper.MaxTime;
if (productMetaData.Storage_Period_Repeat != 0)
expireDate = next_give_time.AddMinutes(productMetaData.Storage_Period_Repeat);
next_give_time = next_give_time.AddMinutes(productMetaData.Mail_Repeat_Interval);
if (expireDate < nowTime)
{
var task_mail_expired_log_data = MailBusinessLogHelper.toMailExpiredLogInfo(order_guid, productMetaData.Id, next_give_time, expireDate, nowTime, left_count);
invokers.Add(new MailExpiredBusinessLog(task_mail_expired_log_data));
continue;
}
var mail_action = player.getEntityAction<MailAction>();
var mail_Items = new List<ServerCommon.MailItem>() { new ServerCommon.MailItem() { ItemId = (META_ID)productMetaData.ItemID_Repeat, Count = 1, ProductId = (META_ID)productMetaData.Id, isRepeatProduct = true } };
(result, var receivedMailDoc) = await mail_action.tryMakeNewSystemMail(mail_Items, productMetaData.SystemMail_Repeat, expireDate, order_guid);
NullReferenceCheckHelper.throwIfNull(receivedMailDoc, () => $"receivedMailDoc is null !!! - {player.toBasicString()}");
receivedMailDocs.Add(receivedMailDoc);
}
foreach (var receivedMailDoc in receivedMailDocs)
{
var mail_doc = receivedMailDoc as MailDoc;
ArgumentNullException.ThrowIfNull(mail_doc);
var task_mail_log_data = MailBusinessLogHelper.toMailLogInfo(mail_doc);
invokers.Add(new MailBusinessLog(task_mail_log_data));
}
if (left_count <= 0)
{
package_attribute.deleteEntityAttribute();
return (result, receivedMailDocs, true);
}
else
{
package_attribute.NextGiveTime = next_give_time;
package_attribute.LeftCount = left_count;
package_attribute.modifiedEntityAttribute();
return (result, receivedMailDocs, false);
}
}
}