Files
2025-05-01 07:20:41 +09:00

477 lines
20 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Numerics;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
using SESSION_ID = System.Int32;
using WORLD_META_ID = System.UInt32;
using META_ID = System.UInt32;
using ENTITY_GUID = System.String;
using ACCOUNT_ID = System.String;
using OWNER_GUID = System.String;
using USER_GUID = System.String;
using CHARACTER_GUID = System.String;
using ITEM_GUID = System.String;
using NPC_UNIQUE_ID = System.String;
using UGC_NPC_META_GUID = System.String;
using FARMING_PROP_DOC_SK = System.String;
using ANCHOR_META_GUID = System.String;
using MASTER_GUID = System.String;
using GUARD_KEY = System.String;
namespace GameServer;
public class FarmingAction : EntityActionBase
{
private FarmingEffect? m_progress_farming_nullable = null;
public FarmingAction(EntityBase owner)
: base(owner)
{
}
public override async Task<Result> onInit()
{
await Task.CompletedTask;
var result = new Result();
return result;
}
public override void onClear()
{
return;
}
public async Task<Result> resetFarmingState(bool isApplyDb = true)
{
var result = new Result();
var err_msg = string.Empty;
var owner = getOwner();
var server_logic = GameServerApp.getServerLogic();
var db_client = server_logic.getDynamoDbClient();
if (owner is UgcNpc ugc_npc)
{
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {ugc_npc.toBasicString()}");
var ugc_npc_attribute = ugc_npc.getEntityAttribute<UgcNpcAttribute>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {ugc_npc.toBasicString()}");
if(EntityStateType.UsingByFarming == ugc_npc_attribute.State)
{
ugc_npc_action.resetPos(isApplyDb);
if(true == isApplyDb)
{
(result, var ugc_npc_doc) = await ugc_npc_attribute.toDocBase();
if (result.isFail())
{
return result;
}
NullReferenceCheckHelper.throwIfNull(ugc_npc_doc, () => $"ugc_npc_doc is null !!! - {ugc_npc.toBasicString()}");
result = await db_client.simpleUpdateDocumentWithDocType(ugc_npc_doc);
if (result.isFail())
{
err_msg = $"Failed to simpleUpdateDocumentWithDocType() !!! in resetFarmingState() : {result.toBasicString()} - {ugc_npc.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
var origin_entity_attribute = ugc_npc.getOriginEntityAttribute<UgcNpcAttribute>();
NullReferenceCheckHelper.throwIfNull(origin_entity_attribute, () => $"origin_entity_attribute is null !!! - {ugc_npc.toBasicString()}");
origin_entity_attribute.copyEntityAttributeFromDoc(ugc_npc_doc);
Log.getLogger().debug($"UgcNpc reset of State !!! in resetFarmingState() : {ugc_npc.toStateString()} - {ugc_npc.toBasicString()}");
}
}
}
return result;
}
public async Task<(Result, FarmingEffect?)> tryStartFarming( ANCHOR_META_GUID anchorMetaGuid, Int16 farmingActionTryCount )
{
var result = new Result();
var err_msg = string.Empty;
var owner = getOwner();
var game_zone_action = owner.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
var curr_map = game_zone_action.getLinkedToMap();
if(null == curr_map)
{
// 현재 UgcNpc 타입만 해당되는 로직 이다.
// 추후 인던 관련 설계가 리펙토링되면 재정의된 Map 반환(Master가 입장한 Map 반환) 함수로 처리해야 한다. - kangms
(result, curr_map) = owner.getCurrMapOfMaster();
if(result.isFail())
{
return (result, null);
}
}
NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!!");
// 파밍중인 Anchor 인가?
var found_farming_effect = curr_map.findFarmingEffect(anchorMetaGuid);
if(null != found_farming_effect)
{
err_msg = $"Already farming !!! : anchorMetaGuid:{anchorMetaGuid} - {curr_map.toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.FarmingAlready, err_msg);
return (result, null);
}
// 파밍 객체를 생성 한다.
var farming_effect = new FarmingEffect( owner, curr_map);
result = await farming_effect.onInit();
if (result.isFail())
{
return (result, null);
}
var farming_effect_action = farming_effect.getEntityAction<FarmingEffectAction>();
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {owner.toBasicString()}");
// 파밍을 시도해 본다 !!!
result = await farming_effect_action.tryStartEffect( anchorMetaGuid, farmingActionTryCount );
if (result.isFail())
{
return (result, null);
}
if (owner is UgcNpc ugc_npc)
{
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}");
var curr_anchor_info = farming_effect_action.getAnchorInfo();
NullReferenceCheckHelper.throwIfNull(curr_anchor_info, () => $"curr_anchor_info is null !!! - {owner.toBasicString()}");
var farming_prop_meta_id = curr_anchor_info.AnchorProp.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} - {curr_map.toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.FarmingPropMetaDataNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
if(false == MapHelper.getAnchor(curr_anchor_info.AnchorGuid, out var anchor))
{
err_msg = $"Not found FarmingAnchor in Map !!! : FarmingAnchorGuid:{curr_anchor_info.AnchorGuid} - {curr_map.toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.FarmingAnchorNotFound, err_msg);
Log.getLogger().error(result.toBasicString());
return (result, null);
}
var base_pos = new System.Numerics.Vector3(curr_anchor_info.AnchorPos.X, curr_anchor_info.AnchorPos.Y, curr_anchor_info.AnchorPos.Z);
var delta_pos = new System.Numerics.Vector3(found_farming_prop_meta.FarmingStartPosX, found_farming_prop_meta.FarmingStartPosY, found_farming_prop_meta.FarmingStartPosZ);
var target_position = ugc_npc_action.makeToLocatePosition( base_pos, anchor.Rotation.Pitch, anchor.Rotation.Yaw, anchor.Rotation.Roll
, delta_pos, found_farming_prop_meta.FarmingStartRotate );
ugc_npc_action.modifyStateInfo( EntityStateType.UsingByFarming
, target_position
, anchorMetaGuid
, (META_ID)farming_prop_meta_id
, true );
ugc_npc_action.setCountingAsConnectedUser(true);
result = await ugc_npc_action.tryLocateInGameZone(curr_map);
if (result.isFail())
{
return (result, null);
}
}
return (result, farming_effect);
}
public async Task completedFarmingStart( QueryExecutorBase queryExecutorBase
, Player player
, FarmingEffect farmingEffect
, DBQWriteToAttributeAllWithTransactionRunner transactionRunner )
{
var game_zone_action = player.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
var curr_map = game_zone_action.getLinkedToMap();
NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!!");
var result = await curr_map.tryLocateFarming(farmingEffect);
if (result.isSuccess())
{
attachFarmingEffect(farmingEffect);
await transactionRunner.onMergeAfterQueryCommit();
}
var farming_effect_action = farmingEffect.getEntityAction<FarmingEffectAction>();
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {player.toBasicString()}");
var query_batch = queryExecutorBase.getQueryBatch();
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {player.toBasicString()}");
var log_action = query_batch.getLogAction();
NullReferenceCheckHelper.throwIfNull(log_action, () => $"log_action is null !!! - {player.toBasicString()}");
queryExecutorBase.appendBusinessLog(new FarmingBusinessLog(log_action, farming_effect_action.getFarmingLogInfo()));
if(farmingEffect.onGetOwnerEntityType() == OwnerEntityType.UgcNpc)
{
var ugc_npc = farmingEffect.getRootParent() as UgcNpc;
NullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! - {player.toBasicString()}");
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}");
UgcNpcNotifyHelper.send_GS2C_NTF_BEACON_COMPACT_UPDATE(player, ugc_npc, ugc_npc_action.toUgcNpcCompact());
}
}
public async Task<(Result, FarmingEffect?, ReceivedMailDoc?)> tryCancelFarming( ANCHOR_META_GUID anchorMetaGuid )
{
var result = new Result();
var err_msg = string.Empty;
var owner = getOwner();
var game_zone_action = owner.getEntityAction<GameZoneAction>();
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
var curr_map = game_zone_action.getLinkedToMap();
NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!!");
// 파밍중인 Anchor 인가?
var found_farming_effect = curr_map.findFarmingEffect(anchorMetaGuid);
if (null == found_farming_effect)
{
err_msg = $"Not state farming !!! : anchorMetaGuid:{anchorMetaGuid} - {curr_map.toBasicString()}, {owner.toBasicString()}";
result.setFail(ServerErrorCode.FarmingNotState, err_msg);
return (result, null, null);
}
var farming_effect_action = found_farming_effect.getEntityAction<FarmingEffectAction>();
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {owner.toBasicString()}");
// 파밍을 취소를 시도 한다.
(result, var farming_effect, var to_receive_mail_doc_nullable) = await farming_effect_action.tryCancelFarming( anchorMetaGuid );
if (result.isFail())
{
return (result, null, null);
}
return (result, farming_effect, to_receive_mail_doc_nullable);
}
public async Task completedFarmingCancel( QueryExecutorBase queryExecutorBase
, Player player, Map currMap
, FarmingEffect farmingEffect, ReceivedMailDoc? receivedMailDoc
, DBQWriteToAttributeAllWithTransactionRunner transactionRunner )
{
var result = await currMap.tryRemoveFarming(farmingEffect);
if (result.isSuccess())
{
var parent = farmingEffect.getRootParent();
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {player.toBasicString()}");
var farming_action = parent.getEntityAction<FarmingAction>();
NullReferenceCheckHelper.throwIfNull(farming_action, () => $"farming_action is null !!! - {player.toBasicString()}");
farming_action.detachFarmingEffect(farmingEffect);
await transactionRunner.onMergeAfterQueryCommit();
}
var found_user_mail_action = player.getEntityAction<MailAction>();
NullReferenceCheckHelper.throwIfNull(found_user_mail_action, () => $"found_user_mail_action is null !!! - {player.toBasicString()}");
if (null != receivedMailDoc)
{
found_user_mail_action.NewReceivedMail();
}
var farming_effect_action = farmingEffect.getEntityAction<FarmingEffectAction>();
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {player.toBasicString()}");
var query_batch = queryExecutorBase.getQueryBatch();
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {player.toBasicString()}");
var log_action = query_batch.getLogAction();
NullReferenceCheckHelper.throwIfNull(log_action, () => $"log_action is null !!! - {player.toBasicString()}");
queryExecutorBase.appendBusinessLog(new FarmingBusinessLog(log_action, farming_effect_action.getFarmingLogInfo()));
queryExecutorBase.appendBusinessLog(new FarmingRewardBusinessLog(log_action, farming_effect_action.getFarmingRewardLogInfo()));
if (farmingEffect.onGetOwnerEntityType() == OwnerEntityType.UgcNpc)
{
var ugc_npc = farmingEffect.getRootParent() as UgcNpc;
NullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! - {player.toBasicString()}");
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}");
UgcNpcNotifyHelper.send_GS2C_NTF_BEACON_COMPACT_UPDATE(player, ugc_npc, ugc_npc_action.toUgcNpcCompact());
}
}
public void attachFarmingEffect(FarmingEffect farmingEffect)
{
var owner = getOwner();
m_progress_farming_nullable = farmingEffect;
if(owner is Player player)
{
var player_action = player.getEntityAction<PlayerAction>();
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {owner.toBasicString()}");
var selected_character = player_action.getSelectedCharacter();
NullReferenceCheckHelper.throwIfNull(selected_character, () => $"selected_character is null !!! - {owner.toBasicString()}");
var character_action = selected_character.getEntityAction<CharacterAction>();
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {owner.toBasicString()}");
var farming_effect_attribute = farmingEffect.getEntityAttribute<FarmingEffectAttribute>();
NullReferenceCheckHelper.throwIfNull(farming_effect_attribute, () => $"farming_effect_attribute is null !!! - {owner.toBasicString()}");
character_action.setStateInfo(EntityStateType.UsingByFarming, farming_effect_attribute.AnchorMetaGuid, farming_effect_attribute.FarmingPropMetaId);
character_action.broadcastCharacterInfo();
}
}
public void detachFarmingEffect(FarmingEffect farmingEffect)
{
var owner = getOwner();
var to_detach_anchor_meta_guid = farmingEffect.getAnchorMetaGuid();
if (null == m_progress_farming_nullable)
{
var err_msg = $"m_progress_farming_nullable is null !!! : toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
var curr_anchor_meta_guid = m_progress_farming_nullable.getAnchorMetaGuid();
if (curr_anchor_meta_guid != to_detach_anchor_meta_guid)
{
var err_msg = $"Not match AnchorMetaGuid of Farming !!! : currAnchorGuid:{curr_anchor_meta_guid} == toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
if (owner is Player player)
{
var player_action = player.getEntityAction<PlayerAction>();
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {owner.toBasicString()}");
var selected_character = player_action.getSelectedCharacter();
NullReferenceCheckHelper.throwIfNull(selected_character, () => $"selected_character is null !!! - {owner.toBasicString()}");
var character_action = selected_character.getEntityAction<CharacterAction>();
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {owner.toBasicString()}");
character_action.setStateInfo(EntityStateType.None, string.Empty, 0);
character_action.broadcastCharacterInfo();
}
m_progress_farming_nullable = null;
}
public void detachFarmingEffectByAnchorMetaGuid(ANCHOR_META_GUID anchorMetaGuid)
{
var owner = getOwner();
var to_detach_anchor_meta_guid = anchorMetaGuid;
if (null == m_progress_farming_nullable)
{
var err_msg = $"m_progress_farming_nullable is null !!! : toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
var curr_anchor_meta_guid = m_progress_farming_nullable.getAnchorMetaGuid();
if (curr_anchor_meta_guid != to_detach_anchor_meta_guid)
{
var err_msg = $"Not match AnchorMetaGuid of Farming !!! : currAnchorGuid:{curr_anchor_meta_guid} == toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
Log.getLogger().error(err_msg);
return;
}
m_progress_farming_nullable = null;
}
public bool isFarmingHere()
{
return m_progress_farming_nullable != null;
}
public bool isFarmingState()
{
var owner = getOwner();
if (owner is Player player)
{
var player_action = player.getEntityAction<PlayerAction>();
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {owner.toBasicString()}");
var selected_character = player_action.getSelectedCharacter();
NullReferenceCheckHelper.throwIfNull(selected_character, () => $"selected_character is null !!! - {owner.toBasicString()}");
var character_action = selected_character.getEntityAction<CharacterAction>();
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {owner.toBasicString()}");
if(true == character_action.isFarming())
{
return true;
}
}
else if (owner is UgcNpc ugc_npc)
{
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}");
var ugc_npc_attribute = ugc_npc.getEntityAttribute<UgcNpcAttribute>();
NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {owner.toBasicString()}");
if (EntityStateType.UsingByFarming == ugc_npc_attribute.State)
{
return true;
}
}
return false;
}
public FarmingEffect? getFarmingEffect()
{
return m_progress_farming_nullable;
}
}