using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using static ClientToGameReq.Types; using static ClientToGameRes.Types; namespace GameServer.PacketHandler; [PacketHandler(typeof(ClientToGameReq), typeof(ClientToGameReq.Types.C2GS_REQ_CONVERT_MATERIAL_TO_CALIUM), typeof(ConvertMaterialToCaliumPacketHandler), typeof(GameLoginListener))] public class ConvertMaterialToCaliumPacketHandler : PacketRecvHandler { private async Task send_S2C_ACK_CONVERT_MATERIAL_TO_CALIUM(Player owner, Result result, double totalCalium, float caliumForUser, List? items) { var ack_packet = new ClientToGame { Response = new ClientToGameRes { ErrorCode = result.ErrorCode, AckConvertMaterialToCalium = new() } }; if (result.isSuccess()) { ack_packet.Response.AckConvertMaterialToCalium.TotalCalium = totalCalium; ack_packet.Response.AckConvertMaterialToCalium.CaliumForUser = caliumForUser; if (null != items) { ack_packet.Response.AckConvertMaterialToCalium.DelItem.AddRange(items.Select(item => item.toItemData4Client())); } // char info 획득 var account_attribute = owner.getOriginEntityAttribute(); var level_attribute = owner.getOriginEntityAttribute(); var money_attribute = owner.getOriginEntityAttribute(); var nickname_attribute = owner.getOriginEntityAttribute(); 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.AckConvertMaterialToCalium.CurrencyInfo = char_info; } GameServerApp.getServerLogic().onSendPacket(owner, ack_packet); await Task.CompletedTask; } public override async Task onProcessPacket(ISession entityWithSession, IMessage recvMessage) { var result = new Result(); string err_msg; var player = entityWithSession as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); // 1. 기본 정보 체크 var request = (recvMessage as ClientToGame)?.Request.ReqConvertMaterialToCalium; if (null == request) { err_msg = $"Failed to get request type !!! : {nameof(ClientToGame.Request.ReqConvertMaterialToCalium)}"; result.setFail(ServerErrorCode.InvalidArgument, err_msg); Log.getLogger().error(result.toBasicString()); await send_S2C_ACK_CONVERT_MATERIAL_TO_CALIUM(player, result, -1, -1, null); return result; } // 2. 변환 로직 시행 result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "CaliumConverterConvertMaterialToCalium", convertMaterialToCaliumDelegate); if (result.isFail()) { err_msg = $"Failed to runTransactionRunnerSafely()!!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); await send_S2C_ACK_CONVERT_MATERIAL_TO_CALIUM(player, result, -1, -1, null); } return result; async Task convertMaterialToCaliumDelegate() => await convertMaterialToCalium(player, request.UseMaterials.ToDictionary()); } private async Task convertMaterialToCalium(Player player, Dictionary useMaterials) { var server_logic = GameServerApp.getServerLogic(); var result = new Result(); var user_calium_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(user_calium_action, () => $"action is null !!!"); var calium_storage_entity = GameServerApp.getServerLogic().findGlobalEntity(); NullReferenceCheckHelper.throwIfNull(calium_storage_entity, () => $"caliuim_storage_entity is null !!! - {player.toBasicString()}"); var calium_storage_action = calium_storage_entity.getEntityAction(); NullReferenceCheckHelper.throwIfNull(calium_storage_action, () => $"calium_storage_action is null !!! - {player.toBasicString()}"); // 0. calium storage 체크 result = await calium_storage_action.enableCaliumStorage(); if (result.isFail()) return result; // 1. Convert 수량 계산 var convert = await user_calium_action.calculationConvertCalium(useMaterials); // 2. Convert 조건 체크 result = user_calium_action.checkConvertConditions(useMaterials, convert.calium, convert.currency); if (result.isFail()) return result; // 3. Item 제거 var delete_materials = await user_calium_action.deleteMaterials(useMaterials); if (delete_materials.result.isFail()) return delete_materials.result; NullReferenceCheckHelper.throwIfNull(delete_materials.items, () => $"delete_materials.items is null !!!"); // 4. 재화 변경 result = await user_calium_action.changeCurrency(convert.calium, MetaHelper.GameConfigMeta.CaliumConverterCommissionType, convert.currency); if (result.isFail()) return result; // 5. 개인 calium converter 정보 수정 result = user_calium_action.changeDailyCalium(player, convert.calium); if (result.isFail()) return result; var delta = -1 * convert.calium; var total_calium = CaliumStorageHelper.AddDoubleByLong(calium_storage_action.getTotalCalium(CaliumStorageType.Converter), delta); // 6. DB 갱신 { var batch = new QueryBatchEx(player, LogActionType.ConvertCalium, GameServerApp.getServerLogic().getDynamoDbClient(), true); batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); batch.addQuery(new DBQStorageCaliumUpdate(CaliumStorageType.Converter, delta)); writeBusinessLog(player, batch, total_calium, convert.calium); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) return result; } // 7. Calium Storage 재로딩 _ = await calium_storage_action.loadStorageAttribute(); // 8. 변경사항 전송 var calium_event_action = calium_storage_entity.getEntityAction(); NullReferenceCheckHelper.throwIfNull(calium_event_action, () => $"calium_event_action is null !!! - {player.toBasicString()}"); await calium_event_action.sendCaliumEventFromPlayer(player, CaliumEventType.extra_get, "컨버터 교환", -1 * convert.currency, 0); // 9. Response 응답 var user_calium_attribute = player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_calium_attribute, () => $"user_calium_attribute is null !!! - {player.toBasicString()}"); await send_S2C_ACK_CONVERT_MATERIAL_TO_CALIUM(player, result, total_calium, (float)user_calium_attribute.DailyCalium, delete_materials.items.ToList()); // 10. 정보 변경 통보 calium_storage_action.sendChangeStorageInfo(); return result; } private void writeBusinessLog(Player player, QueryBatchBase queryBatchBase, double converterTotalCalium, double obtainCalium) { var user_calium_attribute = player.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(user_calium_attribute, () => $"CaliumAttribute is null !!! - {player.toBasicString()}"); // Converter Calium 변화량 기록 var calium_log_data = new CaliumConverterLogData(); calium_log_data.CurrentDailyCalium = user_calium_attribute.DailyCalium; calium_log_data.CurrentTotalCalium = converterTotalCalium; calium_log_data.DeltaDailyCalium = obtainCalium; calium_log_data.DeltaTotalCalium = obtainCalium; calium_log_data.AmountDeltaType = AmountDeltaType.Consume; var calium_business_log = new CaliumBusinessLog(calium_log_data); queryBatchBase.appendBusinessLog(calium_business_log); } }