|  |  | 
 |  |  | using UnityEngine;
 | 
 |  |  | using Cysharp.Threading.Tasks;
 | 
 |  |  | using System.Reflection;
 | 
 |  |  | using System.Linq;
 | 
 |  |  | 
 | 
 |  |  | #if UNITY_EDITOR
 | 
 |  |  | using UnityEditor;
 | 
 |  |  | #endif
 | 
 |  |  | 
 | 
 |  |  | public class ConfigManager : ManagerBase<ConfigManager>
 | 
 |  |  | {
 | 
 |  |  | 
 |  |  |         isLoadFinished = false;
 | 
 |  |  | 
 | 
 |  |  |         // 加载配置文件
 | 
 |  |  |         int totalConfigs = 17;
 | 
 |  |  |         List<Type> configTypes = new List<Type>() {
 | 
 |  |  |         HashSet<Type> configTypes = new HashSet<Type>() {
 | 
 |  |  |             typeof(ADAwardConfig),
 | 
 |  |  |             typeof(ChestsAwardConfig),
 | 
 |  |  |             typeof(CTGConfig),
 | 
 |  |  |             typeof(DamageNumConfig),
 | 
 |  |  |             typeof(DirtyWordConfig),
 | 
 |  |  |             typeof(EquipGSParamConfig),
 | 
 |  |  |             typeof(DungeonConfig),
 | 
 |  |  |             typeof(DungeonOpenTimeConfig),
 | 
 |  |  |             typeof(FaceConfig),
 | 
 |  |  |             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(PlayerFacePicStarConfig),
 | 
 |  |  |             typeof(PlayerFaceStarConfig),
 | 
 |  |  |             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"))
 | 
 |  |  |         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)
 | 
 |  |  | 
 |  |  |             }
 | 
 |  |  |         }
 | 
 |  |  |         //  编辑器下加入 评估加载时常
 | 
 |  |  |         configTypes.AddRange(configHashSet);
 | 
 |  |  |         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;
 | 
 |  |  | 
 | 
 |  |  |         // 逐个加载配置并更新进度
 | 
 |  |  |         for (int i = 0; i < configTypes.Count; i++)
 | 
 |  |  |         foreach (var configType in configTypes)
 | 
 |  |  |         {
 | 
 |  |  |             var sw = System.Diagnostics.Stopwatch.StartNew();
 | 
 |  |  |             LoadConfigByType(configTypes[i]);
 | 
 |  |  |             LoadConfigByType(configType);
 | 
 |  |  |             sw.Stop();
 | 
 |  |  | #if UNITY_EDITOR
 | 
 |  |  |             if (sw.ElapsedMilliseconds >= 100)
 | 
 |  |  |             {
 | 
 |  |  |                 Debug.LogError($"加载配置 {configTypes[i].Name} 耗时较长: {sw.ElapsedMilliseconds} ms");
 | 
 |  |  |                 Debug.LogError($"加载配置 {configType.Name} 耗时较长: {sw.ElapsedMilliseconds} ms");
 | 
 |  |  |             }
 | 
 |  |  |             else if (sw.ElapsedMilliseconds <= 5)
 | 
 |  |  |             {
 | 
 |  |  |                 fastName.Add(configTypes[i].Name);
 | 
 |  |  |                 fastName.Add(configType.Name);
 | 
 |  |  |             }
 | 
 |  |  |             Debug.Log($"加载配置: {configTypes[i].Name} 用时: {sw.ElapsedMilliseconds} ms");
 | 
 |  |  |             Debug.Log($"加载配置: {configType.Name} 用时: {sw.ElapsedMilliseconds} ms");
 | 
 |  |  | #endif
 | 
 |  |  |             loadingProgress = (float)(i + 1) / totalConfigs;
 | 
 |  |  |             loadingProgress = (float)(iterator++ + 1) / totalConfigs;
 | 
 |  |  |         }
 | 
 |  |  | #if UNITY_EDITOR
 | 
 |  |  |         System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));
 | 
 |  |  | 
 | 
 |  |  |         //加载完后卸载
 | 
 |  |  |         foreach (var configType in configTypes)
 | 
 |  |  |         if (Launch.Instance.isOpenConfigTesting)
 | 
 |  |  |         {
 | 
 |  |  |             var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
 | 
 |  |  |             if (methodInfo != null)
 | 
 |  |  |             System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));
 | 
 |  |  | 
 | 
 |  |  |             //加载完后卸载
 | 
 |  |  |             foreach (var configType in configTypes)
 | 
 |  |  |             {
 | 
 |  |  |                 methodInfo.Invoke(null, null);
 | 
 |  |  |                 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
 | 
 |  |  | 
 |  |  | 
 | 
 |  |  |     public override void Release()
 | 
 |  |  |     {
 | 
 |  |  |         // 清空 ADAwardConfig 字典
 | 
 |  |  |         ClearConfigDictionary<ADAwardConfig>();
 | 
 |  |  |         // 清空 ChestsAwardConfig 字典
 | 
 |  |  |         ClearConfigDictionary<ChestsAwardConfig>();
 | 
 |  |  |         // 清空 CTGConfig 字典
 | 
 |  |  |         ClearConfigDictionary<CTGConfig>();
 | 
 |  |  |         // 清空 DamageNumConfig 字典
 | 
 |  |  |         ClearConfigDictionary<DamageNumConfig>();
 | 
 |  |  |         // 清空 DirtyWordConfig 字典
 | 
 |  |  |         ClearConfigDictionary<DirtyWordConfig>();
 | 
 |  |  |         // 清空 EquipGSParamConfig 字典
 | 
 |  |  |         ClearConfigDictionary<EquipGSParamConfig>();
 | 
 |  |  |         // 清空 DungeonConfig 字典
 | 
 |  |  |         ClearConfigDictionary<DungeonConfig>();
 | 
 |  |  |         // 清空 DungeonOpenTimeConfig 字典
 | 
 |  |  |         ClearConfigDictionary<DungeonOpenTimeConfig>();
 | 
 |  |  |         // 清空 FaceConfig 字典
 | 
 |  |  |         ClearConfigDictionary<FaceConfig>();
 | 
 |  |  |         // 清空 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>();
 | 
 |  |  |         // 清空 PlayerFacePicStarConfig 字典
 | 
 |  |  |         ClearConfigDictionary<PlayerFacePicStarConfig>();
 | 
 |  |  |         // 清空 PlayerFaceStarConfig 字典
 | 
 |  |  |         ClearConfigDictionary<PlayerFaceStarConfig>();
 | 
 |  |  |         // 清空 PriorBundleConfig 字典
 | 
 |  |  |         ClearConfigDictionary<PriorBundleConfig>();
 | 
 |  |  |         // 清空 StoreConfig 字典
 | 
 |  |  |         ClearConfigDictionary<StoreConfig>();
 | 
 |  |  |         // 清空 SuccessConfig 字典
 | 
 |  |  | 
 |  |  |         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
 | 
 |  |  | }
 |