using MetaAssets; using ServerCommon; using ServerCore; using ServerBase; using System.Collections.Concurrent; using NeoSmart.AsyncLock; using GameServer.PacketHandler; using UGCNPC_GUID = System.String; using META_ID = System.UInt32; using ANCHOR_GUID = System.String; using LOCATION_UNIQUE_ID = System.String; using System.Diagnostics.CodeAnalysis; using System.Linq; namespace GameServer { public class CraftAction : EntityActionBase { private ConcurrentDictionary m_Crafts = new(); private bool m_isUpdateCraft = false; public CraftAction(Player owner) : base(owner) { } public override Task onInit() { var result = new Result(); return Task.FromResult(result); } public override void onClear() { m_Crafts.Clear(); } public bool isCraftingHome() { if(m_Crafts.Count == 0) { return false; } return true; } public void setUpdateCraft(bool isUpdateCraft) { m_isUpdateCraft = isUpdateCraft; } public bool isAnchorCrafting(string anchorGuid) { return m_Crafts.ContainsKey(anchorGuid); } public List getCraftInfoList() { return m_Crafts.Values.Select(x => x.toCraftData4Client()).ToList(); } public bool getCraftInfo(string anchorGuid, [MaybeNullWhen(false)] out CraftInfo craftInfo ) { craftInfo = default; if (!m_Crafts.TryGetValue(anchorGuid, out var craft)) return false; craftInfo = craft.toCraftData4Client(); return true; } public async Task AddCraftFromDocs(List craftDocs) { var result = new Result(); var err_msg = string.Empty; m_Crafts.Clear(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); foreach (var craft_doc in craftDocs) { (result, var craft) = await Craft.createCraftFromDoc(player, craft_doc); if(craft is null) { err_msg = $"Failed to create craft from doc"; Log.getLogger().error(err_msg); continue; } var craft_attribute = craft.getEntityAttribute(); if (craft_attribute is null) { err_msg = $"craft_attribute is null"; Log.getLogger().error(err_msg); continue; } if (m_Crafts.TryAdd(craft_attribute.AnchorGuid, craft) == false) { err_msg = $"Failed to get craft attribute : {nameof(CraftAttribute)}"; result.setFail(ServerErrorCode.EntityAttributeIsNull, err_msg); Log.getLogger().error(result.toBasicString()); return result; } } return result; } public async Task ReloadCraft() { var result = new Result(); var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var craft_doc = new CraftDoc(); craft_doc.setCombinationKeyForPK(player.getUserGuid()); craft_doc.onApplyPKSK(); var query_config = server_logic.getDynamoDbClient().makeQueryConfigForReadByPKOnly(craft_doc.getPK()); (result, var craft_docs) = await server_logic.getDynamoDbClient().simpleQueryDocTypesWithQueryOperationConfig(query_config); if (result.isFail()) { return result; } result = await AddCraftFromDocs(craft_docs); if (result.isFail()) { return result; } return result; } public async Task StartCraftProcess(ANCHOR_GUID anchor_guid, META_ID craft_meta_id, UGCNPC_GUID beacon_guid, Pos beacon_pos, int craft_count) { var result = new Result(); var err_msg = string.Empty; if(m_isUpdateCraft == true) { await ReloadCraft(); } var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!"); if (MetaData.Instance._CraftingMetaTable.TryGetValue((int)craft_meta_id, out var crafting_meta_data) == false) { err_msg = $"Not found meta of crafting !!! : craft_meta_id : {craft_meta_id} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } result = checkStartCrafting(anchor_guid, crafting_meta_data, beacon_guid, craft_count); if (result.isFail()) { StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } var inventory_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!"); var player_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!!"); var myhome_agent_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(myhome_agent_action, () => $"myhome_agent_action is null !!!"); DateTime now = DateTimeHelper.Current; DateTime craft_finish_date = now.AddSeconds(crafting_meta_data.CraftingTime * craft_count); string myhome_guid = string.Empty; UgcNpc? ugc_npc = null; if (beacon_guid != string.Empty) { ugc_npc = player_action.findUgcNpc(beacon_guid); if (ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {beacon_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } craft_finish_date = craft_finish_date.AddSeconds(-1 * crafting_meta_data.Beacon_ReduceTime * craft_count); myhome_guid = myhome_agent_action.getMyHomeGuidByAnchorGuid(anchor_guid); if(myhome_guid.isNullOrWhiteSpace()) { err_msg = $"Failed to get Myhome Guid. anchor_guid : {anchor_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.AnchorIsNotInMyhome, err_msg); Log.getLogger().error(err_msg); StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } } var fn_start_craft_profile = async delegate () { var result = new Result(); var err_msg = string.Empty; var invokers = new List(); DynamoDbDocBase? dynamoDbDocBase = null; if (ugc_npc != null) { EntityPos entityPos = beacon_pos == null ? new EntityPos() : new EntityPos() { X = beacon_pos.X, Y = beacon_pos.Y, Z = beacon_pos.Z, FacingAngle = beacon_pos.Angle }; modifyNpcData(player, ugc_npc, anchor_guid, entityPos); dynamoDbDocBase = MakeNewNpcLocationDoc(ugc_npc, entityPos, anchor_guid, myhome_guid); } List decrease_changed_items = new List(); foreach (var material in crafting_meta_data.Material) { (result, var found_delete_item) = await inventory_action.tryDeleteItemByMetaId((META_ID)material.ItemId, (ushort)(material.ItemValue * craft_count)); if (result.isFail()) { StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } decrease_changed_items.AddRange(found_delete_item); } (result, var craft) = await Craft.createCraft(player, anchor_guid, craft_meta_id, beacon_guid, now, craft_finish_date, craft_count); if (result.isFail()) { StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } NullReferenceCheckHelper.throwIfNull(craft, () => $"craft is null !!!"); var craft_attribute = craft.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(craft_attribute, () => $"craft_attribute is null !!!"); var task_log_data = CraftBusinessLogHelper.toCraftLogInfo(craft_attribute); invokers.Add(new CraftBusinessLog(task_log_data)); var batch = new QueryBatchEx( player, LogActionType.CraftStart , server_logic.getDynamoDbClient() ); { if(dynamoDbDocBase != null) batch.addQuery(new DBQEntityWrite(new List() { dynamoDbDocBase })); batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } batch.appendBusinessLogs(invokers); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result); return result; } m_Crafts.TryAdd(anchor_guid, craft); if (ugc_npc != null) { var ugc_npc_action = ugc_npc.getEntityAction(); ugc_npc_action.setCountingAsConnectedUser(false); var game_zone_action = player.getEntityAction(); var map = game_zone_action.getLinkedToMap(); NullReferenceCheckHelper.throwIfNull(map, () => $"map is null !!!"); result = await ugc_npc_action.tryLocateInGameZone(map, myhome_guid); if(result.isSuccess()) { UgcNpcNotifyHelper.send_GS2C_NTF_BEACON_COMPACT_UPDATE(player, ugc_npc, ugc_npc_action.toUgcNpcCompact()); } } StartCraftPacketHandler.send_S2C_ACK_START_CRAFT(player, result, craft, decrease_changed_items, beacon_pos); game_zone_action.broadcast(player, CraftNotifyHelper.makeNotiCraftInfoPacket(m_Crafts.Select(x => x.Value.toCraftData4Client()).ToList(), player.getUserGuid())); return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "StartCraft", fn_start_craft_profile); if (result.isFail()) { err_msg = $"Failed to runTransactionRunnerSafely() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); } return result; } private void modifyNpcData(Player player, UgcNpc ugc_npc, string anchor_guid, EntityPos currPos) { var anchor_meta_id = getAnchorMetaId(player, anchor_guid); var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}"); ugc_npc_action.modifyStateInfo( EntityStateType.UsingByCrafting , currPos , anchor_guid, (META_ID)anchor_meta_id ); } private int getAnchorMetaId(Player player, string anchor_guid) { var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!"); var crafting_anchor = game_zone_action.GetAnchor(anchor_guid); if (crafting_anchor == null) { return 0; } return crafting_anchor.AnchorProp.TableId; } private Result checkStartCrafting(ANCHOR_GUID anchor_guid, CraftingMetaData crafting_meta_data, UGCNPC_GUID beacon_guid, int craft_count) { var result = new Result(); var err_msg = string.Empty; if (m_Crafts.TryGetValue(anchor_guid, out var craft) == true) { err_msg = $"this Anchor is already Crafting now. anchor_guid : {anchor_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingAlreadyCrafting, err_msg); Log.getLogger().error(err_msg); return result; } if (beacon_guid != string.Empty) { result = checkNpcState(beacon_guid); if (result.isFail()) { return result; } } result = checkAbility(crafting_meta_data,beacon_guid); if (result.isFail()) { return result; } result = checkAnchor(crafting_meta_data, anchor_guid); if(result.isFail()) { return result; } //레시피 확인 if (crafting_meta_data.RecipeType == ERecipeType.Add) { result = checkRecipe((META_ID)crafting_meta_data.Id); if (result.isFail()) { return result; } } if(crafting_meta_data.max_craft_limit < craft_count || craft_count < 1) { err_msg = $"craft limit is over. craft meta ID : {crafting_meta_data.Id} - max_craft_limit : {crafting_meta_data.max_craft_limit} - request craft_count : {craft_count} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftInvalidRequestCount, err_msg); Log.getLogger().error(err_msg); return result; } return result; } private Result checkRecipe(META_ID craft_meta_id) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var craft_recipe_action = player.getEntityAction(); if (craft_recipe_action.HasRecipe((META_ID)craft_meta_id) == false) { err_msg = $"Recipe is not register. Craft_meta_id : {craft_meta_id} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingRecipeIsNotRegister, err_msg); Log.getLogger().error(err_msg); return result; } return result; } private Result checkNpcState(UGCNPC_GUID ugcNpc_guid) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var player_action = player.getEntityAction(); var ugc_npc = player_action.findUgcNpc(ugcNpc_guid); if (ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {ugcNpc_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); return result; } var ugc_ncp_attribute = ugc_npc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_ncp_attribute, () => $"ugc_ncp_attribute is null !!!"); if (ugc_ncp_attribute.State != EntityStateType.None) { result.setFail(ServerErrorCode.NpcIsBusy, err_msg); return result; } return result; } private Result checkAbility(CraftingMetaData crafting_meta_data, UGCNPC_GUID ugcNpc_guid) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var ability_action = player.getEntityAction(); if (ugcNpc_guid != string.Empty) { var player_action = player.getEntityAction(); var ugc_npc = player_action.findUgcNpc(ugcNpc_guid); if (ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {ugcNpc_guid} - {player.toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); return result; } ability_action = ugc_npc.getEntityAction(); } foreach (var attribute in crafting_meta_data.Attribute) { if (false == EnumHelper.tryParse(attribute.AttributeName, out var attribute_type)) { err_msg = $"Invalid Ability Enum Type : {attribute_type} - {player.toBasicString()}"; result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg); Log.getLogger().error(err_msg); return result; } var attribute_value = ability_action.getAbility(attribute_type); if (attribute_value == null) { err_msg = $"Invalid Ability Enum Type : {attribute_type} - {player.toBasicString()}"; result.setFail(ServerErrorCode.ServerTypeInvalid, err_msg); Log.getLogger().error(err_msg); return result; } if (attribute_value < attribute.AttributeValue) { err_msg = $"Not Enough Attribute for Craft. attribute name : {attribute_type}, need attribute : {attribute_value}, current attribute : {attribute.AttributeValue} - {player.toBasicString()}"; result.setFail(ServerErrorCode.NotEnoughAttribute, err_msg); Log.getLogger().info(err_msg); return result; } } return result; } private Result checkAnchor(CraftingMetaData crafting_meta_data, ANCHOR_GUID anchor_guid) { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!"); var crafting_anchor = game_zone_action.GetAnchor(anchor_guid); if (crafting_anchor == null) { err_msg = $"anchor is not placed !!! - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingAnchorIsNotPlaced, err_msg); Log.getLogger().error(err_msg); HelpCraftPacketHandler.send_S2C_ACK_HELP_CRAFT(player, result); return result; } if (MetaData.Instance._ItemTable.TryGetValue(crafting_anchor.AnchorProp.TableId, out var item_meta_data) == false) { err_msg = $"Not found meta of Item !!! : item_meta_id : {crafting_anchor.AnchorProp.TableId} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.ItemMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return result; } if (item_meta_data.PropSmallType != crafting_meta_data.PropSmallType) { err_msg = $"Group ID Not match with recipe. item PropSmallType : {item_meta_data.PropSmallType}, crafting PropSmallType : {crafting_meta_data.PropSmallType} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingAnchorIsNotMatchWithRecipe, err_msg); Log.getLogger().error(err_msg); return result; } return result; } private NpcLocationInTargetDoc MakeNewNpcLocationDoc(UgcNpc ugcNpc, EntityPos currPos, string anchorMetaGuid, string myhomeMetaGuid) { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); ArgumentNullReferenceCheckHelper.throwIfNull(ugcNpc, () => $"ugcNpc is null !!! - {player.toBasicString()}"); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}"); var curr_map = game_zone_action.getLinkedToMap(); NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!! - {player.toBasicString()}"); var ugc_npc_action = ugcNpc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}"); var ugc_npc_attribute = ugcNpc.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {player.toBasicString()}"); var location_unique_id = curr_map.makeLOCATION_UNIQUE_IDByMetaId(myhomeMetaGuid); var npcLocation = new NpcLocation() { AnchorMetaGuid = anchorMetaGuid, CurrentPos = currPos }; var doc = new NpcLocationInTargetDoc(location_unique_id, anchorMetaGuid , EntityType.UgcNpc, ugc_npc_attribute.UgcNpcMetaGuid, npcLocation , ugc_npc_attribute.OwnerEntityType, ugc_npc_attribute.OwnerGuid); doc.setQueryType(QueryType.Insert); return doc; } private NpcLocationInTargetDoc MakeDeleteNpcLocationDoc(string anchorMetaGuid, string myhomeMetaGuid) { var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!! - {player.toBasicString()}"); var curr_map = game_zone_action.getLinkedToMap(); NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!! - {player.toBasicString()}"); var location_unique_id = curr_map.makeLOCATION_UNIQUE_IDByMetaId(myhomeMetaGuid); return new NpcLocationInTargetDoc(location_unique_id, anchorMetaGuid); } public async Task StopCraftProcess(ANCHOR_GUID anchor_guid) { var result = new Result(); var err_msg = string.Empty; if (m_isUpdateCraft == true) { await ReloadCraft(); } var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {player.toBasicString()}"); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!"); if (m_Crafts.TryGetValue(anchor_guid, out var craft) == false) { err_msg = $"this Anchor is not Crafting now. anchor_guid : {anchor_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingNotCraftingAnchor, err_msg); Log.getLogger().error(err_msg); StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result); return result; } Int32 craft_meta_id = 0; var fn_stop_craft_profile = async delegate () { var result = new Result(); var err_msg = string.Empty; var invokers = new List(); DynamoDbDocBase? dynamoDbDocBase = null; var craft_attribute = craft.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(craft_attribute, () => $"craft_attribute is null !!!"); craft_attribute.deleteEntityAttribute(); UgcNpc? ugc_npc = null; if (craft_attribute.BeaconGuid != string.Empty) { var player_action = player.getEntityAction(); ugc_npc = player_action.findUgcNpc(craft_attribute.BeaconGuid); if (ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {craft_attribute.BeaconGuid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result); return result; } var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null - {player.toBasicString()}"); var myhome_agent_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(myhome_agent_action, () => $"myhome_agent_action is null !!!"); var myhome_guid = myhome_agent_action.getMyHomeGuidByAnchorGuid(anchor_guid); if (myhome_guid.isNullOrWhiteSpace()) { err_msg = $"Failed to get Myhome Guid. anchor_guid : {anchor_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.AnchorIsNotInMyhome, err_msg); Log.getLogger().error(err_msg); StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result); return result; } ugc_npc_action.modifyStateInfo(EntityStateType.None, new EntityPos(), ""); dynamoDbDocBase = MakeDeleteNpcLocationDoc(anchor_guid, myhome_guid); } var inventory_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!"); if (MetaData.Instance._CraftingMetaTable.TryGetValue((int)craft_attribute.CraftMetaId, out var crafting_meta_data) == false) { err_msg = $"Not found meta of Item !!! : CraftingMetaId:{craft_attribute.CraftMetaId} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result); return result; } List Increase_changed_items = new List(); foreach(var material in crafting_meta_data.Material) { (result, var crafting_items) = await inventory_action.tryTakalbleToBag((META_ID)material.ItemId, (ushort)(material.ItemValue * craft_attribute.CraftCount)); if (result.isFail()) { StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result); return result; } Increase_changed_items.AddRange(crafting_items); } var task_log_data = CraftBusinessLogHelper.toCraftLogInfo(craft_attribute); invokers.Add(new CraftBusinessLog(task_log_data)); var batch = new QueryBatchEx( player, LogActionType.CraftStop , server_logic.getDynamoDbClient() ); { if(dynamoDbDocBase != null) batch.addQuery(new DBQEntityDelete(dynamoDbDocBase)); batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } batch.appendBusinessLogs(invokers); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result); return result; } m_Crafts.TryRemove(anchor_guid, out craft); if (ugc_npc != null) { var ugc_npc_action = ugc_npc.getEntityAction(); var game_zone_action = player.getEntityAction(); result = await ugc_npc_action.tryRemoveInGameZone(); if(result.isSuccess()) { UgcNpcNotifyHelper.send_GS2C_NTF_BEACON_COMPACT_UPDATE(player, ugc_npc, ugc_npc_action.toUgcNpcCompact()); } } StopCraftPacketHandler.send_S2C_ACK_STOP_CRAFT(player, result, anchor_guid, craft_attribute.BeaconGuid, Increase_changed_items); game_zone_action.broadcast(player, CraftNotifyHelper.makeNotiCraftInfoPacket(m_Crafts.Select(x => x.Value.toCraftData4Client()).ToList(), player.getUserGuid())); craft_meta_id = (Int32)craft_attribute.CraftMetaId; return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "StopCraft", fn_stop_craft_profile); if (result.isFail()) { err_msg = $"Failed to runTransaction() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); } if (craft_meta_id > 0) { await QuestManager.It.QuestCheck(player, new QuestCrafting(EQuestEventTargetType.CRAFTING, EQuestEventNameType.STOPPED, craft_meta_id)); } return result; } public async Task FinishCraftProcess(ANCHOR_GUID anchor_guid) { var result = new Result(); var err_msg = string.Empty; if (m_isUpdateCraft == true) { await ReloadCraft(); } var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var server_logic = GameServerApp.getServerLogic(); var game_zone_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!"); if (m_Crafts.TryGetValue(anchor_guid, out var craft) == false) { err_msg = $"this Anchor is not Crafting now. anchor_guid : {anchor_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingNotCraftingAnchor, err_msg); Log.getLogger().error(err_msg); return result; } var craft_attribute = craft.getOriginEntityAttribute(); NullReferenceCheckHelper.throwIfNull(craft_attribute, () => $"craft_attribute is null !!!"); DateTime now = DateTimeHelper.Current; if (craft_attribute.CraftFinishTime > now) { err_msg = $"Crafting Not Finish Time : now : {now} - craftFinishTime : {craft_attribute.CraftFinishTime} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingNotFinish, err_msg); Log.getLogger().error(err_msg); return result; } if (MetaData.Instance._CraftingMetaTable.TryGetValue((int)craft_attribute.CraftMetaId, out var crafting_meta_data) == false) { err_msg = $"Not found meta of Item !!! : CraftingMetaId:{craft_attribute.CraftMetaId} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.CraftingMetaDataNotFound, err_msg); Log.getLogger().error(err_msg); return result; } var fn_finish_craft_profile = async delegate () { var result = new Result(); var err_msg = string.Empty; var invokers = new List(); DynamoDbDocBase? dynamoDbDocBase = null; var inventory_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!"); var craft_attribute = craft.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(craft_attribute, () => $"craft_attribute is null !!!"); craft_attribute.deleteEntityAttribute(); List Increase_changed_items = new List(); (result, var crafting_items) = await inventory_action.tryTakalbleToBag((META_ID)crafting_meta_data.Crafting_ItemId, (ushort)(crafting_meta_data.Crafting_ItemValue * craft_attribute.CraftCount)); if (result.isFail()) { FinishCraftPacketHandler.send_S2C_ACK_FINISH_CRAFT(player, result); return result; } Increase_changed_items.AddRange(crafting_items); UgcNpc? ugc_npc = null; if (craft_attribute.BeaconGuid != string.Empty) { var player_action = player.getEntityAction(); ugc_npc = player_action.findUgcNpc(craft_attribute.BeaconGuid); if (ugc_npc == null) { err_msg = $"UgcNpc Not Found UgcNpc Guid : {craft_attribute.BeaconGuid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.UgcNpcNotFound, err_msg); Log.getLogger().error(err_msg); FinishCraftPacketHandler.send_S2C_ACK_FINISH_CRAFT(player, result); return result; } var myhome_agent_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(myhome_agent_action, () => $"myhome_agent_action is null !!!"); var myhome_guid = myhome_agent_action.getMyHomeGuidByAnchorGuid(anchor_guid); if (myhome_guid.isNullOrWhiteSpace()) { err_msg = $"Failed to get Myhome Guid. anchor_guid : {anchor_guid} - {getOwner().toBasicString()}"; result.setFail(ServerErrorCode.AnchorIsNotInMyhome, err_msg); Log.getLogger().error(err_msg); FinishCraftPacketHandler.send_S2C_ACK_FINISH_CRAFT(player, result); return result; } var ugc_npc_action = ugc_npc.getEntityAction(); NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null - {player.toBasicString()}"); ugc_npc_action.modifyStateInfo(EntityStateType.None, new EntityPos(), ""); dynamoDbDocBase = MakeDeleteNpcLocationDoc(anchor_guid, myhome_guid); (result, var bonus_items) = await inventory_action.tryTakalbleToBag((META_ID)crafting_meta_data.Beacon_BonusItemId, (ushort)(1 * craft_attribute.CraftCount)); if (result.isFail()) { FinishCraftPacketHandler.send_S2C_ACK_FINISH_CRAFT(player, result); return result; } Increase_changed_items.AddRange(bonus_items); } var task_log_data = CraftBusinessLogHelper.toCraftLogInfo(craft_attribute); invokers.Add(new CraftBusinessLog(task_log_data)); var batch = new QueryBatchEx(player, LogActionType.CraftFinish , server_logic.getDynamoDbClient()); { if (dynamoDbDocBase != null) batch.addQuery(new DBQEntityDelete(dynamoDbDocBase)); batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); } batch.appendBusinessLogs(invokers); result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { FinishCraftPacketHandler.send_S2C_ACK_FINISH_CRAFT(player, result); return result; } m_Crafts.TryRemove(anchor_guid, out craft); if (ugc_npc != null) { var ugc_npc_action = ugc_npc.getEntityAction(); var game_zone_action = player.getEntityAction(); result = await ugc_npc_action.tryRemoveInGameZone(); if (result.isFail()) { string room_id = string.Empty; LOCATION_UNIQUE_ID unique_id = string.Empty; int map_id = 0; var map = game_zone_action.getLinkedToMap(); if (map is not null) { room_id = map.m_room_id; unique_id = map.getLocationUniqueId(); map_id = map.MapMId; } err_msg = $"Failed to tryRemoveInGameZone Player room_id : {room_id}, Player Map Location id : {unique_id}, Player MapMid : {map_id}, BeaconGuid : {craft_attribute.BeaconGuid} - {getOwner().toBasicString()}"; Log.getLogger().error(err_msg); } } FinishCraftPacketHandler.send_S2C_ACK_FINISH_CRAFT(player, result, anchor_guid, craft_attribute.BeaconGuid, Increase_changed_items); game_zone_action.broadcast(player, CraftNotifyHelper.makeNotiCraftInfoPacket(m_Crafts.Select(x => x.Value.toCraftData4Client()).ToList(), player.getUserGuid())); return result; }; result = await player.runTransactionRunnerSafely(TransactionIdType.PrivateContents, "FinishCraft", fn_finish_craft_profile); if (result.isFail()) { err_msg = $"Failed to runTransaction() !!! : {result.toBasicString()} - {player.toBasicString()}"; Log.getLogger().error(err_msg); } if (crafting_meta_data.Crafting_ItemId > 0) { await QuestManager.It.QuestCheck(player, new QuestCrafting(EQuestEventTargetType.CRAFTING, EQuestEventNameType.COMPLETED, crafting_meta_data.Crafting_ItemId)); } return result; } public Result cheatAllCraftFinish() { var result = new Result(); var err_msg = string.Empty; var player = getOwner() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var craftList = m_Crafts.Select(x => x.Value).ToList(); foreach (var craft in craftList) { var craft_attribute = craft.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(craft_attribute, () => $"craft_attribute is null !!!"); craft_attribute.CraftFinishTime = DateTimeHelper.Current; craft_attribute.modifiedEntityAttribute(); } return result; } } }