using Amazon.DynamoDBv2.Model; using ServerCommon; using ServerCore; using ServerBase; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UGQDatabase.Models; using Newtonsoft.Json; using static System.Runtime.InteropServices.JavaScript.JSType; using ServerCommon.UGQ.Models; namespace GameServer { public class QuestUgqLiveMeta : QuestMetaBase { private Lazy> m_ugq_quest_data = new Lazy>(); private ConcurrentDictionary<(UInt32, UInt32), QuestMetaAllBaseInfo> UgqQuestData => m_ugq_quest_data.Value; public QuestUgqLiveMeta() : base(UgqStateType.Live, QuestContentState.Live) { } public override async Task<(Result, QuestMetaAllBaseInfo)> getQuestMetaInfo(Player? player, UInt32 questId, UInt32 questRevision) { ArgumentNullReferenceCheckHelper.throwIfNull(player, () => $"player is null !!!"); var result = new Result(); if (false == UgqQuestData.TryGetValue((questId, questRevision), out var ugq_quest_meta_collected_info)) { Log.getLogger().debug($"getQuestMetaInfo not exist memory questId : {questId}, questRevision : {questRevision}"); //서버에 캐싱이 없는 경우 ugq_quest_meta_collected_info = new(m_ugq_state, m_quest_content_state); //api서버에서 호출 (result, var game_quest_data) = await UgqMetaHelper.loadLiveGameQuestGameDataEntity(player, questId, questRevision); if (result.isFail() || game_quest_data is null) { Log.getLogger().error(result.toBasicString()); //호출 해서 데이터가 없는 경우 에러 처리(무조건 있어야 된다.) return (result, null!); } result = await gameQuestDataStateCheck(player, game_quest_data); //여기 result는 그냥 shutdown으로 보내는 거라서 무시 ugq_quest_meta_collected_info.m_quest_data_entity = game_quest_data; (result, var generated_quest_base_info) = UgqMetaHelper.generateUgqQuestBaseInfo(game_quest_data); if (result.isFail()) { return (result, null!); } ugq_quest_meta_collected_info.m_quest_base_info = generated_quest_base_info; UgqQuestData.TryAdd((questId, questRevision), ugq_quest_meta_collected_info); Log.getLogger().debug($"UgqQuestData.TryAdd questId : {questId}, questRevision : {questRevision}"); } else { //캐싱이 오래 됐을 수도 있으니 game -quest - data - simple 로 한번더 확인 필요. //Log.getLogger().debug($"getQuestMetaInfo exist memory questId : {questId}, questRevision : {questRevision}, player : {player.toBasicString()}"); var server_logic = GameServerApp.getServerLogic(); var ugq_api_manager = server_logic.GetUqgApiManager(); var lang_type = player.getLanguageType(); (result, var simple_game_quest_data) = await ugq_api_manager.getUgqQuestSimpleInfo(questId, questRevision, m_quest_content_state); if (result.isFail()) { Log.getLogger().error(result.toBasicString()); return (result, null!); } NullReferenceCheckHelper.throwIfNull(simple_game_quest_data, () => $"simple_game_quest_data is null !!!"); NullReferenceCheckHelper.throwIfNull(ugq_quest_meta_collected_info.m_quest_data_entity, () => $"ugq_quest_meta_collected_info.m_quest_data_entity is null !!!"); ugq_quest_meta_collected_info.m_quest_data_entity.Shutdown = simple_game_quest_data.Shutdown; ugq_quest_meta_collected_info.m_quest_data_entity.State = simple_game_quest_data.State; result = await gameQuestDataStateCheck(player, ugq_quest_meta_collected_info.m_quest_data_entity); if (result.isFail()) { Log.getLogger().error(result.toBasicString()); return (result, null!); } } UgqQuestData.TryGetValue((questId, questRevision), out ugq_quest_meta_collected_info); return (result, ugq_quest_meta_collected_info!); } private async Task gameQuestDataStateCheck(Player player, GameQuestDataEntity gameQuestData) { //api에서 로드해서 상태 값 확인 했는데 shutdown 인 경우 var result = new Result(); if (gameQuestData.Shutdown == true) { var server_logic = GameServerApp.getServerLogic(); var ugq_api_manager = server_logic.GetUqgApiManager(); var lang_type = player.getLanguageType(); //해당 퀘스트가 Shutdown 인경우 갱신 해줘야 된다. (result, var latest_queat_game_data) = await ugq_api_manager.getUgqLatestQuestData((UInt32)gameQuestData.QuestId, lang_type); if (result.isFail()) { var err_msg = $"Failed to getUgqLatestQuestData()!!! questId : {gameQuestData.QuestId} - {player.toBasicString()}"; Log.getLogger().error(err_msg); return result; } NullReferenceCheckHelper.throwIfNull(latest_queat_game_data, () => $"latest_queat_game_data is null !!! - {player.toBasicString()}"); //기존 로드된 데이터의 리비전과, 최신 리비전이 다르면 리비전이 변경이 발생한것 if (gameQuestData.Revision != latest_queat_game_data.Revision) { Log.getLogger().info($"Revision diff gameQuestData.Revision : {gameQuestData.Revision} <-> latest_queat_game_data.Revision : {latest_queat_game_data.Revision}"); gameQuestData.UgqGameQuestDataForClient.UgqStateType = UgqStateType.RevisionChanged; gameQuestData.UgqGameQuestDataForClient.UgqGradeType = gameQuestData.GradeType; //최신 버전이 아닌경우 result = updateUgqState(gameQuestData.UgqGameQuestDataForClient, UgqStateType.RevisionChanged); if (result.isFail()) { return result; } } } return result; } private Result updateUgqState(UgqGameQuestDataForClient ugqGameQuestDataForClient, UgqStateType state) { var result = new Result(); if (ugqGameQuestDataForClient is null) { var err_msg = $"GameQuestDataEntity NotExist ugqGameQuestDataForClientString"; result.setFail(ServerErrorCode.UgqQuestMetaNotExist, err_msg); Log.getLogger().error(err_msg); return result; } ugqGameQuestDataForClient.UgqStateType = state; Log.getLogger().info($"ugq_game_quest_data_for_client ugqState: {state}"); return result; } } }