using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; namespace GameServer.PacketHandler; [PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.RePurchaseItemReq), typeof(RePurchaseItemPacketHandler), typeof(GameLoginListener))] public class RePurchaseItemPacketHandler : PacketRecvHandler { private static void send_S2C_ACK_SHOP_RE_PURCHASE_LIST(Player? owner, Result result, List? rePurchaseItems) { var ack_packet = new ClientToGame { Response = new ClientToGameRes { ErrorCode = result.ErrorCode, RePurchaseItemRes = new ClientToGameRes.Types.RePurchaseItemRes() } }; // 데이터 가져오기 if (result.isSuccess()) { if (null != rePurchaseItems) { foreach (var info in rePurchaseItems) { var attribute = info.getEntityAttribute(); var item = new global::Item { ItemGuid = attribute!.ItemGuid, ItemId = (int)attribute.ItemMetaId, Count = attribute.ItemStackCount, Level = attribute.Level, Slot = attribute.EquipedPos }; item.Attributeids.AddRange(attribute.Attributes.Select(attrib => (int)attrib)); ack_packet.Response.RePurchaseItemRes.Items.Add(item); } } var account_attribute = owner!.getEntityAttribute(); var level_attribute = owner.getEntityAttribute(); var money_attribute = owner.getEntityAttribute(); var nickname_attribute = owner.getEntityAttribute(); var char_info = new CharInfo { Level = (int)level_attribute!.Level, Exp = (int)level_attribute.Exp, Gold = money_attribute!.Gold, Sapphire = money_attribute.Sapphire, Calium = money_attribute.Calium, Ruby = money_attribute.Ruby, Usergroup = account_attribute!.AuthAdminLevelType.ToString(), Operator = (int)account_attribute.AuthAdminLevelType, DisplayName = nickname_attribute!.Nickname, LanguageInfo = (int)account_attribute.LanguageType, IsIntroComplete = 1 }; ack_packet.Response.RePurchaseItemRes.CurrencyInfo = char_info; } GameServerApp.getServerLogic().onSendPacket(owner!, ack_packet); } public override async Task onProcessPacket(ISession entityWithSession, IMessage recvMessage) { var result = new Result(); string err_msg; var entity_player = entityWithSession as Player; NullReferenceCheckHelper.throwIfNull(entity_player, () => $"entity_player is null !!!"); // 1. 기본 정보 체크 var request = (recvMessage as ClientToGame)?.Request.RePurchaseItemReq; if (null == request) { err_msg = $"Failed to get Request !!! : {nameof(ClientToGame.Request.RePurchaseItemReq)}"; result.setFail(ServerErrorCode.InvalidArgument, err_msg); Log.getLogger().error(result.toBasicString()); send_S2C_ACK_SHOP_RE_PURCHASE_LIST(entity_player, result, null); return result; } result = await entity_player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "RePurchaseSoldItem", rePurchaseItemDelegate); if (result.isFail()) { err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {entity_player.toBasicString()}"; Log.getLogger().error(err_msg); send_S2C_ACK_SHOP_RE_PURCHASE_LIST(entity_player, result, null); } return result; async Task rePurchaseItemDelegate() => await rePurchaseItemAsync(entity_player, request.ItemGuid); } private async Task rePurchaseItemAsync(Player entity_player, string item_guid) { var result = new Result(); string err_msg; var shop_action = entity_player.getEntityAction(); var sold_action = shop_action.getSolProductAction(); // 1. 재구매 아이템 체크 var sold_item = sold_action.findSoldProduct(item_guid); if (null == sold_item) { err_msg = $"Fail to get item info () !!! : {nameof(ShopSoldProductAction.findSoldProduct)} - {item_guid}"; result.setFail(ServerErrorCode.NotFoundItemTableId, err_msg); Log.getLogger().error(err_msg); return result; } // 2. item 정보 체크 var item_attrib = sold_item.ItemDoc.getAttrib(); NullReferenceCheckHelper.throwIfNull(item_attrib, () => $"item_attrib is null !!! - {entity_player.toBasicString()}"); (result, var item_data) = ShopHelper.checkItemIdFromTableData((int)item_attrib.ItemMetaId); if (result.isFail()) return result; NullReferenceCheckHelper.throwIfNull(item_data, () => $"item_data is null !!! - {entity_player.toBasicString()}"); // 3. 아이템 지급 var process_re_purchase = await shop_action.processRePurchase(item_data, sold_item); if (process_re_purchase.result.isFail()) return process_re_purchase.result; NullReferenceCheckHelper.throwIfNull(process_re_purchase.changed_item, () => $"process_re_purchase.changed_item is null !!! - {entity_player.toBasicString()}"); // 4. 재화 감소 result = await shop_action.processSpent(process_re_purchase.spent_currency_type, process_re_purchase.spent_currency); if (result.isFail()) return result; // 5. DB 갱신 var batch = new QueryBatchEx( entity_player, LogActionType.ShopRePurchase, GameServerApp.getServerLogic().getDynamoDbClient()); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); batch.addQuery(new QueryFinal()); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) return result; send_S2C_ACK_SHOP_RE_PURCHASE_LIST(entity_player, result, new List { process_re_purchase.changed_item } ); return result; } }