using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using ServerCommon; using ServerCommon.BusinessLogDomain; using MetaAssets; using static ClientToGameMessage.Types; 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 ANCHOR_META_GUID = System.String; namespace GameServer; public class CharacterAction : EntityActionBase { public CharacterAction(Character owner) : base(owner) { } public override async Task onInit() { await Task.CompletedTask; var result = new Result(); return result; } public override void onClear() { return; } public void setStateInfo(EntityStateType stateType, ANCHOR_META_GUID anchorMetaGuid, META_ID metaId) { var owner = getOwner(); var character_attribute = owner.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); character_attribute.StateInfo.StateType = stateType; character_attribute.StateInfo.MetaIdOfStateType = (Int32)metaId; character_attribute.StateInfo.AnchorMetaGuid = anchorMetaGuid; } public async Task tryUpdateApperanceProfile(AvatarInfo? avatarInfo, ClothInfo? clothInfo) { var character = getOwner() as Character; NullReferenceCheckHelper.throwIfNull(character, () => $"character is null !!!"); var player = character.getRootParent() as Player; NullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var user_create_or_load_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(user_create_or_load_action, () => $"user_create_or_load_action is null !!!"); var result = new Result(); var err_msg = string.Empty; if (null == avatarInfo) { err_msg = $"AvatarInfo is null !!! - {character.toBasicString()}"; result.setFail(ServerErrorCode.FunctionParamNull, err_msg); Log.getLogger().error(err_msg); return result; } if(true == isCompletedApprearance()) { var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); var appearance_profile = character_attribute.AppearanceProfileValue; NullReferenceCheckHelper.throwIfNull(appearance_profile, () => $"appearance_profile is null !!!"); err_msg = $"Already Customizing Completed !!! : currCustomizing:{appearance_profile.CustomValues} - {character.toBasicString()}"; result.setFail(ServerErrorCode.CharacterCustomizingAlreadyCompleted, err_msg); Log.getLogger().error(err_msg); return result; } // 1. 캐릭터 외형 정보를 갱신 한다. updateAppearanceProfile(avatarInfo); var item_cloth_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(item_cloth_action, () => $"server_logic is null !!!"); // 2. 테스트 유저가 아닌 경우 캐릭터 의상 정보를 갱신 한다. if (user_create_or_load_action.isTestUser() == false) { result = await item_cloth_action.tryApplyClothsByMetaId(clothInfo); if (result.isFail()) { err_msg = $"Failed to tryApplyClothsByMetaId() !!! : {result.toBasicString()} - {character.toBasicString()}"; Log.getLogger().error(err_msg); return result; } } var server_logic = GameServerApp.getServerLogic(); NullReferenceCheckHelper.throwIfNull(server_logic, () => $"server_logic is null !!! - {player.toBasicString()}"); var batch = new QueryBatchEx( player, LogActionType.CharacterAppearanceUpdate , server_logic.getDynamoDbClient() , true); { batch.addQuery(new DBQWriteToAttributeAllWithTransactionRunner()); batch.addQuery(new QueryFinal(), async (_query) => { await Task.CompletedTask; var query_batch = _query.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()}"); var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!! - {player.toBasicString()}"); var character_log_info = new CharacterLogInfo(); (var result, var update_character_log_info) = await character_attribute.toCharacterLogInfo(); NullReferenceCheckHelper.throwIfNull(update_character_log_info, () => $"update_character_log_info is null !!!"); if (result.isFail()) { err_msg = $"Failed to toCharacterLogInfo() !!! : {result.toBasicString()} - {toBasicString()}, {player.toBasicString()}"; Log.getLogger().error(err_msg); } else { character_log_info.setInfo(update_character_log_info); // 비즈니스 로그 추가 query_batch.appendBusinessLog(new CharacterBusinessLog(log_action, character_log_info)); } return QueryBatchBase.QueryResultType.Success; }); } result = await QueryHelper.sendQueryAndBusinessLog(batch); if (result.isFail()) { return result; } return result; } private void updateAppearanceProfile(AvatarInfo avatarInfo) { var owner = getOwner(); NullReferenceCheckHelper.throwIfNull(owner, () => $"server_logic is null !!!"); if (null == avatarInfo) { var err_msg = $"AvatarInfo is null !!! - {owner.toBasicString()}"; Log.getLogger().info(err_msg); return; } var character = owner as Character; NullReferenceCheckHelper.throwIfNull(character, () => $"character is null !!!"); var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); var appearance_profile = character_attribute.AppearanceProfileValue; NullReferenceCheckHelper.throwIfNull(appearance_profile, () => $"appearance_profile is null !!!"); if (null == avatarInfo.AppearCustomize) { var err_msg = $"avatarInfo.AppearCustomize is null !!! - {owner.toBasicString()}"; Log.getLogger().info(err_msg); return; } var appearance_customize = avatarInfo.AppearCustomize; appearance_profile.BasicStyle = (UInt32)appearance_customize.BasicStyle; appearance_profile.BodyShape = (UInt32)appearance_customize.BodyShape; appearance_profile.HairStyle = (UInt32)appearance_customize.HairStyle; appearance_profile.CustomValues = appearance_customize.CustomValues.Select(x => x).ToList(); appearance_profile.IsCustomCompleted = true; character_attribute.modifiedEntityAttribute(); } public bool isCompletedApprearance() { var character = getOwner() as Character; NullReferenceCheckHelper.throwIfNull(character, () => $"character is null !!!"); var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); var appearance_profile = character_attribute.AppearanceProfileValue; NullReferenceCheckHelper.throwIfNull(appearance_profile, () => $"appearance_profile is null !!!"); return appearance_profile.IsCustomCompleted; } public void broadcastCharacterInfo() { var character = getOwner() as Character; NullReferenceCheckHelper.throwIfNull(character, () => $"appearanccharactere_profile is null !!!"); var player = character.getRootParent() 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 curr_join_map = game_zone_action.getLinkedToMap(); if (null == curr_join_map) { return; } ClientToGame to_client_msg = new(); to_client_msg.Message = new(); // GS2C_NTF_PLAYER_MODIFY, 본 코드가 C/S 연동 테스트 확인 되면 ClientToGameMessage.Types.ActorModify 패킷 및 코드는 제거 해야 한다. - kangms to_client_msg.Message.NtfPlayerModify = new GS2C_NTF_PLAYER_MODIFY(); var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); var inventory_action = player.getEntityAction(); NullReferenceCheckHelper.throwIfNull(inventory_action, () => $"inventory_action is null !!!"); to_client_msg.Message.NtfPlayerModify.ToModifyPlayerGuid = player.getUserGuid(); // 클라이언트는 USER_GUID를 사용 한다. to_client_msg.Message.NtfPlayerModify.AvatarInfo = character_attribute.AppearanceProfileValue.toCharacterAppearanceProfile4Client(); var cloth_info = inventory_action.toClothInven4Client(); NullReferenceCheckHelper.throwIfNull(cloth_info, () => $"cloth_info is null !!!"); to_client_msg.Message.NtfPlayerModify.ClothInfo = cloth_info.toClothInfoOfAnotherUser(); to_client_msg.Message.NtfPlayerModify.EntityStateInfo = character_attribute.StateInfo; curr_join_map.Broadcast(player, to_client_msg); } public void CheatResetCompletedApprearance() { var character = getOwner() as Character; NullReferenceCheckHelper.throwIfNull(character, () => $"character is null !!!"); var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); var appearance_profile = character_attribute.AppearanceProfileValue; NullReferenceCheckHelper.throwIfNull(appearance_profile, () => $"appearance_profile is null !!!"); appearance_profile.IsCustomCompleted = false; character_attribute.modifiedEntityAttribute(); } public bool isFarming() { var character = getOwner() as Character; NullReferenceCheckHelper.throwIfNull(character, () => $"character is null !!!"); var character_attribute = character.getEntityAttribute(); NullReferenceCheckHelper.throwIfNull(character_attribute, () => $"character_attribute is null !!!"); var err_msg = string.Empty; if(EntityStateType.UsingByFarming == character_attribute.StateInfo.StateType) { err_msg = $"Character state is Farming !!! : currState:{character_attribute.StateInfo.StateType} - {character.toBasicString()}"; Log.getLogger().error(err_msg); return true; } return false; } }