| using System;  | 
| using System.Collections.Generic;  | 
| using UnityEngine;  | 
| using Cysharp.Threading.Tasks;  | 
| using System.Reflection;  | 
| using System.Linq;  | 
|   | 
| #if UNITY_EDITOR  | 
| using UnityEditor;  | 
| #endif  | 
|   | 
| public class ConfigManager : ManagerBase<ConfigManager>  | 
| {  | 
|     public bool isLoadFinished  | 
|     {  | 
|         get;  | 
|         private set;  | 
|     }  | 
|   | 
|     private float loadingProgress = 0f;  | 
|   | 
|     public override void Init()  | 
|     {  | 
|         base.Init();  | 
|         InitConfigs();  | 
|     }  | 
|   | 
|     public virtual async UniTask InitConfigs()  | 
|     {  | 
|         // 加载配置文件  | 
|         await LoadConfigs();  | 
|     }  | 
|   | 
|     protected async UniTask LoadConfigs()  | 
|     {  | 
|         loadingProgress = 0f;  | 
|         isLoadFinished = false;  | 
|   | 
|         // 加载配置文件  | 
|         HashSet<Type> configTypes = new HashSet<Type>() {  | 
|             typeof(ADAwardConfig),  | 
|             typeof(BattleMapConfig),  | 
|             typeof(ChestsAwardConfig),  | 
|             typeof(CTGConfig),  | 
|             typeof(DamageNumConfig),  | 
|             typeof(DirtyWordConfig),  | 
|             typeof(DungeonConfig),  | 
|             typeof(DungeonOpenTimeConfig),  | 
|             typeof(FaceConfig),  | 
|             typeof(FamilyDonateConfig),  | 
|             typeof(FightPowerRatioConfig),  | 
|             typeof(FirstChargeConfig),  | 
|             typeof(GoldRushCampConfig),  | 
|             typeof(GoldRushItemConfig),  | 
|             typeof(GoldRushWorkerConfig),  | 
|             typeof(HeroLineupHaloConfig),  | 
|             typeof(HeroQualityLVConfig),  | 
|             typeof(InvestConfig),  | 
|             typeof(ItemConfig),  | 
|             typeof(MainChapterConfig),  | 
|             typeof(MainLevelConfig),  | 
|             typeof(NPCConfig),  | 
|             typeof(NPCExConfig),  | 
|             typeof(NPCLineupConfig),  | 
|             typeof(OrderInfoConfig),  | 
|             typeof(PlayerAttrConfig),  | 
|             typeof(PlayerFaceConfig),  | 
|             typeof(PriorBundleConfig),  | 
|             typeof(StoreConfig),  | 
|             typeof(SuccessConfig),  | 
|             typeof(SysInfoConfig),  | 
|             typeof(TitleStarUpConfig),  | 
|             typeof(TreasureSetConfig),  | 
|             typeof(TreeLVConfig),  | 
|             typeof(WindowSearchConfig),  | 
|             typeof(XBGetItemConfig)  | 
|         };  | 
|   | 
| #if UNITY_EDITOR  | 
|         HashSet<Type> configHashSet = new HashSet<Type>();  | 
|         if (System.IO.File.Exists(Application.dataPath + "/fastConfig.txt") && Launch.Instance.isOpenConfigTesting)  | 
|         {  | 
|             string[] strConfgsArr = System.IO.File.ReadAllLines(Application.dataPath + "/fastConfig.txt");  | 
|             foreach (string str in strConfgsArr)  | 
|             {  | 
|                 Type tpy = Type.GetType(str);  | 
|                 configHashSet.Add(tpy);  | 
|             }  | 
|         }  | 
|         //  编辑器下加入 评估加载时常  | 
|         foreach (var config in configHashSet)  | 
|         {  | 
|             if (!configTypes.Add(config))  | 
|             {  | 
|                 Debug.LogWarning($"配置 {config.Name} 已经存在于 configTypes 中,跳过添加。");  | 
|             }  | 
|         }  | 
|         List<string> fastName = new List<string>();  | 
| #endif  | 
|         int iterator = 0;  | 
|         int totalConfigs = configTypes.Count;  | 
|   | 
|         // 逐个加载配置并更新进度  | 
|         foreach (var configType in configTypes)  | 
|         {  | 
|             var sw = System.Diagnostics.Stopwatch.StartNew();  | 
|             LoadConfigByType(configType);  | 
|             sw.Stop();  | 
| #if UNITY_EDITOR  | 
|             if (sw.ElapsedMilliseconds >= 100)  | 
|             {  | 
|                 Debug.LogError($"加载配置 {configType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");  | 
|             }  | 
|             else if (sw.ElapsedMilliseconds <= 5)  | 
|             {  | 
|                 fastName.Add(configType.Name);  | 
|             }  | 
|             Debug.Log($"加载配置: {configType.Name} 用时: {sw.ElapsedMilliseconds} ms");  | 
| #endif  | 
|             loadingProgress = (float)(iterator++ + 1) / totalConfigs;  | 
|         }  | 
| #if UNITY_EDITOR  | 
|         if (Launch.Instance.isOpenConfigTesting)  | 
|         {  | 
|             System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));  | 
|   | 
|             //加载完后卸载  | 
|             foreach (var configType in configTypes)  | 
|             {  | 
|                 var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);  | 
|                 if (methodInfo != null)  | 
|                 {  | 
|                     methodInfo.Invoke(null, null);  | 
|                 }  | 
|             }  | 
|         }  | 
| #endif  | 
|   | 
|         // 加载完成后设置isLoadFinished为true  | 
|         loadingProgress = 1f;  | 
|         isLoadFinished = true;  | 
|     }  | 
|   | 
|     public void LoadConfigByType(Type configType)  | 
|     {  | 
|         string configName = configType.Name;  | 
|         if (configName.EndsWith("Config"))  | 
|         {  | 
|             configName = configName.Substring(0, configName.Length - 6);  | 
|         }  | 
|         string[] texts = ResManager.Instance.LoadConfig(configName);  | 
|         if (texts != null)  | 
|         {  | 
|             string[] lines = texts;  | 
|             var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);  | 
|             if (methodInfo != null)  | 
|             {  | 
|                 methodInfo.Invoke(null, new object[] { lines });  | 
|                 // 设置初始化标志  | 
|                 var isInitField = configType.GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);  | 
|                 if (isInitField != null)  | 
|                 {  | 
|                     isInitField.SetValue(null, true);  | 
|                 }  | 
|                 Debug.Log($"加载配置: {configType.Name} 成功");  | 
|             }  | 
|             else  | 
|             {  | 
|                 Debug.LogError($"配置类 {configType.Name} 没有静态Init方法");  | 
|             }  | 
|         }  | 
|         else  | 
|         {  | 
|             Debug.LogError($"找不到配置文件: {configName}");  | 
|         }  | 
|     }  | 
|   | 
|     private async UniTask LoadConfig<T>() where T : class  | 
|     {  | 
|         string configName = typeof(T).Name;  | 
|   | 
|         string[] texts = ResManager.Instance.LoadConfig(configName);  | 
|         if (texts != null)  | 
|         {  | 
|             string[] lines = texts;  | 
|             var methodInfo = typeof(T).GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);  | 
|             if (methodInfo != null)  | 
|             {  | 
|                 methodInfo.Invoke(null, lines);  | 
|                 // 设置初始化标志  | 
|                 var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);  | 
|                 if (isInitField != null)  | 
|                 {  | 
|                     isInitField.SetValue(null, true);  | 
|                 }  | 
|                 Debug.Log($"加载配置: {typeof(T).Name} 成功");  | 
|             }  | 
|             else  | 
|             {  | 
|                 Debug.LogError($"配置类 {typeof(T).Name} 没有静态Init方法");  | 
|             }  | 
|         }  | 
|         else  | 
|         {  | 
|             Debug.LogError($"找不到配置文件: {configName}");  | 
|         }  | 
|     }  | 
|   | 
|     public float GetLoadingProgress()  | 
|     {  | 
|         return loadingProgress;  | 
|     }  | 
|   | 
|     private void ClearConfigDictionary<T>() where T : class  | 
|     {  | 
|         // 重置 T 初始化状态  | 
|         var isInitField = typeof(T).GetField("isInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);  | 
|         if (isInitField != null)  | 
|         {  | 
|             isInitField.SetValue(null, false);  | 
|         }  | 
|     }  | 
|   | 
|     public override void Release()  | 
|     {  | 
|         // 清空 ADAwardConfig 字典  | 
|         ClearConfigDictionary<ADAwardConfig>();  | 
|         // 清空 BattleMapConfig 字典  | 
|         ClearConfigDictionary<BattleMapConfig>();  | 
|         // 清空 ChestsAwardConfig 字典  | 
|         ClearConfigDictionary<ChestsAwardConfig>();  | 
|         // 清空 CTGConfig 字典  | 
|         ClearConfigDictionary<CTGConfig>();  | 
|         // 清空 DamageNumConfig 字典  | 
|         ClearConfigDictionary<DamageNumConfig>();  | 
|         // 清空 DirtyWordConfig 字典  | 
|         ClearConfigDictionary<DirtyWordConfig>();  | 
|         // 清空 DungeonConfig 字典  | 
|         ClearConfigDictionary<DungeonConfig>();  | 
|         // 清空 DungeonOpenTimeConfig 字典  | 
|         ClearConfigDictionary<DungeonOpenTimeConfig>();  | 
|         // 清空 FaceConfig 字典  | 
|         ClearConfigDictionary<FaceConfig>();  | 
|         // 清空 FamilyDonateConfig 字典  | 
|         ClearConfigDictionary<FamilyDonateConfig>();  | 
|         // 清空 FightPowerRatioConfig 字典  | 
|         ClearConfigDictionary<FightPowerRatioConfig>();  | 
|         // 清空 FirstChargeConfig 字典  | 
|         ClearConfigDictionary<FirstChargeConfig>();  | 
|         // 清空 GoldRushCampConfig 字典  | 
|         ClearConfigDictionary<GoldRushCampConfig>();  | 
|         // 清空 GoldRushItemConfig 字典  | 
|         ClearConfigDictionary<GoldRushItemConfig>();  | 
|         // 清空 GoldRushWorkerConfig 字典  | 
|         ClearConfigDictionary<GoldRushWorkerConfig>();  | 
|         // 清空 HeroLineupHaloConfig 字典  | 
|         ClearConfigDictionary<HeroLineupHaloConfig>();  | 
|         // 清空 HeroQualityLVConfig 字典  | 
|         ClearConfigDictionary<HeroQualityLVConfig>();  | 
|         // 清空 InvestConfig 字典  | 
|         ClearConfigDictionary<InvestConfig>();  | 
|         // 清空 ItemConfig 字典  | 
|         ClearConfigDictionary<ItemConfig>();  | 
|         // 清空 MainChapterConfig 字典  | 
|         ClearConfigDictionary<MainChapterConfig>();  | 
|         // 清空 MainLevelConfig 字典  | 
|         ClearConfigDictionary<MainLevelConfig>();  | 
|         // 清空 NPCConfig 字典  | 
|         ClearConfigDictionary<NPCConfig>();  | 
|         // 清空 NPCExConfig 字典  | 
|         ClearConfigDictionary<NPCExConfig>();  | 
|         // 清空 NPCLineupConfig 字典  | 
|         ClearConfigDictionary<NPCLineupConfig>();  | 
|         // 清空 OrderInfoConfig 字典  | 
|         ClearConfigDictionary<OrderInfoConfig>();  | 
|         // 清空 PlayerAttrConfig 字典  | 
|         ClearConfigDictionary<PlayerAttrConfig>();  | 
|         // 清空 PlayerFaceConfig 字典  | 
|         ClearConfigDictionary<PlayerFaceConfig>();  | 
|         // 清空 PriorBundleConfig 字典  | 
|         ClearConfigDictionary<PriorBundleConfig>();  | 
|         // 清空 StoreConfig 字典  | 
|         ClearConfigDictionary<StoreConfig>();  | 
|         // 清空 SuccessConfig 字典  | 
|         ClearConfigDictionary<SuccessConfig>();  | 
|         // 清空 SysInfoConfig 字典  | 
|         ClearConfigDictionary<SysInfoConfig>();  | 
|         // 清空 TitleStarUpConfig 字典  | 
|         ClearConfigDictionary<TitleStarUpConfig>();  | 
|         // 清空 TreasureSetConfig 字典  | 
|         ClearConfigDictionary<TreasureSetConfig>();  | 
|         // 清空 TreeLVConfig 字典  | 
|         ClearConfigDictionary<TreeLVConfig>();  | 
|         // 清空 WindowSearchConfig 字典  | 
|         ClearConfigDictionary<WindowSearchConfig>();  | 
|         // 清空 XBGetItemConfig 字典  | 
|         ClearConfigDictionary<XBGetItemConfig>();  | 
|     }  | 
|   | 
| #if UNITY_EDITOR  | 
|     [MenuItem("Tools/Config/自检")]  | 
|     public static void CheckAndGenerateFastConfig()  | 
|     {  | 
|         // 获取 Editor Assembly  | 
|         var editorAsm = System.AppDomain.CurrentDomain.GetAssemblies()  | 
|             .FirstOrDefault(a => a.FullName.Contains("Editor"));  | 
|   | 
|         if (editorAsm == null)  | 
|         {  | 
|             Debug.LogError("[自检] 未找到 Editor Assembly,无法自检。");  | 
|             return;  | 
|         }  | 
|   | 
|         // 反射获取 ConfigGenerater 类型  | 
|         var configGeneraterType = editorAsm.GetType("ConfigGenerater");  | 
|         if (configGeneraterType == null)  | 
|         {  | 
|             Debug.LogError("[自检] 未找到 ConfigGenerater 类型。");  | 
|             return;  | 
|         }  | 
|   | 
|         // 调用 GetAllConfigClasses 静态方法  | 
|         var getAllConfigClassesMethod = configGeneraterType.GetMethod("GetAllConfigClasses", BindingFlags.Public | BindingFlags.Static);  | 
|         var allConfigClasses = getAllConfigClassesMethod?.Invoke(null, null) as List<string>;  | 
|         if (allConfigClasses == null)  | 
|         {  | 
|             Debug.LogError("[自检] 获取全部配置类失败。");  | 
|             return;  | 
|         }  | 
|   | 
|         // 获取 ExcludeClassList 字段  | 
|         var excludeField = configGeneraterType.GetField("ExcludeClassList", BindingFlags.Public | BindingFlags.Static);  | 
|         var excludeClassList = excludeField?.GetValue(null) as List<string> ?? new List<string>();  | 
|   | 
|         // 排除不需要的类  | 
|         var checkClasses = allConfigClasses.Where(c => !excludeClassList.Contains(c)).ToList();  | 
|   | 
|         List<string> fastName = new List<string>();  | 
|   | 
|         foreach (var className in checkClasses)  | 
|         {  | 
|             // 这里也要用 Editor Assembly 获取类型  | 
|             var configType = editorAsm.GetType(className) ?? Type.GetType(className);  | 
|             if (configType == null)  | 
|             {  | 
|                 Debug.LogWarning($"[自检] 未找到类型: {className}");  | 
|                 continue;  | 
|             }  | 
|   | 
|             var sw = System.Diagnostics.Stopwatch.StartNew();  | 
|   | 
|             // 反射调用静态Init方法  | 
|             string configName = configType.Name;  | 
|             if (configName.EndsWith("Config"))  | 
|                 configName = configName.Substring(0, configName.Length - 6);  | 
|   | 
|             string[] texts = ResManager.Instance.LoadConfig(configName);  | 
|             if (texts != null)  | 
|             {  | 
|                 string[] lines = texts;  | 
|                 var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);  | 
|                 if (methodInfo != null)  | 
|                 {  | 
|                     methodInfo.Invoke(null, new object[] { lines });  | 
|                 }  | 
|             }  | 
|   | 
|             sw.Stop();  | 
|   | 
|             if (sw.ElapsedMilliseconds >= 100)  | 
|             {  | 
|                 Debug.LogError($"[自检] 加载配置 {configType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");  | 
|             }  | 
|             else if (sw.ElapsedMilliseconds <= 5)  | 
|             {  | 
|                 fastName.Add(configType.Name);  | 
|             }  | 
|             Debug.Log($"[自检] 加载配置: {configType.Name} 用时: {sw.ElapsedMilliseconds} ms");  | 
|         }  | 
|   | 
|         // 释放所有已加载的配置  | 
|         foreach (var className in checkClasses)  | 
|         {  | 
|             var configType = editorAsm.GetType(className) ?? Type.GetType(className);  | 
|             if (configType == null) continue;  | 
|             var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);  | 
|             if (methodInfo != null)  | 
|             {  | 
|                 methodInfo.Invoke(null, null);  | 
|             }  | 
|         }  | 
|   | 
|         System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));  | 
|         Debug.Log($"[自检] fastConfig.txt 生成完毕,快速表有:{string.Join(", ", fastName)}");  | 
|     }  | 
| #endif  | 
| }  |