using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; using META_ID = System.UInt32; namespace GameServer; public class ItemBuyAction : EntityActionBase { public List? BuyItems => m_buy_items; private List? m_buy_items { get; set; } public ItemBuyAction(Player owner) : base(owner) { } public override async Task onInit() { await Task.CompletedTask; var result = new Result(); return result; } public override void onClear() { return; } public async Task tryBuyItem(META_ID item_id, int buy_count) { var result = new Result(); var discount = checkPurchaseDiscountType((int)item_id); // 1. item data 체크 (result, var item_data) = checkBuyItemConditions((int)item_id, buy_count); if (result.isFail()) return result; // 2. 구매 처리 (result, var spent_currency_type, var spent_currency) = await processForItem(item_data!, buy_count, discount.discount_rate); if (result.isFail()) return result; // 3. 재화 차감 result = await processSpent(spent_currency_type, spent_currency); if (result.isFail()) return result; result = await updateItemFirstPurchaseHistory(discount.discount_type, (int)item_id); return result; } private async Task<(Result result, CurrencyType spent_currency_type, double spent_currency)> processForItem( MetaAssets.ItemMetaData item_data, int buy_count, int discountRate) { var result = new Result(); string err_msg; var player = getOwner() as Player; var inventory_action = player?.getEntityAction(); if (null == inventory_action) { err_msg = $"Fail to get Inventory Action : {nameof(InventoryActionBase)}."; result.setFail(ServerErrorCode.EntityActionNotFound, err_msg); Log.getLogger().error(err_msg); return (result, CurrencyType.None, 0); } (result, var changed_items) = await inventory_action.tryTakalbleToBag((META_ID)item_data.ItemId, (ushort)buy_count); if (result.isFail()) return (result, CurrencyType.None, 0); m_buy_items ??= new(); m_buy_items.AddRange(changed_items); var check_currency_type = ShopHelper.checkCurrencyTypeFromCurrencyId(item_data.Buy_id); if (check_currency_type.result.isFail()) return (check_currency_type.result, CurrencyType.None, 0); var price = await ShopHelper.checkCaliumCurrency(check_currency_type.currencyType, item_data.BuyPrice, discountRate); return (result, check_currency_type.currencyType, buy_count * price); } private async Task processSpent(CurrencyType spent_currency_type, double spent_currency) { var result = new Result(); var money_action = getOwner().getEntityAction(); if (null == money_action) { var err_msg = $"Fail to get Money Action : {nameof(MoneyAction)}."; result.setFail(ServerErrorCode.EntityActionNotFound, err_msg); Log.getLogger().error(err_msg); return result; } result = await money_action.changeMoney(spent_currency_type, -1 * spent_currency); return result; } (DiscountType discount_type, int discount_rate) checkPurchaseDiscountType(int itemMetaId) { var discount_type = DiscountType.None; int discount_rate = 0; var player = getOwner().getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); var item_first_purchase_history_agent_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(item_first_purchase_history_agent_action, () => $"ItemFirstPurchaseHistoryAgentAction is null !!! - {player.toBasicString()}"); if (!MetaData.Instance._ItemTable.TryGetValue(itemMetaId, out var item_meta_data)) return (discount_type, discount_rate); if (item_first_purchase_history_agent_action.isItemFirstPurchase(item_meta_data.ItemId)) { discount_type = DiscountType.ItemFirstPurchase; discount_rate = item_meta_data.Buy_Discount_Rate; } return (discount_type, discount_rate); } (Result result, MetaAssets.ItemMetaData? item_data) checkBuyItemConditions(int itemMetaId, int buyItemCount) { var result = new Result(); (result, var item_data) = ShopHelper.checkItemIdFromTableData(itemMetaId); if (result.isFail()) { Log.getLogger().error(result.toBasicString()); return (result, null); } var player = getOwner().getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => "player is null !!!"); result = player.checkItemFirstPurchaseItemCount((int)itemMetaId, buyItemCount); if (result.isFail()) { return (result, null); } return (result, item_data); } async Task updateItemFirstPurchaseHistory(DiscountType discountType, int itemMetaId) { var result = new Result(); var player = getOwner().getRootParent(); if (discountType != DiscountType.ItemFirstPurchase) return result; var item_first_purchase_history_agent_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(item_first_purchase_history_agent_action, () => $"ItemFirstPurchaseHistoryAgentAction is null !!! - {player.toBasicString()}"); result = await item_first_purchase_history_agent_action.tryAddItemFirstPurchaseHistoryFromMetaId(itemMetaId); if (result.isFail()) { return result; } return result; } }