Files
caliverse_server/ServerCommon/MetaData/MetaData.cs
2025-05-01 07:20:41 +09:00

1085 lines
45 KiB
C#

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<MetaAssets.AttributeRandomGroupMetaData> attributeRandomGroupDatas = new();
}
public class ShopProductRandomGroupInfo
{
public int TotalWeight = 0;
public List<MetaAssets.ShopProductMetaData> 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<PropGroupOrderData> 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<MetaAssets.GachaMetaData> GachaList = new();
int TotalWeight = 0;
private Random rng = new Random();
public SelectedGacha(List<MetaAssets.GachaMetaData> 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<MetaAssets.GachaMetaData> getRewardsByOrderNo(Int32 orderNo)
{
var selected_gachas = new List<MetaAssets.GachaMetaData>();
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<string, MetaAssets.TestUserCreateMetaData> m_test_user_create_meta_datas =>
Meta.TestUserCreateMetaTable.TestUserCreateMetaDataListbyId;
public IReadOnlyDictionary<string, MetaAssets.TestUserInitialMetaData> m_test_user_initial_meta_datas =>
Meta.TestUserInitialMetaTable.TestUserInitialMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.UserCreateMetaData> m_user_create_meta_datas =>
Meta.UserCreateMetaTable.UserCreateMetaDataListbyMetaId;
public IReadOnlyDictionary<int, MetaAssets.InstanceMetaData> _IndunTable =>
Meta.InstanceMetaTable.InstanceMetaDataListbyId;
public IReadOnlyDictionary<string, MetaAssets.TextStringMetaData> _textTable =>
Meta.TextStringMetaTable.TextStringMetaDataListbyKey;
public IReadOnlyDictionary<int, MetaAssets.NpcMetaData> _npcTable =>
Meta.NpcMetaTable.NpcMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.InstanceConcertMetaData> _ConcertTable =>
Meta.InstanceConcertMetaTable.InstanceConcertMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.ItemMetaData> _ItemTable =>
Meta.ItemMetaTable.ItemMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.LandMetaData> _LandTable =>
Meta.LandMetaTable.LandMetaDataListbyLandId;
public IReadOnlyDictionary<int, MetaAssets.BuildingMetaData> _BuildingTable =>
Meta.BuildingMetaTable.BuildingMetaDataListbyBuildingId;
public IReadOnlyDictionary<int, MetaAssets.SocialActionMetaData> _SocialActionTable =>
Meta.SocialActionMetaTable.SocialActionMetaDataListbySocial_action_id;
public IReadOnlyDictionary<int, MetaAssets.BuffMetaData> _BuffTable =>
Meta.BuffMetaTable.BuffMetaDataListbyBuffId;
public IReadOnlyDictionary<int, MetaAssets.WarpMetaData> _WarpTable =>
Meta.WarpMetaTable.WarpMetaDataListbyWarpId;
public IReadOnlyDictionary<int, MetaAssets.WorldMetaData> _WorldMetaTable =>
Meta.WorldMetaTable.WorldMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.TaxiMetaData> _TaxiMetaTable =>
Meta.TaxiMetaTable.TaxiMetaDataListbyTaxi_id;
public IReadOnlyDictionary<int, MetaAssets.ToolMetaData> _ToolMetaTable =>
Meta.ToolMetaTable.ToolMetaDataListbyToolId;
public IReadOnlyDictionary<string, MetaAssets.AttributeDefinitionMetaData> _AttributeDefinitionMetaTable =>
Meta.AttributeDefinitionMetaTable.AttributeDefinitionMetaDataListbyKey;
public Dictionary<string, AttributeRandomGroupInfo> _AttributeRandomGroupMetaTable = new();
public IReadOnlyDictionary<int, MetaAssets.ItemLevelEnchantMetaData> _ItemLevelEnchantMetaTable =>
Meta.ItemLevelEnchantMetaTable.ItemLevelEnchantMetaDataListbyLevel;
public Dictionary<string, string> _GameConfigMetaTable = new();
public Dictionary<CurrencyType, MetaAssets.CurrencyMetaData> _CurrencyMetaTableByCurrencyType = new();
public IReadOnlyDictionary<int, MetaAssets.ProductMetaData> _ProductMetaDataById =>
Meta.ProductMetaTable.ProductMetaDataListbyId;
public List<string> _BanWordMetaTable = new();
public List<string> _BanWordNicknameMetaTable = new();
public IReadOnlyDictionary<int, MetaAssets.ShopMetaData> _ShopMetaTable =>
Meta.ShopMetaTable.ShopMetaDataListbyId;
public Dictionary<int, MetaAssets.ShopProductMetaData> _ShopProductMetaTable = new();
public Dictionary<int, List<MetaAssets.ShopProductMetaData>> _ShopNecessaryProductByGroupIdTable = new();
public Dictionary<int, ShopProductRandomGroupInfo> _ShopRandomProductByGroupIdTable = new();
public IReadOnlyDictionary<int, MetaAssets.BasicStyleMetaData> _BasicStyleMetaTable =>
Meta.BasicStyleMetaTable.BasicStyleMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.RewardPropMetaData> _RewardPropMetaTable =>
Meta.RewardPropMetaTable.RewardPropMetaDataListbyId;
public Dictionary<int, PropGroupData> _PropGroupMetaTable = new();
public IReadOnlyList<MetaAssets.ClaimMetaData> _ClaimTable =>
Meta.ClaimMetaTable.ClaimMetaDataList;
public Dictionary<(int, MetaAssets.ClaimType), ClaimMetaData> _ClaimMetaTable = new();
public Dictionary<int, List<MetaAssets.RewardMetaData>> _RewardMetaTable = new();
public Dictionary<int, SelectedGacha> _GachaMetaTable = new();
private IReadOnlyDictionary<UInt32, MetaAssets.QuestAssignMetaData> _QuestAssignMetaTable =>
Meta.QuestAssignMetaTable.QuestAssignMetaDataListbyQuestId;
public List<QuestAssignMetaInfo> m_quest_assign_meta_infos = new();
public List<QuestTaskMetaInfo> m_quest_task_meta_infos = new();
public Dictionary<UInt32, Dictionary<Int32, MetaAssets.QuestScriptMetaData>> _QuestScriptMetaTable = new();
public Dictionary<UInt32, QuestBaseInfo> _QuestBaseinfoTable = new();
public IReadOnlyDictionary<int, MetaAssets.CraftingMetaData> _CraftingMetaTable =>
Meta.CraftingMetaTable.CraftingMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.RequirementMetaData> _RequirementMetaTable =>
Meta.RequirementMetaTable.RequirementMetaDataListbyId;
public IReadOnlyList<MetaAssets.UGQInputTaskMetaData> UGQInputTaskMetaDataList =>
Meta.UGQInputMetaTable.UGQInputTaskMetaDataList;
public IReadOnlyDictionary<Int32, MetaAssets.UGQInputTaskMetaData> UGQInputTaskMetaDataById =>
Meta.UGQInputMetaTable.UGQInputTaskMetaDataListbyId;
public IReadOnlyList<MetaAssets.UGQInputDialogMetaData> UGQInputDialogMetaDataList =>
Meta.UGQInputMetaTable.UGQInputDialogMetaDataList;
public IReadOnlyDictionary<int, MetaAssets.UGQInputDialogMetaData> UGQInputDialogMetaDataListbyId =>
Meta.UGQInputMetaTable.UGQInputDialogMetaDataListbyId;
public IReadOnlyDictionary<Int32, MetaAssets.UGQInputDialogMetaData> UGQInputDialogMetaDataById =>
Meta.UGQInputMetaTable.UGQInputDialogMetaDataListbyId;
public IReadOnlyDictionary<string, MetaAssets.UGQInputDialogConditionMetaData> UGQInputDialogConditionMetaDataListbyName =>
Meta.UGQInputMetaTable.UGQInputDialogConditionMetaDataListbyName;
public IReadOnlyDictionary<int, MetaAssets.UGQPresetImageMetaData> UGQPresetImageMetaDataListbyId =>
Meta.UGQInputMetaTable.UGQPresetImageMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.UGQMapImageMetaData> UGQMapImageMetaDataListbyId =>
Meta.UGQInputMetaTable.UGQMapImageDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.UGQBeaconActionData> UGQBeaconActionDataListbyId =>
Meta.UGQBeaconActionTable.UGQBeaconActionDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.SeasonPassMetaData> SeasonPassMetaData =>
Meta.SeasonPassMetaTable.SeasonPassMetaDataListbyId;
public Dictionary<int, Dictionary<int, MetaAssets.SeasonPassRewardMetaData>> SeasonPassRewardTablebySeasonPassId = new();
public IReadOnlyDictionary<int, MetaAssets.InteriorMetaData> _InteriorMetaTable =>
Meta.InteriorMetaTable.InteriorMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.EditableFrameworkMetaData> _EditableFrameworkMetaTable =>
Meta.EditableFrameworkMetaTable.EditableFrameworkMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.EditableRoomMetaData> _EditableRoomMetaTable =>
Meta.EditableRoomMetaTable.EditableRoomMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.CaliumConverterMaterialData> _CaliumConverterMaterialTable =>
Meta.CaliumConverterMaterialTable.CaliumConverterMaterialDataListbyId;
public IReadOnlyDictionary<string, MetaAssets.SystemMailMetaData> SystemMailMetaData =>
Meta.SystemMailMetaTable.SystemMailMetaDataListbyKey;
public IReadOnlyDictionary<int, MetaAssets.NPCGeneralMetaData> NpcGeneralMetaData =>
Meta.NPCGeneralMetaTable.NPCGeneralMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.FarmingPropMetaData> _FarmingPropMetaTable =>
Meta.FarmingPropMetaTable.FarmingPropMetaDataListbyId;
public IReadOnlyDictionary<int, MetaAssets.ZoneMetaData> ZoneMetaDataListbyId =>
Meta.ZoneMetaTable.ZoneMetaDataListbyId;
public Dictionary<(EditorType, SizeType), MetaAssets.RentalfeeData> _RentalfeeTable = new();
public IReadOnlyDictionary<int, BattleObjectMetaData> _BattleObjectMetaTable =>
Meta.BattleObjectMetaTable.BattleObjectMetaDataListbyId;
public IReadOnlyDictionary<int, BattleObjectSpawnGroupMetaData> _BattleObjectSpawnGroupMetaTable =>
Meta.BattleObjectSpawnGroupMetaTable.BattleObjectSpawnGroupMetaDataListbyId;
public IReadOnlyDictionary<int, BattleFFAConfigData> _BattleFFAConfigMetaTable =>
Meta.BattleFFAConfigMetaTable.BattleFFAConfigMetaDataListbyId;
public IReadOnlyDictionary<int, IReadOnlyDictionary<int, BattleFFARewardData>> _BattleFFARewardMetaTable = new Dictionary<int, IReadOnlyDictionary<int, BattleFFARewardData>>();
public BattleObjectMetaData _BattlePodStorageMeta = new(new());
public BattleObjectMetaData _BattlePickupPodMeta = new(new());
public IReadOnlyDictionary<int, MetaAssets.UserLogMetaData> 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<MetaAssets.ShopProductMetaData>();
_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<int> 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<int, MetaAssets.SeasonPassRewardMetaData>();
SeasonPassRewardTablebySeasonPassId.Add(one.SeasonPassId, seasonPassRewardList);
}
seasonPassRewardList.Add(one.Grade, one);
}
}
{
List<int> 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<int, BattleFFARewardData>)group
.OrderBy(data => data.ChargeLevel)
.ToDictionary(data => data.ChargeLevel, data => data)
) as IReadOnlyDictionary<int, IReadOnlyDictionary<int, BattleFFARewardData>>;
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<MetaAssets.ClaimRewardMetaData> 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<Int32, MetaAssets.QuestScriptMetaData>();
_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<UInt32, QuestBaseInfo> LoadQuestBaseInfo()
{
Dictionary<UInt32, QuestBaseInfo> 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<int> setTaskNum = new();
SortedSet<int> 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<QuestScriptMetaData> scripts, ref QuestBaseInfo questBaseInfo, ref SortedSet<int> 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<Int32 /*Task Number*/, (Int32, Int32) /*Task Start Index i, Task End Index*/> 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<QuestScriptMetaData> scripts, KeyValuePair<Int32, (Int32, Int32)> 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<QuestScriptMetaData> scripts, KeyValuePair<Int32, (Int32, Int32)> 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<QuestScriptMetaData> scripts, KeyValuePair<Int32, (Int32, Int32)> 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<QuestScriptMetaData> scripts, ref Dictionary<Int32, (Int32, Int32) > 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;
}
}