using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using Amazon.DynamoDBv2.DocumentModel; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; using ANCHOR_META_GUID = System.String; using USER_GUID = System.String; using USER_NICKNAME = System.String; using LOCATION_UNIQUE_ID = System.String; using META_ID = System.UInt32; namespace GameServer; public static class FarmingHelper { public static async Task tryFinalyzeUncompletedFarmingByMap(Map currMap) { var result = new Result(); var err_msg = string.Empty; var server_logic = GameServerApp.getServerLogic(); var db_client = server_logic.getDynamoDbClient(); var location_unique_id = currMap.getLocationUniqueId(); var farming_location_doc = new FarmingEffectLocationInTargetDoc(location_unique_id); var query_config = db_client.makeQueryConfigForReadByPKOnly(farming_location_doc.getPK()); (result, var read_docs) = await db_client.simpleQueryDocTypesWithQueryOperationConfig(query_config); if (result.isFail()) { err_msg = $"Failed to simpleQueryDocTypesWithQueryOperationConfig() !!! : {result.toBasicString()} - LocationUniqueId:{location_unique_id}"; Log.getLogger().error(err_msg); return result; } var anchors = currMap.getAnchors(); var farming_effects = currMap.getFarmingEffects(); foreach (var doc in read_docs) { var sk = doc.getSK(); (result, var primary_key) = PrimaryKey.parseLinkPKSK(sk); if (result.isFail()) { err_msg = $"Failed to parseLinkPKSK() !!!, invalid FARMING_EFFECT_DOC_LINK_PKSK !!! : {result.toBasicString()}, LINK_PKSK:{sk} - LocationUniqueId:{location_unique_id}"; Log.getLogger().error(err_msg); continue; } var read_farming_effect_location_in_target_attrib = doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(read_farming_effect_location_in_target_attrib, () => $"read_farming_effect_location_in_target_attrib is null !!!"); var user_guid = read_farming_effect_location_in_target_attrib.UserGuid; var user_nickname = read_farming_effect_location_in_target_attrib.UserNickname; var anchor_meta_guid = read_farming_effect_location_in_target_attrib.AnchorMetaGuid; (result, var make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey(anchor_meta_guid, location_unique_id); if (result.isFail()) { err_msg = $"Failed to makePrimaryKey() !!! : {result.toBasicString()}, anchorMetaGuid:{anchor_meta_guid}, locationUniqueId:{location_unique_id} - LocationUniqueId:{location_unique_id}"; Log.getLogger().error(err_msg); Log.getLogger().error(result.toBasicString()); continue; } NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!!"); query_config = db_client.makeQueryConfigForReadByPKSK( make_primary_key.PK, make_primary_key.SK); (result, var found_farming_effect_doc) = await db_client.simpleQueryDocTypeWithQueryOperationConfig(query_config); if (result.isFail()) { err_msg = $"Failed to parse simpleQueryDocTypeWithQueryOperationConfig() !!! : {result.toBasicString()}, PK:{make_primary_key.PK}, SK:{make_primary_key.SK} - LocationUniqueId:{location_unique_id}"; Log.getLogger().error(err_msg); continue; } NullReferenceCheckHelper.throwIfNull(found_farming_effect_doc, () => $"found_farming_effect_doc is null !!!"); var farming_effect_attrib = found_farming_effect_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(farming_effect_attrib, () => $"farming_effect_attrib is null !!!"); ArgumentNullException.ThrowIfNull( anchor_meta_guid == farming_effect_attrib.AnchorMetaGuid , $"Not match Farming AnchorMetaGuid !!! : inLocation:{anchor_meta_guid} == inFarmingEffect:{farming_effect_attrib.AnchorMetaGuid}" ); anchor_meta_guid = farming_effect_attrib.AnchorMetaGuid; if (false == anchors.TryGetValue(anchor_meta_guid, out var found_anchor_info)) { err_msg = $"Not found Farming AnchorInfo in Meta !!! : anchorMetaGuid:{anchor_meta_guid} - LocationUniqueId:{location_unique_id}"; Log.getLogger().error(err_msg); continue; } if (FarmingStateType.Progress == farming_effect_attrib.FarmingState) { result = await FarmingHelper.tryRewardAndPurge( found_farming_effect_doc , farming_effect_attrib.FarmingEndTime, new TimeSpan(0, 0, 0, 0, 0) , user_guid, user_nickname , LogActionType.FarmingIncompletedReward ); if (result.isFail()) { continue; } found_anchor_info.PropState = farming_effect_attrib.FarmingState.toPropState(); found_anchor_info.respawnTime = farming_effect_attrib.FarmingRespawnTime.ToTimestamp(); currMap.PropModifyNoti(found_anchor_info.AnchorGuid); var player_manager = server_logic.getPlayerManager(); if (false == player_manager.tryGetUserByPrimaryKey(user_guid, out var found_user)) { var login_cache_request = new LoginCacheOtherUserRequest(server_logic, server_logic.getRedisConnector(), user_guid); await login_cache_request.fetchLogin(); var login_cache = login_cache_request.getLoginCache(); if (login_cache != null) { FarmingNotifyHelper.send_GS2MQS_NTF_FARMING_END( server_logic , login_cache.CurrentServer , user_guid, found_farming_effect_doc.toFarmingSummary(user_guid) ); } } else { var player_action = found_user.getEntityAction(); NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {found_user.toBasicString()}"); if (FarmingSummonedEntityType.Beacon == farming_effect_attrib.FarmingSummonedEntityType) { var had_ugc_npcs = player_action.getHadUgcNpcs(); if (false == had_ugc_npcs.TryGetValue(farming_effect_attrib.FarmingEntityGuid, out var found_ugc_npc)) { err_msg = $"Not found UgcNpc !!! : ugcNpcMetaGuid:{farming_effect_attrib.FarmingEntityGuid} - {found_user.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().info(result.toBasicString()); continue; } var farming_action = found_ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(farming_action, () => $"farming_action is null !!! - {found_user.toBasicString()}"); result = await farming_action.resetFarmingState(); if (result.isFail()) { err_msg = $"Failed to resetFarmingState() !!! : {result.toBasicString()} - {found_user.toBasicString()}"; Log.getLogger().error(err_msg); continue; } } } } } return result; } public static async Task<(Result, bool)> tryFinalyzeUncompletedFarmingByOwner(EntityBase owner, UserLoader? userLoader = null) { var result = new Result(); var err_msg = string.Empty; var server_logic = GameServerApp.getServerLogic(); var db_client = server_logic.getDynamoDbClient(); var instance_room_storage = new InstanceRoomStorage(); instance_room_storage.Init(server_logic.getRedisDb(), ""); var user_guid = string.Empty; var user_nickname = string.Empty; (result, var entity_profile) = ServerCommon.EntityHelper.getMasterProfile(owner); if(result.isFail()) { return (result, false); } NullReferenceCheckHelper.throwIfNull(entity_profile, () => $"entity_profile is null !!!"); user_guid = entity_profile.MasterGuid; user_nickname = entity_profile.MasterNickname; var is_need_to_register_progress_farming = false; var owner_guid = string.Empty; if(owner is Player player) { owner_guid = user_guid; } else if( owner is UgcNpc ugc_npc ) { owner_guid = ugc_npc.getUgcNpcMetaGuid(); is_need_to_register_progress_farming = true; } (result, var make_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey(owner_guid); if (result.isFail()) { err_msg = $"Failed to makePrimaryKey() !!! : {result.toBasicString()}, OwnerGuid:{owner_guid} - UserGuid:{user_guid}, UserNickname:{user_nickname}"; Log.getLogger().error(err_msg); return (result, false); } NullReferenceCheckHelper.throwIfNull(make_primary_key, () => $"make_primary_key is null !!! - {owner.toBasicString()}"); var query_config = db_client.makeQueryConfigForReadByPKOnly(make_primary_key.PK); (result, var read_doc) = await db_client.simpleQueryDocTypeWithQueryOperationConfig(query_config, false); if(result.isFail()) { err_msg = $"Failed to simpleQueryDocTypeWithQueryOperationConfig() !!! : {result.toBasicString()} - UserGuid:{user_guid}, UserNickname:{user_nickname}"; Log.getLogger().error(err_msg); return (result, false); } if (null == read_doc) { if (owner is UgcNpc ugc_npc) { var farming_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(farming_action, () => $"farming_action is null !!! - {ugc_npc.toBasicString()} - {owner.toBasicString()}"); if(true == farming_action.isFarmingState()) { err_msg = $"UgcNpc Farming State synchronization error !!! - {ugc_npc.toStateString()}, {ugc_npc.toBasicString()} - {owner.toBasicString()}"; Log.getLogger().error(err_msg); return (result, true); } } return (result, false); } var pk = read_doc.getPK(); var sk = read_doc.getSK(); (result, var primary_key) = PrimaryKey.parseLinkPKSK(sk); if (result.isFail()) { err_msg = $"Failed to parseLinkPKSK() !!!, invalid FARMING_EFFECT_DOC_LINK_PKSK !!! : {result.toBasicString()}, LINK_PKSK:{sk} - PK:{pk}, SK:{sk} - UserGuid:{user_guid}, UserNickname:{user_nickname}"; Log.getLogger().error(err_msg); return (result, false); } NullReferenceCheckHelper.throwIfNull(primary_key, () => $"make_primary_key is null !!! - {owner.toBasicString()}"); var location_unique_id = primary_key.SK; query_config = db_client.makeQueryConfigForReadByPKSK(primary_key.PK, primary_key.SK); (result, var found_farming_effect_doc) = await db_client.simpleQueryDocTypeWithQueryOperationConfig(query_config, false); if (result.isFail()) { err_msg = $"Failed to simpleQueryDocTypeWithQueryOperationConfig() !!! : {result.toBasicString()} - PK:{primary_key.PK}, SK:{primary_key.SK}, LocationUniqueId:{location_unique_id} - UserGuid:{user_guid}, UserNickname:{user_nickname}"; Log.getLogger().error(err_msg); return (result, false); } if(null == found_farming_effect_doc) { return (result, true); } NullReferenceCheckHelper.throwIfNull(found_farming_effect_doc, () => $"found_farming_effect_doc is null !!! - {owner.toBasicString()}"); var farming_effect_attrib = found_farming_effect_doc.getAttrib(); NullReferenceCheckHelper.throwIfNull(farming_effect_attrib, () => $"farming_effect_attrib is null !!! - PK:{primary_key.PK}, SK:{primary_key.SK}, UserGuid:{user_guid}, UserNickname:{user_nickname}"); if( FarmingStateType.Progress == farming_effect_attrib.FarmingState ) { (result, var location_unique_id_parts) = Map.parseLOCATION_UNIQUE_ID(location_unique_id); if (result.isFail()) { err_msg = $"Failed to parseLOCATION_UNIQUE_ID() !!! : {result.toBasicString()}, LocationUniqueId:{location_unique_id} - PK:{primary_key.PK}, SK:{primary_key.SK}, UserGuid:{user_guid}, UserNickname:{user_nickname}"; Log.getLogger().error(err_msg); return (result, false); } NullReferenceCheckHelper.throwIfNull(location_unique_id_parts, () => $"location_unique_id_parts is null !!! - {owner.toBasicString()}"); var anchor_meta_guid = found_farming_effect_doc.getCombinationKeyForPK(); var location_target_type = location_unique_id_parts[0]; var map_meta_id = location_unique_id_parts[1]; var instance_number = location_unique_id_parts[2]; // 인스턴스 존재하지 않는다면 즉시 해당 인스턴스의 배치된 파밍은 즉시 보상 이다 !!! var found_instance = await instance_room_storage.GetInstanceRoomInfo(instance_number); if (null == found_instance) { // 파밍 보상을 지급하고 배치된 FarmingEffect를 제거 한다. var reward_result = await FarmingHelper.tryRewardAndPurge( found_farming_effect_doc , farming_effect_attrib.FarmingEndTime, new TimeSpan(0, 0, 0, 0, 0) , user_guid, user_nickname , LogActionType.FarmingIncompletedReward ); if (reward_result.isFail()) { err_msg = $"Failed to FarmingHelper.tryRewardAndPurge() !!! : {result.toBasicString()} - LocationUniqueId:{location_unique_id}, UserGuid:{user_guid}, UserNickname:{user_nickname}"; Log.getLogger().error(err_msg); } if ( owner is UgcNpc ugc_npc ) { var farming_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(farming_action, () => $"farming_action is null !!! - {ugc_npc.toBasicString()} - {owner.toBasicString()}"); if (true == farming_action.isFarmingState()) { return (result, true); } } } else { if (true == is_need_to_register_progress_farming && userLoader != null) { userLoader.pushProgressFarmingSummary(found_farming_effect_doc.toFarmingSummary(user_guid)); } } } return (result, false); } public static async Task tryRewardAndPurge( FarmingEffectDoc farmingEffectDoc , DateTime currentTime, TimeSpan toAddTime , USER_GUID receiverUserGuid, USER_NICKNAME receiverUserNickname , LogActionType farmingLogActionType ) { var result = new Result(); var err_msg = string.Empty; var farming_effect_attrib = farmingEffectDoc.getAttrib(); NullReferenceCheckHelper.throwIfNull(farming_effect_attrib, () => $"farming_effect_attrib in null !!! - userNickName:{receiverUserNickname}"); var anchor_meta_guid = farming_effect_attrib.AnchorMetaGuid; var location_unique_id = farming_effect_attrib.LocationUniqueId; if (false == MapDataTable.Instance.getAnchor(anchor_meta_guid, out var found_anchor)) { err_msg = $"Not found Anchor in MapDataTable !!! : anchorMetaGuid:{anchor_meta_guid} - locationUniqueId:{location_unique_id}, userNickName:{receiverUserNickname}"; result.setFail(ServerErrorCode.NotFoundAnchorGuidInMap, err_msg); Log.getLogger().error(result.toBasicString()); return result; } var farming_prop_meta_id = (Int32)found_anchor.TableID; if (false == MetaData.Instance._FarmingPropMetaTable.TryGetValue(farming_prop_meta_id, out var found_farming_prop_meta)) { err_msg = $"Not found FarmingPropMeta in FarmingPropMetaTable !!! : FarmingPropMetaId:{farming_prop_meta_id} - anchorMetaGuid:{anchor_meta_guid}, locationUniqueId:{location_unique_id}, userNickName:{receiverUserNickname}"; result.setFail(ServerErrorCode.FarmingPropMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return result; } var reward_gacha_group_id = found_farming_prop_meta.RewardGachaGroupID; if (false == MetaData.Instance._GachaMetaTable.TryGetValue(reward_gacha_group_id, out var found_gacha_meta)) { err_msg = $"Not found GachaMeta in GachaMetaTable !!! : RewardGachaGroupId:{reward_gacha_group_id} - anchorMetaGuid:{anchor_meta_guid}, locationUniqueId:{location_unique_id}, userNickName:{receiverUserNickname}"; result.setFail(ServerErrorCode.GachaMetaDataNotFound, err_msg); Log.getLogger().error(result.toBasicString()); return result; } (result, ReceivedMailDoc? to_receive_mail_doc) = await tryReward( farmingEffectDoc , currentTime, toAddTime, (UInt16)found_farming_prop_meta.InteractionCoolTime , (META_ID)reward_gacha_group_id, found_gacha_meta , receiverUserGuid, receiverUserNickname ); if(result.isFail()) { err_msg = $"Failed to tryReward() !!! : {result.toBasicString()} - anchorMetaGuid:{anchor_meta_guid}, locationUniqueId:{location_unique_id}, userNickName:{receiverUserNickname}"; Log.getLogger().error(err_msg); return result; } result = await tryApplyFarmingRewardAndPurge( receiverUserGuid, farmingEffectDoc , farmingLogActionType , (META_ID)reward_gacha_group_id, found_gacha_meta , to_receive_mail_doc); if (result.isFail()) { err_msg = $"Failed to tryApplyFarmingRewardAndPurge() !!! : {result.toBasicString()} - anchorMetaGuid:{anchor_meta_guid}, locationUniqueId:{location_unique_id}, userNickName:{receiverUserNickname}"; Log.getLogger().error(err_msg); return result; } return result; } public static async Task<(Result, ReceivedMailDoc?)> tryReward( FarmingEffectDoc farmingEffectDoc , DateTime farmingEndTime, TimeSpan toAddTime, UInt16 respawnCoolingTimeSec , META_ID rewardGachaGroupId, SelectedGacha selectedGacha , USER_GUID receiverUserGuid, USER_NICKNAME receiverUserNickname ) { var result = new Result(); var err_msg = string.Empty; var server_logic = GameServerApp.getServerLogic(); var db_client = server_logic.getDynamoDbClient(); var system_manager = server_logic.getSystemMailManager(); var farming_effect_attrib = farmingEffectDoc.getAttrib(); NullReferenceCheckHelper.throwIfNull(farming_effect_attrib, () => $"farming_effect_attrib in null !!! - receiverUserNickname:{receiverUserNickname}"); var anchor_meta_guid = farming_effect_attrib.AnchorMetaGuid; var location_unique_id = farming_effect_attrib.LocationUniqueId; PropState prop_state = PropState.None; DateTime respawn_time = DateTimeHelper.MinTime; ReceivedMailDoc? received_mail_doc = null; var reward_count = 0; // 파밍 경과 시간을 계산하여 보상 개수를 산정 한다. var try_count = farming_effect_attrib.FarmingActionReqTryCount; var farming_time = farming_effect_attrib.FarmingEndTime - farming_effect_attrib.FarmingStartTime; if(TimeSpan.Zero < farming_time) { var reward_segment_time = farming_time / try_count; var farming_elapsed_time = farmingEndTime.Add(toAddTime) - farming_effect_attrib.FarmingStartTime; if(TimeSpan.Zero < farming_elapsed_time) { farming_elapsed_time = farming_time < farming_elapsed_time ? farming_time : farming_elapsed_time; reward_count = (short)(farming_elapsed_time / reward_segment_time); farming_effect_attrib.CompletedRewardCount = (short)reward_count; } } // 파밍을 보상을 우편으로 송신 하기 if (0 < reward_count) { var picked_gacha_rewards = new List(); for (var i = 0; i < reward_count; i++) { var picked_gacha_reward = selectedGacha.getRandomReward(); if(null == picked_gacha_reward) { err_msg = $"Empty random reward !!! - rewardGachaGroupId:{rewardGachaGroupId}, Count:{i}, rewardCount:{reward_count}, anchorMetaGuid:{anchor_meta_guid}, receiverNickname:{receiverUserNickname}"; result.setFail(ServerErrorCode.GachaRewardEmpty, err_msg); Log.getLogger().error(result.toBasicString()); continue; } picked_gacha_rewards.Add(picked_gacha_reward); } var system_mail_meta_key = ServerCommon.Constant.FARMING_REWARD_SYSTEM_MAIL_META_KEY; if (MetaData.Instance.SystemMailMetaData.TryGetValue(system_mail_meta_key, out var found_system_mail_meta) == false) { err_msg = $"Not found SystemMailMeta in SystemMailMetaTable !!! : SystemMailMetaKey:{system_mail_meta_key} - anchorMetaGuid:{anchor_meta_guid}"; result.setFail(ServerErrorCode.SystemMailMetaDataNotFound, err_msg); return (result, null); } (result, received_mail_doc) = await Mail.createSystemMailWithMeta( receiverUserGuid, receiverUserNickname , found_system_mail_meta , MetaHelper.toMailItems(picked_gacha_rewards) , MetaHelper.GameConfigMeta.SystemMailStoragePeriod ); if(result.isFail()) { return (result, null); } } // 보상을 받을 수 없는 경우 var respawn_cooling_sec = respawnCoolingTimeSec; if (0 < respawn_cooling_sec) { prop_state = PropState.Respawning; respawn_time = DateTimeHelper.Current.AddSeconds(respawn_cooling_sec); } else { prop_state = PropState.Deactivated; } // 갱신된 파밍 정보를 업데이트 한다. farming_effect_attrib.FarmingActionReqTryCount = 0; farming_effect_attrib.FarmingStartTime = DateTimeHelper.MinTime; farming_effect_attrib.FarmingEndTime = DateTimeHelper.MinTime; farming_effect_attrib.FarmingState = prop_state.toFarmingStateType(); farming_effect_attrib.FarmingRespawnTime = respawn_time; farming_effect_attrib.CompletedRewardCount = 0; return (result, received_mail_doc); } public static async Task tryApplyFarmingRewardAndPurge( USER_GUID userGuid , FarmingEffectDoc farmingEffectDoc , LogActionType farmingLogActionType , META_ID rewardGachaGroupId, SelectedGacha? selectedGacha , ReceivedMailDoc? receivedMailDoc ) { var farming_effect_attrib = farmingEffectDoc.getAttrib(); NullReferenceCheckHelper.throwIfNull(farming_effect_attrib, () => $"farming_effect_attrib in null !!!"); var result = new Result(); var err_msg = string.Empty; var anchor_meta_guid = farming_effect_attrib.AnchorMetaGuid; var location_unique_id = farming_effect_attrib.LocationUniqueId; var farming_entity_guid = farming_effect_attrib.FarmingEntityGuid; var server_logic = GameServerApp.getServerLogic(); var db_client = server_logic.getDynamoDbClient(); var system_manager = server_logic.getSystemMailManager(); var farming_effect_doc_link_pksk = FarmingEffectDoc.makeLINK_PKSK(anchor_meta_guid, location_unique_id); NullReferenceCheckHelper.throwIfNull(farming_effect_doc_link_pksk, () => $"farming_effect_doc_link_pksk in null !!! - anchorMeatGuid:{farming_effect_attrib.AnchorMetaGuid}, farmingEntityGuid:{farming_entity_guid}"); var to_write_docs = new List(); // 보상 우편 지급을 등록 한다. if(null != receivedMailDoc) { to_write_docs.Add(receivedMailDoc); } // 파밍 소유 관계 DB 정보를 제거 한다. var farming_owner_doc = new FarmingEffectOwnerDoc(farming_entity_guid, farming_effect_doc_link_pksk); farming_owner_doc.setQueryType(QueryType.Delete); to_write_docs.Add(farming_owner_doc); // 파밍 배치 DB 정보를 제거 한다. var farming_location_doc = new FarmingEffectLocationInTargetDoc(location_unique_id, farming_effect_doc_link_pksk); farming_location_doc.setQueryType(QueryType.Delete); to_write_docs.Add(farming_location_doc); // 파밍 DB 정보를 제거 한다. var farming_doc = new FarmingEffectDoc(anchor_meta_guid, location_unique_id); farming_doc.setQueryType(QueryType.Delete); to_write_docs.Add(farming_doc); var batch = new QueryBatch( system_manager, new LogActionEx(farmingLogActionType) , server_logic.getDynamoDbClient() , true ); { batch.addQuery(new DBQEntityWrite(to_write_docs)); batch.addQuery(new QueryFinal(), async (_query) => { await completedFarmingRewardAndPurge( _query, userGuid, farming_doc , rewardGachaGroupId, selectedGacha , receivedMailDoc ); return QueryBatchBase.QueryResultType.Success; }); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } return result; } public static async Task completedFarmingRewardAndPurge( QueryExecutorBase queryExecutorBase , USER_GUID userGuid , FarmingEffectDoc farmingDoc , META_ID rewardGachaGroupId, SelectedGacha? selectedGacha , ReceivedMailDoc? receivedMailDoc ) { var server_logic = GameServerApp.getServerLogic(); var player_manager = server_logic.getPlayerManager(); if (player_manager.tryGetUserByPrimaryKey(userGuid, out var found_user) == true) { if (null != receivedMailDoc) { var found_user_mail_action = found_user.getEntityAction(); found_user_mail_action.NewReceivedMail(); } } else { var login_cache_request = new LoginCacheOtherUserRequest(server_logic, server_logic.getRedisConnector(), userGuid); await login_cache_request.fetchLogin(); var login_cache = login_cache_request.getLoginCache(); if (login_cache != null) { var mg_server = server_logic.getRabbitMqConnector() as RabbitMQ4Game; NullReferenceCheckHelper.throwIfNull(mg_server, () => $"mg_server is null !!! - userGuid:{userGuid}"); var s2s_ntf_msg = new ServerMessage(); s2s_ntf_msg.ReceiveMailNoti = new ServerMessage.Types.ReceiveMailNoti() { AccountGuid = userGuid }; mg_server.SendMessage(login_cache.CurrentServer, s2s_ntf_msg); } } var query_batch = queryExecutorBase.getQueryBatch(); NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - userGuid:{userGuid}"); var log_action = query_batch.getLogAction(); NullReferenceCheckHelper.throwIfNull(log_action, () => $"log_action is null !!! - userGuid:{userGuid}"); var reward_meta_type = (selectedGacha != null ? selectedGacha.getTypeName() : string.Empty); query_batch.appendBusinessLog(new FarmingBusinessLog(log_action, farmingDoc.toFarmingLogInfo(userGuid))); query_batch.appendBusinessLog(new FarmingRewardBusinessLog(log_action, farmingDoc.toFarmingRewardLogInfo(userGuid, reward_meta_type, rewardGachaGroupId))); } }