hch
85 分钟以前 c26c07703564106864e6c1af1b437f4060c6cbac
Main/Config/ConfigManager.cs
@@ -3,7 +3,11 @@
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Reflection;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class ConfigManager : ManagerBase<ConfigManager>
{
@@ -33,96 +37,112 @@
        isLoadFinished = false;
        // 加载配置文件
        int totalConfigs = 63;
        Type[] configTypes = new Type[] {
            typeof(AppointItemConfig),
            typeof(AudioConfig),
            typeof(ChatBubbleBoxConfig),
        HashSet<Type> configTypes = new HashSet<Type>() {
            typeof(ChestsAwardConfig),
            typeof(ChestsConfig),
            typeof(CTGConfig),
            typeof(CTGSelectItemConfig),
            typeof(DailyLivenessRewardConfig),
            typeof(DailyQuestConfig),
            typeof(DailyQuestOpenTimeConfig),
            typeof(DienstgradConfig),
            typeof(DirtyNameConfig),
            typeof(DamageNumConfig),
            typeof(DirtyWordConfig),
            typeof(EffectConfig),
            typeof(EmojiPackConfig),
            typeof(EquipGSParamConfig),
            typeof(EquipPlaceMapConfig),
            typeof(FamilyConfig),
            typeof(FamilyEmblemConfig),
            typeof(FirstGoldConfig),
            typeof(FrameAnimationConfig),
            typeof(FuncConfigConfig),
            typeof(FuncOpenLVConfig),
            typeof(FunctionTeamSetConfig),
            typeof(GetItemWaysConfig),
            typeof(GmCmdConfig),
            typeof(GuideConfig),
            typeof(HeroAwakeConfig),
            typeof(HeroBreakConfig),
            typeof(HeroConfig),
            typeof(HeroFetterConfig),
            typeof(HeroQualityAwakeConfig),
            typeof(HeroQualityBreakConfig),
            typeof(HeroQualityConfig),
            typeof(HeroSkinConfig),
            typeof(HeroTalentConfig),
            typeof(IconConfig),
            typeof(FaceConfig),
            typeof(FightPowerRatioConfig),
            typeof(HeroLineupHaloConfig),
            typeof(HeroQualityLVConfig),
            typeof(InvestConfig),
            typeof(ItemConfig),
            typeof(KickOutReasonConfig),
            typeof(LanguageConfig),
            typeof(MailConfig),
            typeof(MainChapterConfig),
            typeof(MainLevelConfig),
            typeof(NPCConfig),
            typeof(NPCExConfig),
            typeof(NPCLineupConfig),
            typeof(OrderInfoConfig),
            typeof(PlayerAttrConfig),
            typeof(PlayerFaceConfig),
            typeof(PlayerFacePicConfig),
            typeof(PlayerLVConfig),
            typeof(PlayerPropertyConfig),
            typeof(priorbundleConfig),
            typeof(RealmConfig),
            typeof(RealmLVUPTaskConfig),
            typeof(RichTextMsgReplaceConfig),
            typeof(RuleConfig),
            typeof(SkillConfig),
            typeof(PriorBundleConfig),
            typeof(StoreConfig),
            typeof(SuccessConfig),
            typeof(SysInfoConfig),
            typeof(TaskConfig),
            typeof(TitleStarUpConfig),
            typeof(TreasureCntAwardConfig),
            typeof(TreasureItemLibConfig),
            typeof(TreasureSetConfig),
            typeof(TreeLVConfig),
            typeof(WindowSearchConfig),
            typeof(XBGetItemConfig)
        };
        // 逐个加载配置并更新进度
        for (int i = 0; i < configTypes.Length; i++)
#if UNITY_EDITOR
        HashSet<Type> configHashSet = new HashSet<Type>();
        if (System.IO.File.Exists(Application.dataPath + "/fastConfig.txt") && Launch.Instance.isOpenConfigTesting)
        {
            await LoadConfigByType(configTypes[i]);
            loadingProgress = (float)(i + 1) / totalConfigs;
            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 async UniTask LoadConfigByType(Type configType)
    public void LoadConfigByType(Type configType)
    {
        string configName = configType.Name;
        if (configName.EndsWith("Config"))
        {
            configName = configName.Substring(0, configName.Length - 6);
        }
        TextAsset textAsset = ResManager.Instance.LoadAsset<TextAsset>("Config", configName);
        if (textAsset != null)
        string[] texts = ResManager.Instance.LoadConfig(configName);
        if (texts != null)
        {
            string[] lines = textAsset.text.Split('\n');
            string[] lines = texts;
            var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
            if (methodInfo != null)
            {
@@ -150,10 +170,10 @@
    {
        string configName = typeof(T).Name;
        TextAsset textAsset = ResManager.Instance.LoadAsset<TextAsset>("Config", configName);
        if (textAsset != null)
        string[] texts = ResManager.Instance.LoadConfig(configName);
        if (texts != null)
        {
            string[] lines = textAsset.text.Split('\n');
            string[] lines = texts;
            var methodInfo = typeof(T).GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            if (methodInfo != null)
            {
@@ -194,131 +214,157 @@
    public override void Release()
    {
        // 清空 AppointItemConfig 字典
        ClearConfigDictionary<AppointItemConfig>();
        // 清空 AudioConfig 字典
        ClearConfigDictionary<AudioConfig>();
        // 清空 ChatBubbleBoxConfig 字典
        ClearConfigDictionary<ChatBubbleBoxConfig>();
        // 清空 ChestsAwardConfig 字典
        ClearConfigDictionary<ChestsAwardConfig>();
        // 清空 ChestsConfig 字典
        ClearConfigDictionary<ChestsConfig>();
        // 清空 CTGConfig 字典
        ClearConfigDictionary<CTGConfig>();
        // 清空 CTGSelectItemConfig 字典
        ClearConfigDictionary<CTGSelectItemConfig>();
        // 清空 DailyLivenessRewardConfig 字典
        ClearConfigDictionary<DailyLivenessRewardConfig>();
        // 清空 DailyQuestConfig 字典
        ClearConfigDictionary<DailyQuestConfig>();
        // 清空 DailyQuestOpenTimeConfig 字典
        ClearConfigDictionary<DailyQuestOpenTimeConfig>();
        // 清空 DienstgradConfig 字典
        ClearConfigDictionary<DienstgradConfig>();
        // 清空 DirtyNameConfig 字典
        ClearConfigDictionary<DirtyNameConfig>();
        // 清空 DamageNumConfig 字典
        ClearConfigDictionary<DamageNumConfig>();
        // 清空 DirtyWordConfig 字典
        ClearConfigDictionary<DirtyWordConfig>();
        // 清空 EffectConfig 字典
        ClearConfigDictionary<EffectConfig>();
        // 清空 EmojiPackConfig 字典
        ClearConfigDictionary<EmojiPackConfig>();
        // 清空 EquipGSParamConfig 字典
        ClearConfigDictionary<EquipGSParamConfig>();
        // 清空 EquipPlaceMapConfig 字典
        ClearConfigDictionary<EquipPlaceMapConfig>();
        // 清空 FamilyConfig 字典
        ClearConfigDictionary<FamilyConfig>();
        // 清空 FamilyEmblemConfig 字典
        ClearConfigDictionary<FamilyEmblemConfig>();
        // 清空 FirstGoldConfig 字典
        ClearConfigDictionary<FirstGoldConfig>();
        // 清空 FrameAnimationConfig 字典
        ClearConfigDictionary<FrameAnimationConfig>();
        // 清空 FuncConfigConfig 字典
        ClearConfigDictionary<FuncConfigConfig>();
        // 清空 FuncOpenLVConfig 字典
        ClearConfigDictionary<FuncOpenLVConfig>();
        // 清空 FunctionTeamSetConfig 字典
        ClearConfigDictionary<FunctionTeamSetConfig>();
        // 清空 GetItemWaysConfig 字典
        ClearConfigDictionary<GetItemWaysConfig>();
        // 清空 GmCmdConfig 字典
        ClearConfigDictionary<GmCmdConfig>();
        // 清空 GuideConfig 字典
        ClearConfigDictionary<GuideConfig>();
        // 清空 HeroAwakeConfig 字典
        ClearConfigDictionary<HeroAwakeConfig>();
        // 清空 HeroBreakConfig 字典
        ClearConfigDictionary<HeroBreakConfig>();
        // 清空 HeroConfig 字典
        ClearConfigDictionary<HeroConfig>();
        // 清空 HeroFetterConfig 字典
        ClearConfigDictionary<HeroFetterConfig>();
        // 清空 HeroQualityAwakeConfig 字典
        ClearConfigDictionary<HeroQualityAwakeConfig>();
        // 清空 HeroQualityBreakConfig 字典
        ClearConfigDictionary<HeroQualityBreakConfig>();
        // 清空 HeroQualityConfig 字典
        ClearConfigDictionary<HeroQualityConfig>();
        // 清空 HeroSkinConfig 字典
        ClearConfigDictionary<HeroSkinConfig>();
        // 清空 HeroTalentConfig 字典
        ClearConfigDictionary<HeroTalentConfig>();
        // 清空 IconConfig 字典
        ClearConfigDictionary<IconConfig>();
        // 清空 FaceConfig 字典
        ClearConfigDictionary<FaceConfig>();
        // 清空 FightPowerRatioConfig 字典
        ClearConfigDictionary<FightPowerRatioConfig>();
        // 清空 HeroLineupHaloConfig 字典
        ClearConfigDictionary<HeroLineupHaloConfig>();
        // 清空 HeroQualityLVConfig 字典
        ClearConfigDictionary<HeroQualityLVConfig>();
        // 清空 InvestConfig 字典
        ClearConfigDictionary<InvestConfig>();
        // 清空 ItemConfig 字典
        ClearConfigDictionary<ItemConfig>();
        // 清空 KickOutReasonConfig 字典
        ClearConfigDictionary<KickOutReasonConfig>();
        // 清空 LanguageConfig 字典
        ClearConfigDictionary<LanguageConfig>();
        // 清空 MailConfig 字典
        ClearConfigDictionary<MailConfig>();
        // 清空 MainChapterConfig 字典
        ClearConfigDictionary<MainChapterConfig>();
        // 清空 MainLevelConfig 字典
        ClearConfigDictionary<MainLevelConfig>();
        // 清空 NPCConfig 字典
        ClearConfigDictionary<NPCConfig>();
        // 清空 NPCExConfig 字典
        ClearConfigDictionary<NPCExConfig>();
        // 清空 NPCLineupConfig 字典
        ClearConfigDictionary<NPCLineupConfig>();
        // 清空 OrderInfoConfig 字典
        ClearConfigDictionary<OrderInfoConfig>();
        // 清空 PlayerAttrConfig 字典
        ClearConfigDictionary<PlayerAttrConfig>();
        // 清空 PlayerFaceConfig 字典
        ClearConfigDictionary<PlayerFaceConfig>();
        // 清空 PlayerFacePicConfig 字典
        ClearConfigDictionary<PlayerFacePicConfig>();
        // 清空 PlayerLVConfig 字典
        ClearConfigDictionary<PlayerLVConfig>();
        // 清空 PlayerPropertyConfig 字典
        ClearConfigDictionary<PlayerPropertyConfig>();
        // 清空 priorbundleConfig 字典
        ClearConfigDictionary<priorbundleConfig>();
        // 清空 RealmConfig 字典
        ClearConfigDictionary<RealmConfig>();
        // 清空 RealmLVUPTaskConfig 字典
        ClearConfigDictionary<RealmLVUPTaskConfig>();
        // 清空 RichTextMsgReplaceConfig 字典
        ClearConfigDictionary<RichTextMsgReplaceConfig>();
        // 清空 RuleConfig 字典
        ClearConfigDictionary<RuleConfig>();
        // 清空 SkillConfig 字典
        ClearConfigDictionary<SkillConfig>();
        // 清空 PriorBundleConfig 字典
        ClearConfigDictionary<PriorBundleConfig>();
        // 清空 StoreConfig 字典
        ClearConfigDictionary<StoreConfig>();
        // 清空 SuccessConfig 字典
        ClearConfigDictionary<SuccessConfig>();
        // 清空 SysInfoConfig 字典
        ClearConfigDictionary<SysInfoConfig>();
        // 清空 TaskConfig 字典
        ClearConfigDictionary<TaskConfig>();
        // 清空 TitleStarUpConfig 字典
        ClearConfigDictionary<TitleStarUpConfig>();
        // 清空 TreasureCntAwardConfig 字典
        ClearConfigDictionary<TreasureCntAwardConfig>();
        // 清空 TreasureItemLibConfig 字典
        ClearConfigDictionary<TreasureItemLibConfig>();
        // 清空 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
}