using System.Collections.Generic; using System.Diagnostics; using System.Text.RegularExpressions; using System.Text; using Newtonsoft.Json; using Amazon.Runtime.Internal.Transform; using Google.Protobuf.WellKnownTypes; using ServerCore; using ServerBase; using MetaAssets; namespace ServerCommon; public static class InstanceDataExtentions { public static EPlaceType placeType(this MetaAssets.InstanceMetaData instanceData) { return instanceData.ContentsType.toPlaceType(); } } public static class ItemLevelEnchantDataExtentions { public static MetaAssets.ConsumeItem? GetConsumeItem(this MetaAssets.ItemLevelEnchantMetaData itemLevelEnchantData, string rarity) { return rarity switch { "Common" => itemLevelEnchantData.Common, "Rare" => itemLevelEnchantData.Rare, "Epic" => itemLevelEnchantData.Epic, "Legend" => itemLevelEnchantData.Legend, _ => null }; } } public class AttributeRandomGroupInfo { public int TotalWeight = 0; public List attributeRandomGroupDatas = new(); } public class ShopProductRandomGroupInfo { public int TotalWeight = 0; public List RandomGroupList = new(); } public class PropGroupData { public int group_id; public string group_folder_name = string.Empty; public int group_respawn_time; public int max_spawn_quantity; public List prop_order_data = new(); public int max_prop_spawn_weight; } public class PropGroupOrderData { public int prop_order; public int prop_id; public int prop_spawn_weight; public string prop_display_name = string.Empty; } public class SelectedGacha { public List GachaList = new(); int TotalWeight = 0; private Random rng = new Random(); public SelectedGacha(List gachaList) { GachaList = gachaList; TotalWeight = GachaList.Sum(v => v.Weight); } public MetaAssets.GachaMetaData getRandomReward() { int accumulatedWeight = 0; int randomValue = rng.Next(TotalWeight); foreach (var data in GachaList) { accumulatedWeight += data.Weight; if (randomValue < accumulatedWeight) { return data; } } return GachaList[0]; } public List getRewardsByOrderNo(Int32 orderNo) { var selected_gachas = new List(); var gacha_count = GachaList.Count; if( orderNo < 1 || gacha_count < orderNo ) { Log.getLogger().error($"Invalid Order Number !!! : 0 < orderNo:{orderNo} <= gachaCount:{gacha_count}"); return selected_gachas; } for (int i = 1; i <= orderNo; i++) { var index = i - 1; selected_gachas.Add(GachaList[index]); } return selected_gachas; } } public class MetaData { public static MetaData Instance { get; } = new MetaData(); readonly string _inputPath = $"resource/meta"; public MetaAssets.MetaTable Meta { get; } = new MetaAssets.MetaTable(); // LandDecoData, BuildingLfData, BasicCostumeSetData, SocialActionPresetData, MannequinData, ItemSetData 삭제 public IReadOnlyDictionary m_test_user_create_meta_datas => Meta.TestUserCreateMetaTable.TestUserCreateMetaDataListbyId; public IReadOnlyDictionary m_test_user_initial_meta_datas => Meta.TestUserInitialMetaTable.TestUserInitialMetaDataListbyId; public IReadOnlyDictionary m_user_create_meta_datas => Meta.UserCreateMetaTable.UserCreateMetaDataListbyMetaId; public IReadOnlyDictionary _IndunTable => Meta.InstanceMetaTable.InstanceMetaDataListbyId; public IReadOnlyDictionary _textTable => Meta.TextStringMetaTable.TextStringMetaDataListbyKey; public IReadOnlyDictionary _npcTable => Meta.NpcMetaTable.NpcMetaDataListbyId; public IReadOnlyDictionary _ConcertTable => Meta.InstanceConcertMetaTable.InstanceConcertMetaDataListbyId; public IReadOnlyDictionary _ItemTable => Meta.ItemMetaTable.ItemMetaDataListbyId; public IReadOnlyDictionary _LandTable => Meta.LandMetaTable.LandMetaDataListbyLandId; public IReadOnlyDictionary _BuildingTable => Meta.BuildingMetaTable.BuildingMetaDataListbyBuildingId; public IReadOnlyDictionary _SocialActionTable => Meta.SocialActionMetaTable.SocialActionMetaDataListbySocial_action_id; public IReadOnlyDictionary _BuffTable => Meta.BuffMetaTable.BuffMetaDataListbyBuffId; public IReadOnlyDictionary _WarpTable => Meta.WarpMetaTable.WarpMetaDataListbyWarpId; public IReadOnlyDictionary _WorldMetaTable => Meta.WorldMetaTable.WorldMetaDataListbyId; public IReadOnlyDictionary _TaxiMetaTable => Meta.TaxiMetaTable.TaxiMetaDataListbyTaxi_id; public IReadOnlyDictionary _ToolMetaTable => Meta.ToolMetaTable.ToolMetaDataListbyToolId; public IReadOnlyDictionary _AttributeDefinitionMetaTable => Meta.AttributeDefinitionMetaTable.AttributeDefinitionMetaDataListbyKey; public Dictionary _AttributeRandomGroupMetaTable = new(); public IReadOnlyDictionary _ItemLevelEnchantMetaTable => Meta.ItemLevelEnchantMetaTable.ItemLevelEnchantMetaDataListbyLevel; public Dictionary _GameConfigMetaTable = new(); public Dictionary _CurrencyMetaTableByCurrencyType = new(); public IReadOnlyDictionary _ProductMetaDataById => Meta.ProductMetaTable.ProductMetaDataListbyId; public List _BanWordMetaTable = new(); public List _BanWordNicknameMetaTable = new(); public IReadOnlyDictionary _ShopMetaTable => Meta.ShopMetaTable.ShopMetaDataListbyId; public Dictionary _ShopProductMetaTable = new(); public Dictionary> _ShopNecessaryProductByGroupIdTable = new(); public Dictionary _ShopRandomProductByGroupIdTable = new(); public IReadOnlyDictionary _BasicStyleMetaTable => Meta.BasicStyleMetaTable.BasicStyleMetaDataListbyId; public IReadOnlyDictionary _RewardPropMetaTable => Meta.RewardPropMetaTable.RewardPropMetaDataListbyId; public Dictionary _PropGroupMetaTable = new(); public IReadOnlyList _ClaimTable => Meta.ClaimMetaTable.ClaimMetaDataList; public Dictionary<(int, MetaAssets.ClaimType), ClaimMetaData> _ClaimMetaTable = new(); public Dictionary> _RewardMetaTable = new(); public Dictionary _GachaMetaTable = new(); private IReadOnlyDictionary _QuestAssignMetaTable => Meta.QuestAssignMetaTable.QuestAssignMetaDataListbyQuestId; public List m_quest_assign_meta_infos = new(); public List m_quest_task_meta_infos = new(); public Dictionary> _QuestScriptMetaTable = new(); public Dictionary _QuestBaseinfoTable = new(); public IReadOnlyDictionary _CraftingMetaTable => Meta.CraftingMetaTable.CraftingMetaDataListbyId; public IReadOnlyDictionary _RequirementMetaTable => Meta.RequirementMetaTable.RequirementMetaDataListbyId; public IReadOnlyList UGQInputTaskMetaDataList => Meta.UGQInputMetaTable.UGQInputTaskMetaDataList; public IReadOnlyDictionary UGQInputTaskMetaDataById => Meta.UGQInputMetaTable.UGQInputTaskMetaDataListbyId; public IReadOnlyList UGQInputDialogMetaDataList => Meta.UGQInputMetaTable.UGQInputDialogMetaDataList; public IReadOnlyDictionary UGQInputDialogMetaDataListbyId => Meta.UGQInputMetaTable.UGQInputDialogMetaDataListbyId; public IReadOnlyDictionary UGQInputDialogMetaDataById => Meta.UGQInputMetaTable.UGQInputDialogMetaDataListbyId; public IReadOnlyDictionary UGQInputDialogConditionMetaDataListbyName => Meta.UGQInputMetaTable.UGQInputDialogConditionMetaDataListbyName; public IReadOnlyDictionary UGQPresetImageMetaDataListbyId => Meta.UGQInputMetaTable.UGQPresetImageMetaDataListbyId; public IReadOnlyDictionary UGQMapImageMetaDataListbyId => Meta.UGQInputMetaTable.UGQMapImageDataListbyId; public IReadOnlyDictionary UGQBeaconActionDataListbyId => Meta.UGQBeaconActionTable.UGQBeaconActionDataListbyId; public IReadOnlyDictionary SeasonPassMetaData => Meta.SeasonPassMetaTable.SeasonPassMetaDataListbyId; public Dictionary> SeasonPassRewardTablebySeasonPassId = new(); public IReadOnlyDictionary _InteriorMetaTable => Meta.InteriorMetaTable.InteriorMetaDataListbyId; public IReadOnlyDictionary _EditableFrameworkMetaTable => Meta.EditableFrameworkMetaTable.EditableFrameworkMetaDataListbyId; public IReadOnlyDictionary _EditableRoomMetaTable => Meta.EditableRoomMetaTable.EditableRoomMetaDataListbyId; public IReadOnlyDictionary _CaliumConverterMaterialTable => Meta.CaliumConverterMaterialTable.CaliumConverterMaterialDataListbyId; public IReadOnlyDictionary SystemMailMetaData => Meta.SystemMailMetaTable.SystemMailMetaDataListbyKey; public IReadOnlyDictionary NpcGeneralMetaData => Meta.NPCGeneralMetaTable.NPCGeneralMetaDataListbyId; public IReadOnlyDictionary _FarmingPropMetaTable => Meta.FarmingPropMetaTable.FarmingPropMetaDataListbyId; public IReadOnlyDictionary ZoneMetaDataListbyId => Meta.ZoneMetaTable.ZoneMetaDataListbyId; public Dictionary<(EditorType, SizeType), MetaAssets.RentalfeeData> _RentalfeeTable = new(); public IReadOnlyDictionary _BattleObjectMetaTable => Meta.BattleObjectMetaTable.BattleObjectMetaDataListbyId; public IReadOnlyDictionary _BattleObjectSpawnGroupMetaTable => Meta.BattleObjectSpawnGroupMetaTable.BattleObjectSpawnGroupMetaDataListbyId; public IReadOnlyDictionary _BattleFFAConfigMetaTable => Meta.BattleFFAConfigMetaTable.BattleFFAConfigMetaDataListbyId; public IReadOnlyDictionary> _BattleFFARewardMetaTable = new Dictionary>(); public BattleObjectMetaData _BattlePodStorageMeta = new(new()); public BattleObjectMetaData _BattlePickupPodMeta = new(new()); public IReadOnlyDictionary m_user_log_meta_datas => Meta.UserLogMetaTable.UserLogMetaDataListbyMetaId; MetaData() { } public bool LoadTableAll(string? dataPath = null) { if (dataPath == null) { string inputPath2 = Path.GetFullPath(_inputPath, Environment.CurrentDirectory); if (!Directory.Exists(inputPath2)) { throw new Exception($"Not found Path:{inputPath2}"); } Meta.load(inputPath2); } else { Meta.load(dataPath); } foreach (var one in Meta.AttributeRandomGroupMetaTable.AttributeRandomGroupMetaDataList) { if (_AttributeRandomGroupMetaTable.TryGetValue(one.GroupID, out var value) == false) { if (false == _AttributeRandomGroupMetaTable.TryAdd(one.GroupID, new() { attributeRandomGroupDatas = [one], TotalWeight = one.Weight })) { throw new Exception($"Key={one.Key} is duplicated"); } continue; } value.TotalWeight += one.Weight; value.attributeRandomGroupDatas.Add(one); } foreach(var one in Meta.ItemLevelEnchantMetaTable.ItemLevelEnchantMetaDataList) { if(one.Common.AttributeValues.Count != Constant.COMMON_ITEM_ATTRIBUTE_COUNT) { throw new Exception($"Invalid Table Data"); } if (one.Rare.AttributeValues.Count != Constant.RARE_ITEM_ATTRIBUTE_COUNT) { throw new Exception($"Invalid Table Data"); } if (one.Epic.AttributeValues.Count != Constant.EPIC_ITEM_ATTRIBUTE_COUNT) { throw new Exception($"Invalid Table Data"); } if (one.Legend.AttributeValues.Count != Constant.LEGEND_ITEM_ATTRIBUTE_COUNT) { throw new Exception($"Invalid Table Data"); } } foreach (var one in Meta.GameConfigMetaTable.GameConfigMetaDataList) { _GameConfigMetaTable.TryAdd(one.Key, one.Value); } foreach(var one in Meta.CurrencyMetaTable.CurrencyMetaDataList) { _CurrencyMetaTableByCurrencyType.TryAdd(one.CurrencyType, one); } foreach(var one in Meta.BanWordMetaTable.BanWordMetaDataList) { _BanWordMetaTable.Add(one.BanWord); } foreach (var one in Meta.BanWordNicknameMetaTable.BanWordNicknameMetaDataList) { _BanWordNicknameMetaTable.Add(one.BanWordNickname); } foreach (var one in Meta.ShopProductMetaTable.ShopProductMetaDataList) { if (false == _ShopProductMetaTable.TryAdd(one.ID, one)) { throw new Exception($"ShopProductData Id = {one.ID} is duplicated."); } if (one.Is_Random == false) { if (_ShopNecessaryProductByGroupIdTable.TryGetValue(one.Group_Id, out var productDataList) == false) { productDataList = new List(); _ShopNecessaryProductByGroupIdTable.Add(one.Group_Id, productDataList); } productDataList.Add(one); } else { if (_ShopRandomProductByGroupIdTable.TryGetValue(one.Group_Id, out var productDataList) == false) { productDataList = new ShopProductRandomGroupInfo(); productDataList.TotalWeight += one.Weight; _ShopRandomProductByGroupIdTable.Add(one.Group_Id, productDataList); } productDataList.TotalWeight += one.Weight; productDataList.RandomGroupList.Add(one); } } foreach (var item in Meta.SpawnPropGroupMetaTable.SpawnPropGroupMetaDataList) { if (!_PropGroupMetaTable.TryGetValue(item.group_id, out var group_data)) { group_data = new(); group_data.group_id = item.group_id; group_data.group_folder_name = item.group_folder_name; group_data.group_respawn_time = item.group_respawn_time; group_data.max_spawn_quantity = item.max_spawn_quantity; if (!_PropGroupMetaTable.TryAdd(item.group_id, group_data)) { throw new Exception($"PropGroupData Add Fail Id = {item.group_id}"); } } PropGroupOrderData group_order_data = new(); group_order_data.prop_order = item.prop_order; group_order_data.prop_id = item.prop_id; group_order_data.prop_spawn_weight = item.prop_spawn_weight; group_order_data.prop_display_name = item.prop_display_name; group_data.max_prop_spawn_weight += item.prop_spawn_weight; group_data.prop_order_data.Add(group_order_data); } LoadClaimRewardInfo(Meta.ClaimRewardMetaTable.ClaimRewardMetaDataList); { List distinctRewardIds = Meta.RewardMetaTable.RewardMetaDataList.Select(x => x.m_group_id).Distinct().ToList(); foreach (int groupId in distinctRewardIds) { var rewardList = Meta.RewardMetaTable.RewardMetaDataList.Where(x => x.m_group_id == groupId).ToList(); if (rewardList is null) { throw new Exception($"RewardData rewardList is null groupId={groupId}."); } if (!_RewardMetaTable.TryAdd(groupId, rewardList)) { throw new Exception($"_RewardMetaData Add Error groupId={groupId}."); } _RewardMetaTable[groupId] = rewardList; } } { foreach (var one in Meta.SeasonPassRewardMetaTable.SeasonPassRewardMetaDataList) { if(SeasonPassRewardTablebySeasonPassId.TryGetValue(one.SeasonPassId, out var seasonPassRewardList) == false) { seasonPassRewardList = new Dictionary(); SeasonPassRewardTablebySeasonPassId.Add(one.SeasonPassId, seasonPassRewardList); } seasonPassRewardList.Add(one.Grade, one); } } { List distinctRewardIds = Meta.GachaMetaTable.GachaMetaDataList.Select(x => x.GroupId).Distinct().ToList(); foreach (int groupId in distinctRewardIds) { var rewardList = Meta.GachaMetaTable.GachaMetaDataList.Where(x => x.GroupId == groupId).ToList(); if (rewardList is null) { throw new Exception($"RewardData rewardList is null groupId={groupId}."); } SelectedGacha gacha = new(rewardList); _GachaMetaTable[groupId] = gacha; } } { foreach (var rentalfee_data in Meta.RentalfeeDataTable.RentalfeeDataList) { if (!_RentalfeeTable.TryAdd((rentalfee_data.EditorInfo, rentalfee_data.SizeCategory), rentalfee_data)) { throw new Exception($"EditorInfo:{rentalfee_data.EditorInfo}, SizeCategory:{rentalfee_data.SizeCategory} is duplicated"); } } } { _BattleFFARewardMetaTable = Meta.BattleFFARewardMetaTable.BattleFFARewardMetaDataList .GroupBy(data => data.GroupID) .ToDictionary( group => group.Key, group => (IReadOnlyDictionary)group .OrderBy(data => data.ChargeLevel) .ToDictionary(data => data.ChargeLevel, data => data) ) as IReadOnlyDictionary>; var pod_storage_meta = Meta.BattleObjectMetaTable.BattleObjectMetaDataList.FirstOrDefault(metaData => metaData.Name == "Pod_CombatStand"); if (pod_storage_meta is null) throw new Exception($"pod_storage_meta is null!!!!!!"); _BattlePodStorageMeta = pod_storage_meta; var pickup_pod_meta = Meta.BattleObjectMetaTable.BattleObjectMetaDataList.FirstOrDefault(metaData => metaData.ObjectType == EBattleObjectType.Pod_Box); if (pickup_pod_meta is null) throw new Exception($"pod_storage_meta is null!!!!!!"); _BattlePickupPodMeta = pickup_pod_meta; } LoadQuest(); ValidatorErrorCollection errors = new(); MetaTableValidator validator = new MetaTableValidator(); validator.validate(errors); errors.log(); if (errors.HasError == true) { // 로그가 다 안 찍혀서 딜레이 시킴 Task.Delay(1000).Wait(); throw new Exception("validation error"); } return true; } private void LoadClaimRewardInfo(IReadOnlyList rewardDatas) { _ClaimMetaTable = new(); DateTime now = DateTimeHelper.Current; foreach (MetaAssets.ClaimMetaData claim in _ClaimTable) { if (claim.EndTime < now) { continue; } foreach (MetaAssets.ClaimRewardMetaData reward in rewardDatas) { if (claim.ClaimId != reward.ClaimId) continue; EEventType eventType = EEventType.ClaimReward; if (reward.ClaimType.Equals(MetaAssets.ClaimType.Membership)) { eventType = EEventType.ClaimReward; } if (!_ClaimMetaTable.TryGetValue((reward.ClaimId, reward.ClaimType), out var group)) { group = new ClaimMetaData(eventType, reward.ClaimId, reward.ClaimType); group.StartTime = claim.StartTime.UtcDateTime; group.EndTime = claim.EndTime.UtcDateTime; group.DetailInfo = new(); _ClaimMetaTable[(reward.ClaimId, reward.ClaimType)] = group; } ClaimRewardDetail detail = new(); detail.Idx = reward.Idx; detail.RewardGroupId = reward.RewardGroupID; detail.CoolTime = reward.CoolTime; detail.isSpecialReward = reward.IsSpecialReward; group.DetailInfo.Add(reward.Idx, detail); _ClaimMetaTable[(reward.ClaimId, reward.ClaimType)] = group; } } } void LoadQuest() { foreach (var one in Meta.QuestAssignMetaTable.QuestAssignMetaDataList) { m_quest_assign_meta_infos.Add(convertDataToQuestAssignMetaInfo(one)); } foreach (var one in Meta.QuestMetaTable.QuestMetaDataList) { m_quest_task_meta_infos.Add(convertDataToQuestTaskMetaInfo(one)); } foreach (var one in Meta.QuestScriptMetaTable.QuestScriptMetaDataList) { if (!_QuestScriptMetaTable.TryGetValue(one.QuestId, out var group)) { group = new Dictionary(); _QuestScriptMetaTable[one.QuestId] = group; } if (!group.TryAdd(one.Index, one)) { Log.getLogger().error($"QuestScriptDataQuestData key={one.Index} QuestId={one.QuestId} is duplicated."); continue; } } _QuestBaseinfoTable = LoadQuestBaseInfo(); } private Dictionary LoadQuestBaseInfo() { Dictionary dicBaseinfo = new(); //AssignableQuestsAfterEnd 를 제외한 값 설정 foreach (MetaAssets.QuestAssignMetaData questData in _QuestAssignMetaTable.Values) { if (!dicBaseinfo.TryGetValue(questData.QuestId, out var questBaseInfo)) { questBaseInfo = new QuestBaseInfo(); dicBaseinfo.TryAdd(questData.QuestId, questBaseInfo); } if (!_QuestScriptMetaTable.TryGetValue(questData.QuestId, out var scriptList)) { Log.getLogger().error($"_QuestScriptMetaData Error QuestId : {questData.QuestId}"); continue; } //SortedSet setTaskNum = new(); SortedSet setTaskIdx = new(); makeQuestBaseInfo(scriptList.Values.ToList(), ref questBaseInfo, ref setTaskIdx, questData.QuestId, questData.QuestType.ToString(), questData.Reveal, questData.AssignType.ToString(), questData.RequirementType.ToString(), questData.RequirementValue, questData.OncePeriodRange, questData.NormalPoolActive, questData.ForceAccept, questData.RewardGroupId, questData.Dialogue, questData.DialogueResult, UgqStateType.None ); //var taskCount = setTaskNum.Count; //int[] arrTaskNum = setTaskNum.ToArray(); int[] arrTaskIdx = setTaskIdx.ToArray(); //카운터 있는지만 한번터 체크 //for (int i = 0; i < taskCount; i++) //{ // if (!questBaseInfo.QuestTaskGroupList.TryGetValue(arrTaskNum[i], out var QuestTaskGroupData3)) // { // Log.getLogger().error($"QuestTaskGroupData not exist arrTaskNum[i] : {arrTaskNum[i]}, i : {i}"); // break; // } // //태스크 단위로 카운터 있는지만 따로 체크 // for (int j = arrTaskIdx[i]; j < arrTaskIdx[i + 1]; j++) // { // if (!scriptList.TryGetValue(j, out var scriptAboutFunction)) // { // Log.getLogger().error($"functionCheckIdx {j} not exist"); // break; // } // if (scriptAboutFunction.FunctionTarget.Equals(nameof(EQuestFunctionTargetType.COUNTER)) && scriptAboutFunction.Function.Equals(nameof(EQuestFunctionNameType.SET))) // { // if (!int.TryParse(scriptAboutFunction.FunctionCondition1, out var minCount)) // { // Log.getLogger().error($"FunctionCondition1 convert Error : {scriptAboutFunction.FunctionCondition1}"); // break; // } // if (!int.TryParse(scriptAboutFunction.FunctionCondition2, out var maxCount)) // { // Log.getLogger().error($"counter set FunctionCondition2 convert Error : {scriptAboutFunction.FunctionCondition2}"); // break; // } // string eventString = makeEventScriptString(scriptList[j]); // QuestTaskGroupData3.EventStringList.Add(eventString); // QuestTaskGroupData3.HasCounter = true; // QuestTaskGroupData3.MinCounter = minCount; // QuestTaskGroupData3.MaxCounter = maxCount; // } // if (scriptAboutFunction.FunctionTarget.Equals(nameof(EQuestFunctionTargetType.TIMER)) && scriptAboutFunction.Function.Equals(nameof(EQuestFunctionNameType.START))) // { // if (!int.TryParse(scriptAboutFunction.FunctionCondition1, out var remainTime)) // { // Log.getLogger().error($"timer set FunctionCondition1 convert Error : {scriptAboutFunction.FunctionCondition1}"); // break; // } // QuestTaskGroupData3.HasTimer = true; // QuestTaskGroupData3.RemainTime = remainTime; // } // if (scriptAboutFunction.FunctionTarget.Equals(nameof(EQuestFunctionTargetType.QUEST)) && scriptAboutFunction.Function.Equals(nameof(EQuestFunctionNameType.ASSIGN))) // { // if (!int.TryParse(scriptAboutFunction.FunctionCondition1, out var quesId)) // { // Log.getLogger().error($"quest assign FunctionCondition1 convert Error : {scriptAboutFunction.FunctionCondition1}"); // break; // } // QuestTaskGroupData3.HasAssignableQuest = true; // QuestTaskGroupData3.AssignableQuestIds.Add((UInt32)quesId); // } // } //} } //다음 활성 퀘스트 정보 셋팅 foreach (MetaAssets.QuestAssignMetaData questData in _QuestAssignMetaTable.Values) { //이전 퀘스트를 완료하고 나면 메일을 보내줘야 되는 데이터를 기록 if (questData.RequirementType.Equals(MetaAssets.EAssignRequireType.Quest_Complete)) { var questId = (UInt32)questData.RequirementValue; if (!dicBaseinfo.TryGetValue(questId, out var questInfo)) { if (questId == 20000) continue; //20000번인 경우는 기획자와 이야기해서 지정한 번호로 로그 안남기고 continue Log.getLogger().error($"Quest Base Info Table not exist info : {questId}"); continue; } //노멀 퀘는 여기서 안주고 시간으로 준다. if (questData.QuestType.Equals(MetaAssets.EQuestType.NORMAL.ToString())) continue; questInfo.AssignableQuestsAfterEnd.Add(questData.QuestId); } } string strData = JsonConvert.SerializeObject(dicBaseinfo); //Log.getLogger().info(strData); return dicBaseinfo; } public void makeQuestBaseInfo(List scripts, ref QuestBaseInfo questBaseInfo, ref SortedSet setTaskIdx, UInt32 questId, string questType, bool reveal, string assignType, string requirementType, UInt32 requirementValue, OncePeriodRangeType type, bool normalPoolActive, bool forceAccept, Int32 rewardGroupId, string dialogue, string dialogueResult, UgqStateType state, UInt32 questRevision = 0 ) { questBaseInfo.QuestId = questId; questBaseInfo.QuestRevision = questRevision; questBaseInfo.QuestType = questType; questBaseInfo.Reveal = reveal; questBaseInfo.AssignType = assignType; questBaseInfo.RequirementType = requirementType; questBaseInfo.RequirementValue = requirementValue; questBaseInfo.OncePeriodRangeType = type; questBaseInfo.NormalPoolActive = normalPoolActive; questBaseInfo.ForceAccept = forceAccept; questBaseInfo.RewardGroupId = rewardGroupId; questBaseInfo.Dialogue = dialogue; questBaseInfo.DialogueResult = dialogueResult; questBaseInfo.UgqState = state; questBaseInfo.QuestTaskGroupList = new(); //태스크가 몇개이고 시작 태스크의 인덱스가 몇번인지 체크 Dictionary task_search_infos = new(); //스크립트 돌면서 task_number 체크, 태스크별 시작인덱스, 종료 인덱스 체크 makeTaskSearchInfos(scripts, ref task_search_infos, ref questBaseInfo); //태스크 별로 event 저장 처리 foreach (var task_search_info in task_search_infos) { makeEventAndFunctionInfos(scripts, task_search_info, ref questBaseInfo); checkParallelAndCounterAndAssign(scripts, task_search_info, ref questBaseInfo); //checkPropState(scripts, task_search_info, ref questBaseInfo); } } // private void checkPropState(List scripts, KeyValuePair taskSearchInfos, ref QuestBaseInfo questBaseInfo) // { // var task_number = taskSearchInfos.Key; // var script_start_idx = taskSearchInfos.Value.Item1; // var script_end_idx = taskSearchInfos.Value.Item2; // questBaseInfo.QuestTaskGroupList.TryGetValue(task_number, out var quest_task_group); // NullReferenceCheckHelper.throwIfNull(quest_task_group, () => $"Quest Task Group is null !!! - task_number:{task_number}"); // // //Parallel, Counter 체크 // for (Int32 i = script_start_idx; i <= script_end_idx; i++) // { // if (scripts[i].FunctionTarget.Equals(EQuestFunctionTargetType.PROP.ToString()) && scripts[i].Function.Equals(EQuestFunctionNameType.SWITCH.ToString())) // { // if (!int.TryParse(scripts[i].FunctionCondition1, out var propId)) // { // Log.getLogger().error($"FunctionCondition1 convert Error questId : {questBaseInfo.QuestId}, {JsonConvert.SerializeObject(scripts[i])}"); // } // if (!int.TryParse(scripts[i].FunctionCondition2, out var propState)) // { // Log.getLogger().error($"FunctionCondition2 convert Error questId : {questBaseInfo.QuestId}, {JsonConvert.SerializeObject(scripts[i])}"); // } // break; // } // } // // // } private void checkParallelAndCounterAndAssign(List scripts, KeyValuePair taskSearchInfos, ref QuestBaseInfo questBaseInfo) { var task_number = taskSearchInfos.Key; var script_start_idx = taskSearchInfos.Value.Item1; var script_end_idx = taskSearchInfos.Value.Item2; questBaseInfo.QuestTaskGroupList.TryGetValue(task_number, out var quest_task_group); NullReferenceCheckHelper.throwIfNull(quest_task_group, () => $"Quest Task Group is null !!! - task_number:{task_number}"); bool task_active_assign_quest_check = false; //Parallel, Counter 체크 for (Int32 i = script_start_idx; i <= script_end_idx; i++) { //Task actived 일때 task_active_assign_quest_check true로 처리 if (scripts[i].EventTarget.Equals(EQuestEventTargetType.TASK.ToString()) && scripts[i].Event.Equals(EQuestEventNameType.ACTIVED.ToString())) { task_active_assign_quest_check = true; } if (task_active_assign_quest_check) { //true 상태에서 //event가 빈값이 아니고 Task actived 가 아니면 체크 완료 if (false == scripts[i].EventTarget.Equals(string.Empty) && false == scripts[i].Event.Equals(string.Empty)) { if (false == scripts[i].EventTarget.Equals(EQuestEventTargetType.TASK.ToString()) || false == scripts[i].Event.Equals(EQuestEventNameType.ACTIVED.ToString())) { task_active_assign_quest_check = false; } } } //병렬처리일 경우 먼저 병렬 처리 if (scripts[i].FunctionTarget.Equals(EQuestFunctionTargetType.PARALLEL.ToString())) { quest_task_group.IsParallel = true; } //Counter 있는 경우 먼저 처리 if (scripts[i].FunctionTarget.Equals(EQuestFunctionTargetType.COUNTER.ToString()) && scripts[i].Function.Equals(EQuestFunctionNameType.SET.ToString())) { quest_task_group.HasCounter = true; if (!int.TryParse(scripts[i].FunctionCondition1, out var minCount)) { Log.getLogger().error($"FunctionCondition1 convert Error questId : {questBaseInfo.QuestId}, {JsonConvert.SerializeObject(scripts[i])}"); minCount = 0; } quest_task_group.MinCounter = minCount; if (!int.TryParse(scripts[i].FunctionCondition2, out var maxCount)) { Log.getLogger().error($"FunctionCondition2 convert Error questId : {questBaseInfo.QuestId}, {JsonConvert.SerializeObject(scripts[i])}"); maxCount = 0; } quest_task_group.MaxCounter = maxCount; } if (scripts[i].FunctionTarget.Equals(EQuestFunctionTargetType.QUEST.ToString()) && scripts[i].Function.Equals(EQuestFunctionNameType.ASSIGN.ToString())) { if (task_active_assign_quest_check) { quest_task_group.HasAssignableQuest = true; if (!int.TryParse(scripts[i].FunctionCondition1, out var questId)) { Log.getLogger().error($"FunctionCondition1 convert Error questId : {questBaseInfo.QuestId}, {JsonConvert.SerializeObject(scripts[i])}"); } quest_task_group.AssignableQuestIds.Add((UInt32)questId); } } } } private void makeEventAndFunctionInfos(List scripts, KeyValuePair taskSearchInfos, ref QuestBaseInfo questBaseInfo) { var task_number = taskSearchInfos.Key; var script_start_idx = taskSearchInfos.Value.Item1; var script_end_idx = taskSearchInfos.Value.Item2; questBaseInfo.QuestTaskGroupList.TryGetValue(task_number, out var quest_task_group); NullReferenceCheckHelper.throwIfNull(quest_task_group, () => $"Quest Task Group is null !!! - task_number:{task_number}"); if (questBaseInfo.QuestId == 20001) { Log.getLogger().error(""); } for (Int32 i = script_start_idx; i <= script_end_idx; i++) { //EventTarget 이 없으면 continue; if (scripts[i].EventTarget.Equals(string.Empty)) continue; if (scripts[i].EventTarget.Equals(EQuestEventTargetType.TASK.ToString())) continue; // Task 도 별도로 가지고 있는다. 대신 Parallel과 Counter는 나중에 체크 해준다. string eventString = makeEventScriptString(scripts[i]); quest_task_group.EventStringList.Add(eventString); if (!quest_task_group.QuestEventGroupByEventString.TryGetValue(eventString, out var questEventInfo)) { questEventInfo = new QuestEventInfo(); //quest_task_group.QuestEventGroup.TryAdd(i, questEventInfo); quest_task_group.QuestEventGroupByEventString.TryAdd(eventString, questEventInfo); questEventInfo.QuestEventFunctionList = new(); } questEventInfo.EventIdx = i; questEventInfo.EventTarget = scripts[i].EventTarget; questEventInfo.EventName = scripts[i].Event; questEventInfo.EventCondition1 = scripts[i].EventCondition1; questEventInfo.EventCondition2 = scripts[i].EventCondition2; //excel to json 처리시 json에서 빈 문자열로 처리 안하고 0으로 처리하는 케이스가 있어서 보정 처리 if (scripts[i].EventCondition2.Equals("0")) { questEventInfo.EventCondition2 = ""; } questEventInfo.EventCondition3 = scripts[i].EventCondition3; //이벤트 체크 되면 그다음 펑션체크 //Event 빈값과, TASK 는 넘겼으니 여기는 다음 이벤트 부터 처리가 된다. int func_start_idx = i; for (Int32 j = func_start_idx; j <= script_end_idx; j++) { //두번째 돌때부터 EventTarget에 정보가 있으면 break; if (j > func_start_idx && false == scripts[j].EventTarget.Equals(string.Empty)) break; QuestEventFunction func = new QuestEventFunction(); func.Idx = scripts[j].Index; func.FunctionTarget = scripts[j].FunctionTarget; func.FunctionName = scripts[j].Function; func.FunctionCondition1 = scripts[j].FunctionCondition1; func.FunctionCondition2 = scripts[j].FunctionCondition2; func.FunctionCondition3 = scripts[j].FunctionCondition3; questEventInfo.QuestEventFunctionList.Add(func); } } } private void makeTaskSearchInfos(List scripts, ref Dictionary taskSearchInfos, ref QuestBaseInfo questBaseInfo) { Int32 current_task_number = 0; Int32 task_start_idx = 0; for (Int32 i = 0; i < scripts.Count; i++) { if (scripts[i].EventTarget.Equals(nameof(EQuestEventTargetType.TASK)) && scripts[i].Event.Equals(nameof(EQuestEventNameType.ACTIVED))) { if (!int.TryParse(scripts[i].EventCondition1, out int taskNumber)) { Log.getLogger().error($"EventCondition1 is not Number script : {JsonConvert.SerializeObject(scripts[i])}"); return; } //current_task_number 가 0 이 아니고 taskNumber 와 다르다면 태스크를 끝났으므로 여기서 EndIdx 체크 한다. if (current_task_number != 0 && current_task_number != taskNumber) { taskSearchInfos.TryAdd(current_task_number, (task_start_idx, i - 1)); } task_start_idx = i; current_task_number = taskNumber; //QuestTaskGroup 도 여기서 생성해서 넣어준다. QuestTaskGroup task_group = new(); questBaseInfo.QuestTaskGroupList.TryAdd(taskNumber, task_group); } //마지막 인덱스에서 마지막 태스크 정보 저장 if (i == scripts.Count - 1) { taskSearchInfos.TryAdd(current_task_number, (task_start_idx, i)); } } } public string makeEventScriptString(MetaAssets.QuestScriptMetaData script) { StringBuilder builder = new(); string eventCond2 = script.EventCondition2; if (script.EventCondition2.Equals("0")) { eventCond2 = ""; } builder.Append(script.EventTarget) .Append(script.Event) .Append(script.EventCondition1) .Append(eventCond2) .Append(script.EventCondition3); return builder.ToString(); } public string makeEventScriptStringByEventInfo(QuestEventInfo eventInfo) { StringBuilder builder = new(); builder.Append(eventInfo.EventTarget) .Append(eventInfo.EventName) .Append(eventInfo.EventCondition1) .Append(eventInfo.EventCondition2) .Append(eventInfo.EventCondition3); return builder.ToString(); } public CurrencyType CurrencyItemSmallTypeToCurrencyType(EItemSmallType type) { switch (type) { case EItemSmallType.GOLD: return CurrencyType.Gold; case EItemSmallType.SAPPHIRE: return CurrencyType.Sapphire; case EItemSmallType.CALIUM: return CurrencyType.Calium; case EItemSmallType.BEAM: return CurrencyType.Beam; case EItemSmallType.RUBY: return CurrencyType.Ruby; default: return CurrencyType.None; } } private QuestAssignMetaInfo convertDataToQuestAssignMetaInfo(MetaAssets.QuestAssignMetaData data) { QuestAssignMetaInfo info = new(); var composed_quest_id = QuestHelper.convertQuestIdAndRevisionToUgqQuestId(data.QuestId, 0); info.ComposedQuestId = composed_quest_id; info.QuestType = data.QuestType.ToString(); if (data.Reveal == true) info.Reveal = 1; else info.Reveal = 0; info.QuestName = data.QuestName; info.AssignType = data.AssignType.ToString(); info.RequirementType = data.RequirementType.ToString(); info.RequirementValue = data.RequirementValue; if (data.ForceAccept == true) info.ForceAccept = 1; else info.ForceAccept = 0; info.MailTitle = data.MailTitle; info.MailSender = data.MailSender; info.MailDesc = data.MailDesc; info.Dialogue = data.Dialogue; info.DialogueResult = data.DialogueResult; info.RewardGroupId = data.RewardGroupId; info.Priority = data.Priority; return info; } private QuestTaskMetaInfo convertDataToQuestTaskMetaInfo(MetaAssets.QuestMetaData data) { QuestTaskMetaInfo info = new(); var composed_quest_id = QuestHelper.convertQuestIdAndRevisionToUgqQuestId(data.m_quest_id, 0); info.Idx = data.m_idx; info.ComposedQuestId = composed_quest_id; info.TaskNum = data.m_task_num; info.TaskName = data.m_task_name; info.TaskCondition = data.m_task_condition; info.TaskConditionDesc = data.m_task_condition_desc; info.SetCounter = data.m_set_counter; info.WorldId = data.m_world_id; return info; } }