少年修仙传客户端基础资源
hch
2024-05-17 0dbb961d8dc9a7fe65021916760c2d9eb8194972
0312 资源不混淆,还原
13个文件已修改
2632 ■■■■ 已修改文件
Assets/Editor/AssetBundleBrowser/AssetBundleBuildTab.cs 2275 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/ScriptTemplate/ConfigDataTemplate.txt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/AssetBundleBuildExtersion.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/AssetsVersionCmpMaker.cs 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/AssetsVersionMaker.cs 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/BytesVersionMaker.cs 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/ClientPackage.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/InGameDownTestWindow.cs 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/Tool/TableTool.cs 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Launch/AssetVersion.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Launch/InitialFunctionConfig.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Launch/LoadDll.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Launch/ResourcesModel.cs 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Assets/Editor/AssetBundleBrowser/AssetBundleBuildTab.cs
@@ -1,938 +1,931 @@
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine.AssetBundles.AssetBundleDataSource;
using Assets.Editor.Tool;
using HybridCLR.Editor.Commands;
using HybridCLR.Editor.Settings;
//using Mono.Cecil;
using DG.Tweening.Plugins.Core.PathCore;
using System;
using Path = System.IO.Path;
using HybridCLR.Editor.HotUpdate;
using HybridCLR.Editor;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine.AssetBundles.AssetBundleDataSource;
using Assets.Editor.Tool;
using HybridCLR.Editor.Commands;
using HybridCLR.Editor.Settings;
//using Mono.Cecil;
using DG.Tweening.Plugins.Core.PathCore;
using System;
using Path = System.IO.Path;
using HybridCLR.Editor.HotUpdate;
using HybridCLR.Editor;
using System.Text;
namespace UnityEngine.AssetBundles
{
    [System.Serializable]
    public class AssetBundleBuildTab
    {
        const string k_BuildPrefPrefix = "ABBBuild:";
        // gui vars
        //[SerializeField]
        //private ValidBuildTarget m_BuildTarget = ValidBuildTarget.StandaloneWindows;
        //[SerializeField]
        //private CompressOptions m_Compression = CompressOptions.StandardCompression;
        //private string m_OutputPath = string.Empty;
        //[SerializeField]
        //private bool m_UseDefaultPath = true;
        private string m_streamingPath
        {
            get
            {
                switch (m_UserData.m_BuildTarget)
                {
                    case ValidBuildTarget.Android:
                        return StringUtility.Contact("Assets/StreamingAssets", "/android");
                    case ValidBuildTarget.iOS:
                        return StringUtility.Contact("Assets/StreamingAssets", "/ios");
                    case ValidBuildTarget.StandaloneWindows:
                    case ValidBuildTarget.StandaloneWindows64:
                        return StringUtility.Contact("Assets/StreamingAssets", "/standalone");
                    default:
                        return "Assets/StreamingAssets";
                }
            }
        }
        [SerializeField]
        private bool m_AdvancedSettings;
        [SerializeField]
        private Vector2 m_ScrollPosition;
        class ToggleData
        {
            public ToggleData(bool s,
                string title,
                string tooltip,
                List<string> onToggles,
                BuildAssetBundleOptions opt = BuildAssetBundleOptions.None)
            {
                if (onToggles.Contains(title))
                    state = true;
                else
                    state = s;
                content = new GUIContent(title, tooltip);
                option = opt;
            }
            //public string prefsKey
            //{ get { return k_BuildPrefPrefix + content.text; } }
            public bool state;
            public GUIContent content;
            public BuildAssetBundleOptions option;
        }
        [SerializeField]
        private BuildTabData m_UserData;
        [SerializeField] int m_Version;
        public string ApkOutputPath
        {
            get { return LocalSave.GetString("APKOutPutPath"); }
            set { LocalSave.SetString("APKOutPutPath", value); }
        }
        public string publishers
        {
            get { return LocalSave.GetString("APKPublishers"); }
            set { LocalSave.SetString("APKPublishers", value); }
        }
        List<ToggleData> m_ToggleData;
        ToggleData m_ForceRebuild;
        ToggleData m_CopyToStreaming;
        GUIContent m_TargetContent;
        GUIContent m_CompressionContent;
        public enum CompressOptions
        {
            Uncompressed = 0,
            StandardCompression,
            ChunkBasedCompression,
        }
        GUIContent[] m_CompressionOptions =
        {
            new GUIContent("No Compression"),
            new GUIContent("Standard Compression (LZMA)"),
            new GUIContent("Chunk Based Compression (LZ4)")
        };
        int[] m_CompressionValues = { 0, 1, 2 };
        int rechargeSkin = 1;
        string createRoleLevel = "001";
        public AssetBundleBuildTab()
        {
            m_AdvancedSettings = false;
            m_UserData = new BuildTabData();
            m_UserData.m_OnToggles = new List<string>();
            m_UserData.m_UseDefaultPath = true;
        }
        public void OnDisable()
        {
            var dataPath = System.IO.Path.GetFullPath(".");
            dataPath = dataPath.Replace("\\", "/");
            dataPath += "/Library/AssetBundleBrowserBuild.dat";
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Create(dataPath);
            bf.Serialize(file, m_UserData);
            file.Close();
        }
        public void OnEnable(Rect pos, EditorWindow parent)
        {
            //LoadData...
            var dataPath = System.IO.Path.GetFullPath(".");
            dataPath = dataPath.Replace("\\", "/");
            dataPath += "/Library/AssetBundleBrowserBuild.dat";
            if (File.Exists(dataPath))
            {
                BinaryFormatter bf = new BinaryFormatter();
                FileStream file = File.Open(dataPath, FileMode.Open);
                var data = bf.Deserialize(file) as BuildTabData;
                if (data != null)
                    m_UserData = data;
                file.Close();
            }
            m_ToggleData = new List<ToggleData>();
            m_ToggleData.Add(new ToggleData(
                false,
                "Exclude Type Information",
                "不包含类型信息。发布web平台时,不能使用该选项。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.DisableWriteTypeTree));
            m_ToggleData.Add(new ToggleData(
                false,
                "Force Rebuild",
                "强制重新build所有ab包。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.ForceRebuildAssetBundle));
            m_ToggleData.Add(new ToggleData(
                false,
                "Ignore Type Tree Changes",
                "忽略typetree的变化,不能与DisableWriteTypeTree同时使用。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.IgnoreTypeTreeChanges));
            m_ToggleData.Add(new ToggleData(
                false,
                "Append Hash",
                "附加hash到assetbundle名字中。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.AppendHashToAssetBundleName));
            m_ToggleData.Add(new ToggleData(
                false,
                "Strict Mode",
                "使用严格模式build ab, 有任何非致命的error都不会build成功。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.StrictMode));
            m_ToggleData.Add(new ToggleData(
                false,
                "Dry Run Build",
                "Do a dry run build.",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.DryRunBuild));
            m_ForceRebuild = new ToggleData(
                false,
                "Rebuild",
                "选中后会清空所有旧的资源,全部重新打包(建议测试时不勾选可加快打包速度)",
                m_UserData.m_OnToggles);
            m_CopyToStreaming = new ToggleData(
                false,
                "Copy to StreamingAssets",
                "资源打包完成后,会将所有资源拷贝至:" + m_streamingPath + " for use in stand-alone player.",
                m_UserData.m_OnToggles);
            m_TargetContent = new GUIContent("Build Target", "Choose target platform to build for.");
            m_CompressionContent = new GUIContent("Compression", "Choose no compress, standard (LZMA), or chunk based (LZ4)");
            if (m_UserData.m_UseDefaultPath)
            {
                ResetPathToDefault();
            }
        }
        public void OnGUI(Rect pos)
        {
            m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition);
            bool newState = false;
            var centeredStyle = GUI.skin.GetStyle("Label");
            centeredStyle.alignment = TextAnchor.UpperCenter;
            GUILayout.Label(new GUIContent("Example build setup"), centeredStyle);
            //basic options
            EditorGUILayout.Space();
            GUILayout.BeginVertical();
            // build target
            using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildTarget))
            {
                ValidBuildTarget tgt = (ValidBuildTarget)EditorGUILayout.EnumPopup(m_TargetContent, m_UserData.m_BuildTarget);
                if (tgt != m_UserData.m_BuildTarget)
                {
                    m_UserData.m_BuildTarget = tgt;
                    if (m_UserData.m_UseDefaultPath)
                    {
                        m_UserData.m_OutputPath = "AssetBundles/";
                        m_UserData.m_OutputPath += m_UserData.m_BuildTarget.ToString();
                        //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
                    }
                }
            }
            ////output path
            using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildOutputDirectory))
            {
                EditorGUILayout.Space();
                GUILayout.BeginHorizontal();
                var newPath = EditorGUILayout.TextField("Output Path", m_UserData.m_OutputPath);
                if ((newPath != m_UserData.m_OutputPath) &&
                     (newPath != string.Empty))
                {
                    m_UserData.m_UseDefaultPath = false;
                    m_UserData.m_OutputPath = newPath;
                    //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
                }
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
                    BrowseForFolder();
                if (GUILayout.Button("Reset", GUILayout.MaxWidth(75f)))
                    ResetPathToDefault();
                //if (string.IsNullOrEmpty(m_OutputPath))
                //    m_OutputPath = EditorUserBuildSettings.GetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath");
                GUILayout.EndHorizontal();
                EditorGUILayout.Space();
                newState = GUILayout.Toggle(
                    m_ForceRebuild.state,
                    m_ForceRebuild.content);
                if (newState != m_ForceRebuild.state)
                {
                    if (newState)
                        m_UserData.m_OnToggles.Add(m_ForceRebuild.content.text);
                    else
                        m_UserData.m_OnToggles.Remove(m_ForceRebuild.content.text);
                    m_ForceRebuild.state = newState;
                }
                newState = GUILayout.Toggle(
                    m_CopyToStreaming.state,
                    m_CopyToStreaming.content);
                if (newState != m_CopyToStreaming.state)
                {
                    if (newState)
                        m_UserData.m_OnToggles.Add(m_CopyToStreaming.content.text);
                    else
                        m_UserData.m_OnToggles.Remove(m_CopyToStreaming.content.text);
                    m_CopyToStreaming.state = newState;
                }
            }
            // advanced options
            using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildOptions))
            {
                EditorGUILayout.Space();
                m_AdvancedSettings = EditorGUILayout.Foldout(m_AdvancedSettings, "Advanced Settings");
                if (m_AdvancedSettings)
                {
                    var indent = EditorGUI.indentLevel;
                    EditorGUI.indentLevel = 1;
                    CompressOptions cmp = (CompressOptions)EditorGUILayout.IntPopup(
                        m_CompressionContent,
                        (int)m_UserData.m_Compression,
                        m_CompressionOptions,
                        m_CompressionValues);
                    if (cmp != m_UserData.m_Compression)
                    {
                        m_UserData.m_Compression = cmp;
                    }
                    foreach (var tog in m_ToggleData)
                    {
                        newState = EditorGUILayout.ToggleLeft(
                            tog.content,
                            tog.state);
                        if (newState != tog.state)
                        {
                            if (newState)
                                m_UserData.m_OnToggles.Add(tog.content.text);
                            else
                                m_UserData.m_OnToggles.Remove(tog.content.text);
                            tog.state = newState;
                        }
                    }
                    EditorGUILayout.Space();
                    EditorGUI.indentLevel = indent;
                }
            }
            if (GUILayout.Button("HybridclrBuild(不能热更)"))
            {
                EditorApplication.delayCall += ExcuteBuildHybridclrBuild;
            }
            // build.
            EditorGUILayout.Space();
            if (GUILayout.Button("Build All Assets"))
            {
                EditorApplication.delayCall += ExecuteBuildAll;
            }
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Config"))
            {
                EditorApplication.delayCall += ExcuteBuildConfig;
            }
            if (GUILayout.Button("UI"))
            {
                EditorApplication.delayCall += ExcuteBuildUI;
            }
            if (GUILayout.Button("BuiltIn"))
            {
                EditorApplication.delayCall += ExcuteBuildBuiltIn;
            }
            if (GUILayout.Button("Audio"))
            {
                EditorApplication.delayCall += ExcuteBuildAudio;
            }
            if (GUILayout.Button("Video"))
            {
                EditorApplication.delayCall += ExcuteBuildVideo;
            }
            if (GUILayout.Button("Levels"))
            {
                EditorApplication.delayCall += ExcuteBuildLevels;
            }
            if (GUILayout.Button("MobEffectShader"))
            {
                EditorApplication.delayCall += ExcuteBuildMobEffectShader;
namespace UnityEngine.AssetBundles
{
    [System.Serializable]
    public class AssetBundleBuildTab
    {
        const string k_BuildPrefPrefix = "ABBBuild:";
        // gui vars
        //[SerializeField]
        //private ValidBuildTarget m_BuildTarget = ValidBuildTarget.StandaloneWindows;
        //[SerializeField]
        //private CompressOptions m_Compression = CompressOptions.StandardCompression;
        //private string m_OutputPath = string.Empty;
        //[SerializeField]
        //private bool m_UseDefaultPath = true;
        private string m_streamingPath
        {
            get
            {
                switch (m_UserData.m_BuildTarget)
                {
                    case ValidBuildTarget.Android:
                        return StringUtility.Contact("Assets/StreamingAssets", "/android");
                    case ValidBuildTarget.iOS:
                        return StringUtility.Contact("Assets/StreamingAssets", "/ios");
                    case ValidBuildTarget.StandaloneWindows:
                    case ValidBuildTarget.StandaloneWindows64:
                        return StringUtility.Contact("Assets/StreamingAssets", "/standalone");
                    default:
                        return "Assets/StreamingAssets";
                }
            }
        }
        [SerializeField]
        private bool m_AdvancedSettings;
        [SerializeField]
        private Vector2 m_ScrollPosition;
        class ToggleData
        {
            public ToggleData(bool s,
                string title,
                string tooltip,
                List<string> onToggles,
                BuildAssetBundleOptions opt = BuildAssetBundleOptions.None)
            {
                if (onToggles.Contains(title))
                    state = true;
                else
                    state = s;
                content = new GUIContent(title, tooltip);
                option = opt;
            }
            //public string prefsKey
            //{ get { return k_BuildPrefPrefix + content.text; } }
            public bool state;
            public GUIContent content;
            public BuildAssetBundleOptions option;
        }
        [SerializeField]
        private BuildTabData m_UserData;
        [SerializeField] int m_Version;
        public string ApkOutputPath
        {
            get { return LocalSave.GetString("APKOutPutPath"); }
            set { LocalSave.SetString("APKOutPutPath", value); }
        }
        public string publishers
        {
            get { return LocalSave.GetString("APKPublishers"); }
            set { LocalSave.SetString("APKPublishers", value); }
        }
        List<ToggleData> m_ToggleData;
        ToggleData m_ForceRebuild;
        ToggleData m_CopyToStreaming;
        GUIContent m_TargetContent;
        GUIContent m_CompressionContent;
        public enum CompressOptions
        {
            Uncompressed = 0,
            StandardCompression,
            ChunkBasedCompression,
        }
        GUIContent[] m_CompressionOptions =
        {
            new GUIContent("No Compression"),
            new GUIContent("Standard Compression (LZMA)"),
            new GUIContent("Chunk Based Compression (LZ4)")
        };
        int[] m_CompressionValues = { 0, 1, 2 };
        int rechargeSkin = 1;
        string createRoleLevel = "001";
        public AssetBundleBuildTab()
        {
            m_AdvancedSettings = false;
            m_UserData = new BuildTabData();
            m_UserData.m_OnToggles = new List<string>();
            m_UserData.m_UseDefaultPath = true;
        }
        public void OnDisable()
        {
            var dataPath = System.IO.Path.GetFullPath(".");
            dataPath = dataPath.Replace("\\", "/");
            dataPath += "/Library/AssetBundleBrowserBuild.dat";
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Create(dataPath);
            bf.Serialize(file, m_UserData);
            file.Close();
        }
        public void OnEnable(Rect pos, EditorWindow parent)
        {
            //LoadData...
            var dataPath = System.IO.Path.GetFullPath(".");
            dataPath = dataPath.Replace("\\", "/");
            dataPath += "/Library/AssetBundleBrowserBuild.dat";
            if (File.Exists(dataPath))
            {
                BinaryFormatter bf = new BinaryFormatter();
                FileStream file = File.Open(dataPath, FileMode.Open);
                var data = bf.Deserialize(file) as BuildTabData;
                if (data != null)
                    m_UserData = data;
                file.Close();
            }
            if (GUILayout.Button("HybridclrUpdate"))
            {
                EditorApplication.delayCall += ExcuteBuildHybridclrUpdate;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Make VersionFile"))
            {
                EditorApplication.delayCall += MakeAssetsVersionFile;
            }
            if (GUILayout.Button("Copy to StreamingAssets"))
            {
                EditorApplication.delayCall += CopyToStreamingAssets;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
#if UNITY_ANDROID
            GUILayout.BeginHorizontal();
            EditorGUILayout.TextField("Apk Output Path", ApkOutputPath);
            if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
            {
                BrowseForApkOutput();
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
#endif
#if UNITY_STANDALONE
            GUILayout.BeginHorizontal();
            EditorGUILayout.TextField("EXE Output Path", ApkOutputPath);
            if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
            {
                BrowseForApkOutput();
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
#endif
            GUILayout.BeginHorizontal();
            EditorGUILayout.TextField("SDK Project Path", ClientPackage.SDK_PLUGIN_PROJECT);
            if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
            {
                BrowseForSDKProject();
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
#if UNITY_IOS
            ClientPackage.auditOutTime = EditorGUILayout.TextField("AppStore OutTime", ClientPackage.auditOutTime, GUILayout.Height(20));
            EditorGUILayout.Space();
#endif
            GUILayout.BeginHorizontal();
            ClientPackage.AssetPrior = EditorGUILayout.IntField("AssetPrior", ClientPackage.AssetPrior, GUILayout.Height(50), GUILayout.Width(250));
            publishers = EditorGUILayout.TextField("Publishers", publishers, GUILayout.Height(50));
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
            GUILayout.BeginHorizontal();
            ClientPackage.includeConfig = EditorGUILayout.Toggle("Include Config ", ClientPackage.includeConfig, GUILayout.Width(250));
            ClientPackage.includeUI = EditorGUILayout.Toggle("Include UI ", ClientPackage.includeUI, GUILayout.Width(250));
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
            GUILayout.BeginHorizontal();
            ClientPackage.obfuscatorEnabled = EditorGUILayout.Toggle("Obfuscator Enable ", ClientPackage.obfuscatorEnabled, GUILayout.Width(250));
#if UNITY_STANDALONE
            if (GUILayout.Button("EXE"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageStandalone;
            }
#elif UNITY_ANDROID
            if (GUILayout.Button("APK"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageApk;
            }
#elif UNITY_IOS
            if (GUILayout.Button("IPA_Append "))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageIpaAppend;
            }
#endif
#if UNITY_STANDALONE
            if (GUILayout.Button("EXE Development "))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageStandaloneDevelopment;
            }
#elif UNITY_ANDROID
            if (GUILayout.Button("APK Development"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageDevelopApk;
            }
#elif UNITY_IOS
            if (GUILayout.Button("IPA_Replace"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageIpaReplace;
            }
#endif
            GUILayout.EndHorizontal();
            GUILayout.Space(20);
            if (GUILayout.Button("SwitchVersionConfig"))
            {
                EditorApplication.delayCall += ExecuteSwitchVersionConfig;
            }
            GUILayout.Space(20);
            GUILayout.BeginHorizontal();
            rechargeSkin = EditorGUILayout.IntField("Recharge Skin", rechargeSkin, GUILayout.Width(250));
            if (GUILayout.Button("Switch"))
            {
                UpdateSpriteSetting.SetRechargeSkin(rechargeSkin);
                AssetDatabase.Refresh();
                UpdateSpritePackingSetting.UpdateAllSpritePackingSetting();
            }
            createRoleLevel = EditorGUILayout.TextField("CreateRole Level", createRoleLevel, GUILayout.Width(250));
            if (GUILayout.Button("Switch"))
            {
                UpdateLevelSetting.SetCreateRoleLevel(createRoleLevel);
                AssetDatabase.Refresh();
            }
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }
        private void CopyToStreamingAssets()
        {
            if (Directory.Exists(m_streamingPath))
                Directory.Delete(m_streamingPath, true);
            DirectoryCopy(m_UserData.m_OutputPath, m_streamingPath);
        }
        private void ExecuteBuildAll()
        {
            if (AssetBundleModel.Model.DataSource.CanSpecifyBuildOutputDirectory)
            {
                if (string.IsNullOrEmpty(m_UserData.m_OutputPath))
                {
                    BrowseForFolder();
                }
                if (string.IsNullOrEmpty(m_UserData.m_OutputPath)) //in case they hit "cancel" on the open browser
                {
                    Debug.LogError("AssetBundle Build: No valid output path for build.");
                    return;
                }
                if (m_ForceRebuild.state)
                {
                    try
                    {
                        if (Directory.Exists(m_UserData.m_OutputPath))
                        {
                            Directory.Delete(m_UserData.m_OutputPath, true);
                        }
                        if (m_CopyToStreaming.state)
                        {
                            if (Directory.Exists(m_streamingPath))
                            {
                                Directory.Delete(m_streamingPath, true);
                            }
                        }
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogException(e);
                    }
                }
                if (!Directory.Exists(m_UserData.m_OutputPath))
                {
                    Directory.CreateDirectory(m_UserData.m_OutputPath);
                }
            }
            ExcuteBuildAudio();
            ExcuteBuildVideo();
            ExcuteBuildMobEffectShader();
            ExcuteBuildConfig();
            ExcuteBuildLevels();
            ExcuteBuildUI();
            ExcuteBuildBuiltIn();
            ExcuteBuildHybridclrUpdate();
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            MakeAssetsVersionFile();
            if (m_CopyToStreaming.state)
            {
                if (Directory.Exists(m_streamingPath))
                    Directory.Delete(m_streamingPath, true);
                DirectoryCopy(m_UserData.m_OutputPath, m_streamingPath);
            }
        }
        private void ExcuteBuildAsset(string _category, bool uncompressed = false)
        {
            BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
            if (AssetBundleModel.Model.DataSource.CanSpecifyBuildOptions)
            {
                if (m_UserData.m_Compression == CompressOptions.Uncompressed || uncompressed)
                {
                    opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
                }
                else if (m_UserData.m_Compression == CompressOptions.ChunkBasedCompression)
                {
                    opt |= BuildAssetBundleOptions.ChunkBasedCompression;
                }
                opt |= BuildAssetBundleOptions.DeterministicAssetBundle;
                foreach (var tog in m_ToggleData)
                {
                    if (tog.state)
                    {
                        opt |= tog.option;
                    }
                }
            }
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            AssetBundleBuildExtersion.Build(outputPath, _category, opt, (BuildTarget)m_UserData.m_BuildTarget, m_ForceRebuild.state);
        }
        private void ExcuteBuildBuiltIn()
        {
            BuiltInResourceSetting.SetLaunchBackGround(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget);
            BuiltInResourceSetting.SetLoginBackGround(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget);
            BuiltInResourceSetting.SetLoginLogo(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget);
            UpdateBuiltInSetting.SetBuiltinAssetBundleName();
            ExcuteBuildAsset("builtin");
        }
        private void ExcuteBuildAudio()
        {
            UpdateAudioSetting.SetAllAudioAssetBundleName();
            ExcuteBuildAsset("audio");
        }
        private void ExcuteBuildVideo()
        {
            UpdateVideoSetting.SetAllVideoAssetBundleName();
            ExcuteBuildAsset("video");
        }
        private void ExcuteBuildMobEffectShader()
        {
            UpdateEffectPrefabSetting.SetAllEffectPrefabAssetBundleName();
            UpdateMobSetting.SetAllMobAssetBundleName();
            UpdateShaderSetting.SetAllShaderAssetBundleName();
            ExcuteBuildAsset("mobeffectshader");
        }
        private void ExcuteBuildConfig()
        {
            UpdateScriptableObjectsSetting.SetAllScriptableObjectAssetBundleName();
            ExcuteBuildAsset("config");
            TableTool.CopyConfigsToOutPutPath(StringUtility.Contact(m_UserData.m_OutputPath, "/config"));
        }
        //发包时获取热更dll和裁剪AOT
        private void ExcuteBuildHybridclrBuild()
        {
            //重新生成热更dll和裁剪AOT
            PrebuildCommand.GenerateAll();
            // 输出到AssetBundles目录
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            outputPath = StringUtility.Contact(outputPath, "/daimazijie");
            if (Directory.Exists(outputPath))
                Directory.Delete(outputPath, true);
            //复制新生成的AOT dll到指定路径
            CopyAOTDataDll(outputPath);
            //复制热更dll到指定路径
            CopyHotUpdateDll(outputPath);
            AssetDatabase.Refresh();
        }
        //热更新时获取热更dll
        private void ExcuteBuildHybridclrUpdate()
        {
            //生成热更dll
            CompileDllCommand.CompileDll(EditorUserBuildSettings.activeBuildTarget);
            //判断当前的dll有没有使用了被裁剪的aot dll
            if (IsAccessMissingMetadata())
            {
                DebugEx.LogError("当前热更代码使用了被裁剪的aot dll,请使用HybridclrBuild重新生成,重新出包");
                return;
            }
            // 输出到AssetBundles目录
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            outputPath = StringUtility.Contact(outputPath, "/daimazijie");
            CopyHotUpdateDll(outputPath);
            MakeBytesVersionFile();
            AssetDatabase.Refresh();
        }
        private void MakeBytesVersionFile()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(m_UserData.m_OutputPath, "/daimazijie"), fileInfos);
            BytesVersionMaker.WriteAssetsVersionFile(Path.Combine(Directory.GetParent(Application.dataPath).FullName, m_UserData.m_OutputPath), fileInfos);
            Debug.Log("热更新代码更新完毕,生成md5文件");
        }
        //复制裁剪AOT到指定目录
        void CopyAOTDataDll(string outputPath)
        {
            //项目根目录
            string rootDir = Directory.GetParent(Application.dataPath).FullName.Replace(@"\", @"/");
            //当前构建的平台名称
            string platformName = "/" + EditorUserBuildSettings.activeBuildTarget + "/";
            //上次出包时使用的AOT所在路径
            string checkAotDir = rootDir + "/HybridCLRData/CheckAssembliesPostIl2CppStrip" + platformName;
            //HybridCLR Settings面板上设置的裁减后AOT dll输出根目录
            string strippedAOTDllOutputRootDir = "/" + HybridCLRSettings.Instance.strippedAOTDllOutputRootDir;
            //重新生成的AOT所在路径
            string aotDir = StringUtility.Contact(rootDir, strippedAOTDllOutputRootDir, platformName);
            if (Directory.Exists(checkAotDir))
            {
                Directory.Delete(checkAotDir, true);
                Directory.CreateDirectory(checkAotDir);
            }
            //复制一份出包时使用的AOT
            CopyDirectoryToPath(aotDir, checkAotDir);
            for (int i = 0; i < AOTGenericReferences.PatchedAOTAssemblyList.Count; i++)
            {
                string dllFile = StringUtility.Contact(aotDir, AOTGenericReferences.PatchedAOTAssemblyList[i]);
                var outDllFile = outputPath + "/" + AssetVersionUtility.EncodeFileName(AOTGenericReferences.PatchedAOTAssemblyList[i]) + ".bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogErrorFormat("错误:{0} 不存在", dllFile);
                    return;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                //File.Copy(dllFile, outDllFile, true);
                ChangeBytes(dllFile, outDllFile);
            }
        }
        //复制热更dll到指定目录
        void CopyHotUpdateDll(string outputPath)
        {
            //项目根目录
            string rootDir = Directory.GetParent(Application.dataPath).FullName.Replace(@"\", @"/");
            //当前构建的平台名称
            string platformName = "/" + EditorUserBuildSettings.activeBuildTarget + "/";
            //HybridCLR Settings面板上设置的热更新dll编译输出根目录
            string hotUpdateDllCompileOutputRootDir = "/" + HybridCLRSettings.Instance.hotUpdateDllCompileOutputRootDir;
            //热更DLL生成目录
            string hotDllDir = StringUtility.Contact(rootDir, hotUpdateDllCompileOutputRootDir, platformName);
            //HybridCLR的Settings面板上设置的热更新Assembly Definitions 资源
            var assemblyDefinitionAsset = HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions;
            for (int i = 0; i < assemblyDefinitionAsset.Length; i++)
            {
                string assemblyPath = AssetDatabase.GetAssetPath(assemblyDefinitionAsset[i]);
                string assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
                string dllFile = StringUtility.Contact(hotDllDir, assemblyName, ".dll");
                var outDllFile = outputPath + "/" + assemblyName + ".dll.bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogErrorFormat("错误:{0} 不存在", dllFile);
                    return;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                //File.Copy(dllFile, outDllFile, true);
                ChangeBytes(dllFile, outDllFile);
            }
            //HybridCLR的Settings面板上设置的要热更的DLL资源
            string[] hotUpdateAssemblies = HybridCLRSettings.Instance.hotUpdateAssemblies;
            for (int i = 0; i < hotUpdateAssemblies.Length; i++)
            {
                string dllFile = StringUtility.Contact(hotDllDir, hotUpdateAssemblies[i], ".dll");
                var outDllFile = outputPath + "/" + hotUpdateAssemblies[i] + ".dll.bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogErrorFormat("错误:{0} 不存在", dllFile);
                    return;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                //File.Copy(dllFile, outDllFile, true);
                ChangeBytes(dllFile, outDllFile);
            }
            //HybridCLR的Settings面板上设置的预留的热更新dlls
            string[] preserveHotUpdateAssemblies = HybridCLRSettings.Instance.preserveHotUpdateAssemblies;
            for (int i = 0; i < preserveHotUpdateAssemblies.Length; i++)
            {
                string dllFile = StringUtility.Contact(hotDllDir, preserveHotUpdateAssemblies[i], ".dll");
                var outDllFile = outputPath + "/" + preserveHotUpdateAssemblies[i] + ".dll.bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogWarningFormat("警告:预留的热更新dll: {0} 不存在", dllFile);
                    continue;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                //File.Copy(dllFile, outDllFile, true);
                ChangeBytes(dllFile, outDllFile);
            }
        }
        //检查目标文件夹下是否有文件
        bool IsFolderNotEmpty(string dir)
        {
            if (Directory.Exists(dir))
            {
                string[] files = Directory.GetFiles(dir);
                if (files.Length > 0)
                    return true;
            }
            return false;
        }
        //检查热更新代码中是否引用了被裁剪的类型或函数
        bool IsAccessMissingMetadata()
        {
            //项目根目录
            string rootDir = Directory.GetParent(Application.dataPath).FullName.Replace(@"\", @"/");
            //当前构建的平台名称
            BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
            string platformName = "/" + target + "/";
            //上次出包时使用的AOT所在路径
            string checkAotDir = rootDir + "/HybridCLRData/CheckAssembliesPostIl2CppStrip" + platformName;
            //上次打包时保存的AOT所在文件夹不存在或没有dll文件
            if (!IsFolderNotEmpty(checkAotDir))
                return true;
            var checker = new MissingMetadataChecker(checkAotDir, new List<string>());
            string hotUpdateDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
            for (int i = 0; i < SettingsUtil.HotUpdateAssemblyFilesExcludePreserved.Count; i++)
            {
                string dllPath = hotUpdateDir + "/" + SettingsUtil.HotUpdateAssemblyFilesExcludePreserved[i];
                bool notAnyMissing = checker.Check(dllPath);
                if (!notAnyMissing)
                {
                    return true;
                }
            }
            return false;
        }
        private void CopyDirectoryToPath(string sourceDir, string destinationDir)
        {
            // 如果目标路径不存在,则创建它
            if (!Directory.Exists(destinationDir))
                Directory.CreateDirectory(destinationDir);
            // 获取所有文件并复制
            string[] files = Directory.GetFiles(sourceDir);
            for (int i = 0; i < files.Length; i++)
            {
                string dest = Path.Combine(destinationDir, Path.GetFileName(files[i]));
                File.Copy(files[i], dest, true); // true表示如果目标存在,则覆盖
            }
        }
        private void ExcuteBuildLevels()
        {
            UpdateLevelSetting.SetAllLevelAssetBundleName();
            ExcuteBuildAsset("maps");
        }
        private void ExcuteBuildUI()
        {
            AssetSource.allFromEditor = true;
            //CheckFontSwitch.CheckAndReplaceFontSwitch();
            UpdateUIPrefabSetting.SetAllUIPrefabAssetBundleName();
            UpdateUIWindowSetting.SetAllUIWindowAssetBundleName();
            UpdateSpriteSetting.SetAllSpriteAssetBundleName();
            ExcuteBuildAsset("ui");
        }
        private void SetAssetsVersion()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos);
            for (int i = 0; i < fileInfos.Count; i++)
            {
                var fileInfo = fileInfos[i];
                var fullName = FileExtersion.RemoveVersionFromFileFullName(fileInfo.FullName);
                var newFullName = FileExtersion.AddVersionToFileFullName(fullName, m_Version);
                if (fullName != newFullName)
                {
                    File.Copy(fullName, newFullName, true);
                    File.Delete(fullName);
                }
            }
        }
        private void RemoveAssetsVersion()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos);
            for (int i = 0; i < fileInfos.Count; i++)
            {
                var fileInfo = fileInfos[i];
                var fullName = FileExtersion.RemoveVersionFromFileFullName(fileInfo.FullName);
                if (fullName != fileInfo.FullName)
                {
                    File.Copy(fileInfo.FullName, fullName, true);
                    File.Delete(fileInfo.FullName);
                }
            }
        }
        private void MakeAssetsVersionFile()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos);
            AssetsVersionMaker.WriteAssetsVersionFile(Path.Combine(Directory.GetParent(Application.dataPath).FullName, m_UserData.m_OutputPath), fileInfos);
            Debug.Log("AVersion.txt文件完毕");
        }
        void ChangeBytes(string originalDllBytesFilePath, string outDllFile)
            m_ToggleData = new List<ToggleData>();
            m_ToggleData.Add(new ToggleData(
                false,
                "Exclude Type Information",
                "不包含类型信息。发布web平台时,不能使用该选项。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.DisableWriteTypeTree));
            m_ToggleData.Add(new ToggleData(
                false,
                "Force Rebuild",
                "强制重新build所有ab包。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.ForceRebuildAssetBundle));
            m_ToggleData.Add(new ToggleData(
                false,
                "Ignore Type Tree Changes",
                "忽略typetree的变化,不能与DisableWriteTypeTree同时使用。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.IgnoreTypeTreeChanges));
            m_ToggleData.Add(new ToggleData(
                false,
                "Append Hash",
                "附加hash到assetbundle名字中。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.AppendHashToAssetBundleName));
            m_ToggleData.Add(new ToggleData(
                false,
                "Strict Mode",
                "使用严格模式build ab, 有任何非致命的error都不会build成功。",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.StrictMode));
            m_ToggleData.Add(new ToggleData(
                false,
                "Dry Run Build",
                "Do a dry run build.",
                m_UserData.m_OnToggles,
                BuildAssetBundleOptions.DryRunBuild));
            m_ForceRebuild = new ToggleData(
                false,
                "Rebuild",
                "选中后会清空所有旧的资源,全部重新打包(建议测试时不勾选可加快打包速度)",
                m_UserData.m_OnToggles);
            m_CopyToStreaming = new ToggleData(
                false,
                "Copy to StreamingAssets",
                "资源打包完成后,会将所有资源拷贝至:" + m_streamingPath + " for use in stand-alone player.",
                m_UserData.m_OnToggles);
            m_TargetContent = new GUIContent("Build Target", "Choose target platform to build for.");
            m_CompressionContent = new GUIContent("Compression", "Choose no compress, standard (LZMA), or chunk based (LZ4)");
            if (m_UserData.m_UseDefaultPath)
            {
                ResetPathToDefault();
            }
        }
        public void OnGUI(Rect pos)
        {
            string path = StringUtility.Contact(m_UserData.m_OutputPath, "/daimazijie/");
            m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition);
            bool newState = false;
            var centeredStyle = GUI.skin.GetStyle("Label");
            centeredStyle.alignment = TextAnchor.UpperCenter;
            GUILayout.Label(new GUIContent("Example build setup"), centeredStyle);
            //basic options
            EditorGUILayout.Space();
            GUILayout.BeginVertical();
            // build target
            using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildTarget))
            {
                ValidBuildTarget tgt = (ValidBuildTarget)EditorGUILayout.EnumPopup(m_TargetContent, m_UserData.m_BuildTarget);
                if (tgt != m_UserData.m_BuildTarget)
                {
                    m_UserData.m_BuildTarget = tgt;
                    if (m_UserData.m_UseDefaultPath)
                    {
                        m_UserData.m_OutputPath = "AssetBundles/";
                        m_UserData.m_OutputPath += m_UserData.m_BuildTarget.ToString();
                        //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
                    }
                }
            }
            ////output path
            using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildOutputDirectory))
            {
                EditorGUILayout.Space();
                GUILayout.BeginHorizontal();
                var newPath = EditorGUILayout.TextField("Output Path", m_UserData.m_OutputPath);
                if ((newPath != m_UserData.m_OutputPath) &&
                     (newPath != string.Empty))
                {
                    m_UserData.m_UseDefaultPath = false;
                    m_UserData.m_OutputPath = newPath;
                    //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
                }
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
                    BrowseForFolder();
                if (GUILayout.Button("Reset", GUILayout.MaxWidth(75f)))
                    ResetPathToDefault();
                //if (string.IsNullOrEmpty(m_OutputPath))
                //    m_OutputPath = EditorUserBuildSettings.GetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath");
                GUILayout.EndHorizontal();
                EditorGUILayout.Space();
                newState = GUILayout.Toggle(
                    m_ForceRebuild.state,
                    m_ForceRebuild.content);
                if (newState != m_ForceRebuild.state)
                {
                    if (newState)
                        m_UserData.m_OnToggles.Add(m_ForceRebuild.content.text);
                    else
                        m_UserData.m_OnToggles.Remove(m_ForceRebuild.content.text);
                    m_ForceRebuild.state = newState;
                }
                newState = GUILayout.Toggle(
                    m_CopyToStreaming.state,
                    m_CopyToStreaming.content);
                if (newState != m_CopyToStreaming.state)
                {
                    if (newState)
                        m_UserData.m_OnToggles.Add(m_CopyToStreaming.content.text);
                    else
                        m_UserData.m_OnToggles.Remove(m_CopyToStreaming.content.text);
                    m_CopyToStreaming.state = newState;
                }
            }
            // advanced options
            using (new EditorGUI.DisabledScope(!AssetBundleModel.Model.DataSource.CanSpecifyBuildOptions))
            {
                EditorGUILayout.Space();
                m_AdvancedSettings = EditorGUILayout.Foldout(m_AdvancedSettings, "Advanced Settings");
                if (m_AdvancedSettings)
                {
                    var indent = EditorGUI.indentLevel;
                    EditorGUI.indentLevel = 1;
                    CompressOptions cmp = (CompressOptions)EditorGUILayout.IntPopup(
                        m_CompressionContent,
                        (int)m_UserData.m_Compression,
                        m_CompressionOptions,
                        m_CompressionValues);
                    if (cmp != m_UserData.m_Compression)
                    {
                        m_UserData.m_Compression = cmp;
                    }
                    foreach (var tog in m_ToggleData)
                    {
                        newState = EditorGUILayout.ToggleLeft(
                            tog.content,
                            tog.state);
                        if (newState != tog.state)
                        {
                            if (newState)
                                m_UserData.m_OnToggles.Add(tog.content.text);
                            else
                                m_UserData.m_OnToggles.Remove(tog.content.text);
                            tog.state = newState;
                        }
                    }
                    EditorGUILayout.Space();
                    EditorGUI.indentLevel = indent;
                }
            }
            if (GUILayout.Button("HybridclrBuild(不能热更)"))
            {
                EditorApplication.delayCall += ExcuteBuildHybridclrBuild;
            }
            // build.
            EditorGUILayout.Space();
            if (GUILayout.Button("Build All Assets"))
            {
                EditorApplication.delayCall += ExecuteBuildAll;
            }
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Config"))
            {
                EditorApplication.delayCall += ExcuteBuildConfig;
            }
            if (GUILayout.Button("UI"))
            {
                EditorApplication.delayCall += ExcuteBuildUI;
            }
            if (GUILayout.Button("BuiltIn"))
            {
                EditorApplication.delayCall += ExcuteBuildBuiltIn;
            }
            if (GUILayout.Button("Audio"))
            {
                EditorApplication.delayCall += ExcuteBuildAudio;
            }
            if (GUILayout.Button("Video"))
            {
                EditorApplication.delayCall += ExcuteBuildVideo;
            }
            if (GUILayout.Button("Levels"))
            {
                EditorApplication.delayCall += ExcuteBuildLevels;
            }
            if (GUILayout.Button("MobEffectShader"))
            {
                EditorApplication.delayCall += ExcuteBuildMobEffectShader;
            }
            if (GUILayout.Button("HybridclrUpdate"))
            {
                EditorApplication.delayCall += ExcuteBuildHybridclrUpdate;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Make VersionFile"))
            {
                EditorApplication.delayCall += MakeAssetsVersionFile;
            }
            if (GUILayout.Button("Copy to StreamingAssets"))
            {
                EditorApplication.delayCall += CopyToStreamingAssets;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
            EditorGUILayout.Space();
#if UNITY_ANDROID
            GUILayout.BeginHorizontal();
            EditorGUILayout.TextField("Apk Output Path", ApkOutputPath);
            if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
            {
                BrowseForApkOutput();
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
#endif
#if UNITY_STANDALONE
            GUILayout.BeginHorizontal();
            EditorGUILayout.TextField("EXE Output Path", ApkOutputPath);
            if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
            {
                BrowseForApkOutput();
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
#endif
            GUILayout.BeginHorizontal();
            EditorGUILayout.TextField("SDK Project Path", ClientPackage.SDK_PLUGIN_PROJECT);
            if (GUILayout.Button("Browse", GUILayout.MaxWidth(75f)))
            {
                BrowseForSDKProject();
            }
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
#if UNITY_IOS
            ClientPackage.auditOutTime = EditorGUILayout.TextField("AppStore OutTime", ClientPackage.auditOutTime, GUILayout.Height(20));
            EditorGUILayout.Space();
#endif
            GUILayout.BeginHorizontal();
            ClientPackage.AssetPrior = EditorGUILayout.IntField("AssetPrior", ClientPackage.AssetPrior, GUILayout.Height(50), GUILayout.Width(250));
            publishers = EditorGUILayout.TextField("Publishers", publishers, GUILayout.Height(50));
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
            GUILayout.BeginHorizontal();
            ClientPackage.includeConfig = EditorGUILayout.Toggle("Include Config ", ClientPackage.includeConfig, GUILayout.Width(250));
            ClientPackage.includeUI = EditorGUILayout.Toggle("Include UI ", ClientPackage.includeUI, GUILayout.Width(250));
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
            GUILayout.BeginHorizontal();
            ClientPackage.obfuscatorEnabled = EditorGUILayout.Toggle("Obfuscator Enable ", ClientPackage.obfuscatorEnabled, GUILayout.Width(250));
#if UNITY_STANDALONE
            if (GUILayout.Button("EXE"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageStandalone;
            }
#elif UNITY_ANDROID
            if (GUILayout.Button("APK"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageApk;
            }
#elif UNITY_IOS
            if (GUILayout.Button("IPA_Append "))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageIpaAppend;
            }
#endif
#if UNITY_STANDALONE
            if (GUILayout.Button("EXE Development "))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageStandaloneDevelopment;
            }
#elif UNITY_ANDROID
            if (GUILayout.Button("APK Development"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageDevelopApk;
            }
#elif UNITY_IOS
            if (GUILayout.Button("IPA_Replace"))
            {
                EditorApplication.delayCall += ExecuteBuildClientPackageIpaReplace;
            }
#endif
            GUILayout.EndHorizontal();
            GUILayout.Space(20);
            if (GUILayout.Button("SwitchVersionConfig"))
            {
                EditorApplication.delayCall += ExecuteSwitchVersionConfig;
            }
            GUILayout.Space(20);
            GUILayout.BeginHorizontal();
            rechargeSkin = EditorGUILayout.IntField("Recharge Skin", rechargeSkin, GUILayout.Width(250));
            if (GUILayout.Button("Switch"))
            {
                UpdateSpriteSetting.SetRechargeSkin(rechargeSkin);
                AssetDatabase.Refresh();
                UpdateSpritePackingSetting.UpdateAllSpritePackingSetting();
            }
            createRoleLevel = EditorGUILayout.TextField("CreateRole Level", createRoleLevel, GUILayout.Width(250));
            if (GUILayout.Button("Switch"))
            {
                UpdateLevelSetting.SetCreateRoleLevel(createRoleLevel);
                AssetDatabase.Refresh();
            }
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }
        private void CopyToStreamingAssets()
        {
            if (Directory.Exists(m_streamingPath))
                Directory.Delete(m_streamingPath, true);
            DirectoryCopy(m_UserData.m_OutputPath, m_streamingPath);
        }
        private void ExecuteBuildAll()
        {
            if (AssetBundleModel.Model.DataSource.CanSpecifyBuildOutputDirectory)
            {
                if (string.IsNullOrEmpty(m_UserData.m_OutputPath))
                {
                    BrowseForFolder();
                }
                if (string.IsNullOrEmpty(m_UserData.m_OutputPath)) //in case they hit "cancel" on the open browser
                {
                    Debug.LogError("AssetBundle Build: No valid output path for build.");
                    return;
                }
                if (m_ForceRebuild.state)
                {
                    try
                    {
                        if (Directory.Exists(m_UserData.m_OutputPath))
                        {
                            Directory.Delete(m_UserData.m_OutputPath, true);
                        }
                        if (m_CopyToStreaming.state)
                        {
                            if (Directory.Exists(m_streamingPath))
                            {
                                Directory.Delete(m_streamingPath, true);
                            }
                        }
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogException(e);
                    }
                }
                if (!Directory.Exists(m_UserData.m_OutputPath))
                {
                    Directory.CreateDirectory(m_UserData.m_OutputPath);
                }
            }
            ExcuteBuildAudio();
            ExcuteBuildVideo();
            ExcuteBuildMobEffectShader();
            ExcuteBuildConfig();
            ExcuteBuildLevels();
            ExcuteBuildUI();
            ExcuteBuildBuiltIn();
            ExcuteBuildHybridclrUpdate();
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            MakeAssetsVersionFile();
            if (m_CopyToStreaming.state)
            {
                if (Directory.Exists(m_streamingPath))
                    Directory.Delete(m_streamingPath, true);
                DirectoryCopy(m_UserData.m_OutputPath, m_streamingPath);
            }
        }
        private void ExcuteBuildAsset(string _category, bool uncompressed = false)
        {
            BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
            if (AssetBundleModel.Model.DataSource.CanSpecifyBuildOptions)
            {
                if (m_UserData.m_Compression == CompressOptions.Uncompressed || uncompressed)
                {
                    opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
                }
                else if (m_UserData.m_Compression == CompressOptions.ChunkBasedCompression)
                {
                    opt |= BuildAssetBundleOptions.ChunkBasedCompression;
                }
                opt |= BuildAssetBundleOptions.DeterministicAssetBundle;
                foreach (var tog in m_ToggleData)
                {
                    if (tog.state)
                    {
                        opt |= tog.option;
                    }
                }
            }
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            AssetBundleBuildExtersion.Build(outputPath, _category, opt, (BuildTarget)m_UserData.m_BuildTarget, m_ForceRebuild.state);
        }
        private void ExcuteBuildBuiltIn()
        {
            BuiltInResourceSetting.SetLaunchBackGround(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget);
            BuiltInResourceSetting.SetLoginBackGround(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget);
            BuiltInResourceSetting.SetLoginLogo(publishers.Split('|')[0], (BuildTarget)m_UserData.m_BuildTarget);
            UpdateBuiltInSetting.SetBuiltinAssetBundleName();
            ExcuteBuildAsset("builtin");
        }
        private void ExcuteBuildAudio()
        {
            UpdateAudioSetting.SetAllAudioAssetBundleName();
            ExcuteBuildAsset("audio");
        }
        private void ExcuteBuildVideo()
        {
            UpdateVideoSetting.SetAllVideoAssetBundleName();
            ExcuteBuildAsset("video");
        }
        private void ExcuteBuildMobEffectShader()
        {
            UpdateEffectPrefabSetting.SetAllEffectPrefabAssetBundleName();
            UpdateMobSetting.SetAllMobAssetBundleName();
            UpdateShaderSetting.SetAllShaderAssetBundleName();
            ExcuteBuildAsset("mobeffectshader");
        }
        private void ExcuteBuildConfig()
        {
            UpdateScriptableObjectsSetting.SetAllScriptableObjectAssetBundleName();
            ExcuteBuildAsset("config");
            TableTool.CopyConfigsToOutPutPath(StringUtility.Contact(m_UserData.m_OutputPath, "/config"));
        }
        //发包时获取热更dll和裁剪AOT
        private void ExcuteBuildHybridclrBuild()
        {
            //重新生成热更dll和裁剪AOT
            PrebuildCommand.GenerateAll();
            // 输出到AssetBundles目录
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            outputPath = StringUtility.Contact(outputPath, "/logicbytes");
            if (Directory.Exists(outputPath))
                Directory.Delete(outputPath, true);
            //复制新生成的AOT dll到指定路径
            CopyAOTDataDll(outputPath);
            //复制热更dll到指定路径
            CopyHotUpdateDll(outputPath);
            AssetDatabase.Refresh();
        }
        //热更新时获取热更dll
        private void ExcuteBuildHybridclrUpdate()
        {
            //生成热更dll
            CompileDllCommand.CompileDll(EditorUserBuildSettings.activeBuildTarget);
            //判断当前的dll有没有使用了被裁剪的aot dll
            if (IsAccessMissingMetadata())
            {
                DebugEx.LogError("当前热更代码使用了被裁剪的aot dll,请使用HybridclrBuild重新生成,重新出包");
                return;
            }
            // 输出到AssetBundles目录
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            outputPath = StringUtility.Contact(outputPath, "/logicbytes");
            CopyHotUpdateDll(outputPath);
            MakeBytesVersionFile();
            AssetDatabase.Refresh();
        }
        private void MakeBytesVersionFile()
        {
            ChangeBytes();
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(m_UserData.m_OutputPath, "/logicbytes"), fileInfos);
            BytesVersionMaker.WriteAssetsVersionFile(Path.Combine(Directory.GetParent(Application.dataPath).FullName, m_UserData.m_OutputPath), fileInfos);
            Debug.Log("热更新代码更新完毕,生成md5文件");
        }
        //复制裁剪AOT到指定目录
        void CopyAOTDataDll(string outputPath)
        {
            //项目根目录
            string rootDir = Directory.GetParent(Application.dataPath).FullName.Replace(@"\", @"/");
            //当前构建的平台名称
            string platformName = "/" + EditorUserBuildSettings.activeBuildTarget + "/";
            //上次出包时使用的AOT所在路径
            string checkAotDir = rootDir + "/HybridCLRData/CheckAssembliesPostIl2CppStrip" + platformName;
            //HybridCLR Settings面板上设置的裁减后AOT dll输出根目录
            string strippedAOTDllOutputRootDir = "/" + HybridCLRSettings.Instance.strippedAOTDllOutputRootDir;
            //重新生成的AOT所在路径
            string aotDir = StringUtility.Contact(rootDir, strippedAOTDllOutputRootDir, platformName);
            if (Directory.Exists(checkAotDir))
            {
                Directory.Delete(checkAotDir, true);
                Directory.CreateDirectory(checkAotDir);
            }
            //复制一份出包时使用的AOT
            CopyDirectoryToPath(aotDir, checkAotDir);
            for (int i = 0; i < AOTGenericReferences.PatchedAOTAssemblyList.Count; i++)
            {
                string dllFile = StringUtility.Contact(aotDir, AOTGenericReferences.PatchedAOTAssemblyList[i]);
                var outDllFile = outputPath + "/" + AOTGenericReferences.PatchedAOTAssemblyList[i] + ".bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogErrorFormat("错误:{0} 不存在", dllFile);
                    return;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                File.Copy(dllFile, outDllFile, true);
            }
        }
        //复制热更dll到指定目录
        void CopyHotUpdateDll(string outputPath)
        {
            //项目根目录
            string rootDir = Directory.GetParent(Application.dataPath).FullName.Replace(@"\", @"/");
            //当前构建的平台名称
            string platformName = "/" + EditorUserBuildSettings.activeBuildTarget + "/";
            //HybridCLR Settings面板上设置的热更新dll编译输出根目录
            string hotUpdateDllCompileOutputRootDir = "/" + HybridCLRSettings.Instance.hotUpdateDllCompileOutputRootDir;
            //热更DLL生成目录
            string hotDllDir = StringUtility.Contact(rootDir, hotUpdateDllCompileOutputRootDir, platformName);
            //HybridCLR的Settings面板上设置的热更新Assembly Definitions 资源
            var assemblyDefinitionAsset = HybridCLRSettings.Instance.hotUpdateAssemblyDefinitions;
            for (int i = 0; i < assemblyDefinitionAsset.Length; i++)
            {
                string assemblyPath = AssetDatabase.GetAssetPath(assemblyDefinitionAsset[i]);
                string assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
                string dllFile = StringUtility.Contact(hotDllDir, assemblyName, ".dll");
                var outDllFile = outputPath + "/" + assemblyName + ".dll.bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogErrorFormat("错误:{0} 不存在", dllFile);
                    return;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                File.Copy(dllFile, outDllFile, true);
            }
            //HybridCLR的Settings面板上设置的要热更的DLL资源
            string[] hotUpdateAssemblies = HybridCLRSettings.Instance.hotUpdateAssemblies;
            for (int i = 0; i < hotUpdateAssemblies.Length; i++)
            {
                string dllFile = StringUtility.Contact(hotDllDir, hotUpdateAssemblies[i], ".dll");
                var outDllFile = outputPath + "/" + hotUpdateAssemblies[i] + ".dll.bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogErrorFormat("错误:{0} 不存在", dllFile);
                    return;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                File.Copy(dllFile, outDllFile, true);
            }
            //HybridCLR的Settings面板上设置的预留的热更新dlls
            string[] preserveHotUpdateAssemblies = HybridCLRSettings.Instance.preserveHotUpdateAssemblies;
            for (int i = 0; i < preserveHotUpdateAssemblies.Length; i++)
            {
                string dllFile = StringUtility.Contact(hotDllDir, preserveHotUpdateAssemblies[i], ".dll");
                var outDllFile = outputPath + "/" + preserveHotUpdateAssemblies[i] + ".dll.bytes";
                if (!File.Exists(dllFile))
                {
                    DebugEx.LogWarningFormat("警告:预留的热更新dll: {0} 不存在", dllFile);
                    continue;
                }
                FileExtersion.MakeSureDirectory(outDllFile);
                File.Copy(dllFile, outDllFile, true);
            }
        }
        //检查目标文件夹下是否有文件
        bool IsFolderNotEmpty(string dir)
        {
            if (Directory.Exists(dir))
            {
                string[] files = Directory.GetFiles(dir);
                if (files.Length > 0)
                    return true;
            }
            return false;
        }
        //检查热更新代码中是否引用了被裁剪的类型或函数
        bool IsAccessMissingMetadata()
        {
            //项目根目录
            string rootDir = Directory.GetParent(Application.dataPath).FullName.Replace(@"\", @"/");
            //当前构建的平台名称
            BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
            string platformName = "/" + target + "/";
            //上次出包时使用的AOT所在路径
            string checkAotDir = rootDir + "/HybridCLRData/CheckAssembliesPostIl2CppStrip" + platformName;
            //上次打包时保存的AOT所在文件夹不存在或没有dll文件
            if (!IsFolderNotEmpty(checkAotDir))
                return true;
            var checker = new MissingMetadataChecker(checkAotDir, new List<string>());
            string hotUpdateDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
            for (int i = 0; i < SettingsUtil.HotUpdateAssemblyFilesExcludePreserved.Count; i++)
            {
                string dllPath = hotUpdateDir + "/" + SettingsUtil.HotUpdateAssemblyFilesExcludePreserved[i];
                bool notAnyMissing = checker.Check(dllPath);
                if (!notAnyMissing)
                {
                    return true;
                }
            }
            return false;
        }
        private void CopyDirectoryToPath(string sourceDir, string destinationDir)
        {
            // 如果目标路径不存在,则创建它
            if (!Directory.Exists(destinationDir))
                Directory.CreateDirectory(destinationDir);
            // 获取所有文件并复制
            string[] files = Directory.GetFiles(sourceDir);
            for (int i = 0; i < files.Length; i++)
            {
                string dest = Path.Combine(destinationDir, Path.GetFileName(files[i]));
                File.Copy(files[i], dest, true); // true表示如果目标存在,则覆盖
            }
        }
        private void ExcuteBuildLevels()
        {
            UpdateLevelSetting.SetAllLevelAssetBundleName();
            ExcuteBuildAsset("maps");
        }
        private void ExcuteBuildUI()
        {
            AssetSource.allFromEditor = true;
            //CheckFontSwitch.CheckAndReplaceFontSwitch();
            UpdateUIPrefabSetting.SetAllUIPrefabAssetBundleName();
            UpdateUIWindowSetting.SetAllUIWindowAssetBundleName();
            UpdateSpriteSetting.SetAllSpriteAssetBundleName();
            ExcuteBuildAsset("ui");
        }
        private void SetAssetsVersion()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos);
            for (int i = 0; i < fileInfos.Count; i++)
            {
                var fileInfo = fileInfos[i];
                var fullName = FileExtersion.RemoveVersionFromFileFullName(fileInfo.FullName);
                var newFullName = FileExtersion.AddVersionToFileFullName(fullName, m_Version);
                if (fullName != newFullName)
                {
                    File.Copy(fullName, newFullName, true);
                    File.Delete(fullName);
                }
            }
        }
        private void RemoveAssetsVersion()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos);
            for (int i = 0; i < fileInfos.Count; i++)
            {
                var fileInfo = fileInfos[i];
                var fullName = FileExtersion.RemoveVersionFromFileFullName(fileInfo.FullName);
                if (fullName != fileInfo.FullName)
                {
                    File.Copy(fileInfo.FullName, fullName, true);
                    File.Delete(fileInfo.FullName);
                }
            }
        }
        private void MakeAssetsVersionFile()
        {
            var fileInfos = new List<FileInfo>();
            FileExtersion.GetAllDirectoryFileInfos(m_UserData.m_OutputPath, fileInfos);
            AssetsVersionMaker.WriteAssetsVersionFile(Path.Combine(Directory.GetParent(Application.dataPath).FullName, m_UserData.m_OutputPath), fileInfos);
            Debug.Log("生成AssetsVersion.txt文件完毕");
        }
        void ChangeBytes()
        {
            string path = StringUtility.Contact(m_UserData.m_OutputPath, "/logicbytes/");
            // 原始DLL字节内容文件的路径
            string originalDllBytesFilePath = path + "Assembly-CSharp.dll.bytes";
            // 临时文件的路径,用于写入"abc"后再追加原始DLL字节内容  
            string tempFilePath = AssetVersionUtility.EncodeFileName(outDllFile);
            // 如果目标文件存在,则删除它
            if (File.Exists(tempFilePath))
            {
                File.Delete(tempFilePath);
            }
            string tempFilePath = path + "temp_Assembly-CSharp.dll.bytes";
            // 要写入的字符串"abc"  
            string contentToWrite = "cbg";
            string contentToWrite = "abc";
            // 将"abc"转换为字节数组  
            byte[] abcBytes = Encoding.ASCII.GetBytes(contentToWrite);
@@ -949,213 +942,231 @@
                fs.Write(originalDllBytes, 0, originalDllBytes.Length);
            }
            ReplaceFile(tempFilePath, originalDllBytesFilePath);
        }
        public void ReplaceFile(string sourceFile, string targetFile)
        {
            // 确保源文件存在
            if (!File.Exists(sourceFile))
            {
                throw new FileNotFoundException("源文件未找到:" + sourceFile);
            }
            // 如果目标文件存在,则删除它
            if (File.Exists(targetFile))
            {
                File.Delete(targetFile);
            }
            // 将源文件重命名为目标文件
            File.Move(sourceFile, targetFile);
        }
        static int packageIndex
        {
            get { return LocalSave.GetInt("ClientPackageIndex", 1); }
            set { LocalSave.SetInt("ClientPackageIndex", value); }
        }
        private void ExecuteBuildClientPackageIpaAppend()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, false);
        }
        private void ExecuteBuildClientPackageIpaReplace()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, true);
        }
        private void ExecuteBuildClientPackageApk()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, false);
        }
        private void ExecuteBuildClientPackageDevelopApk()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, true, false);
        }
        private void ExecuteBuildClientPackageStandalone()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage_Standalone.Build(new ClientPackage_Standalone.BuildParams()
            {
                assetBundle = outputPath,
                output = ApkOutputPath,
                buildIndex = packageIndex,
                development = false,
                publisher = publishers,
            });
        }
        private void ExecuteBuildClientPackageStandaloneDevelopment()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage_Standalone.Build(new ClientPackage_Standalone.BuildParams()
            {
                assetBundle = outputPath,
                output = ApkOutputPath,
                buildIndex = packageIndex,
                development = true,
                publisher = publishers,
            });
        }
        private void ExecuteSwitchVersionConfig()
        {
            var newVersionConfigPath = StringUtility.Contact("Assets/Resources/ScriptableObject/Config/VersionConfig", ".asset");
            var versionsFilePath = Application.dataPath + Path.DirectorySeparatorChar + "Editor/VersionConfigs/Versions.txt";
            var lines = File.ReadAllLines(versionsFilePath);
            for (int i = 2; i < lines.Length; i++)
            {
                var line = lines[i];
                var lineStrings = line.Split('\t');
                if (lineStrings[0] == publishers)
                {
                    VersionConfig.Get().Read(line);
                    break;
                }
            }
        }
        private static void DirectoryCopy(string sourceDirName, string destDirName, string excludeEx = null)
        {
            // Get the subdirectories for the specified directory.
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);
            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }
            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string temppath = Path.Combine(destDirName, file.Name);
                if (excludeEx == null || file.Extension != excludeEx)
                    file.CopyTo(temppath, false);
            }
            DirectoryInfo[] dirs = dir.GetDirectories();
            foreach (DirectoryInfo subdir in dirs)
            {
                string temppath = Path.Combine(destDirName, subdir.Name);
                DirectoryCopy(subdir.FullName, temppath);
            }
        }
        private void BrowseForFolder()
        {
            m_UserData.m_UseDefaultPath = false;
            var newPath = EditorUtility.OpenFolderPanel("Bundle Folder", m_UserData.m_OutputPath, string.Empty);
            if (!string.IsNullOrEmpty(newPath))
            {
                var gamePath = System.IO.Path.GetFullPath(".");
                gamePath = gamePath.Replace("\\", "/");
                if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length)
                    newPath = newPath.Remove(0, gamePath.Length + 1);
                m_UserData.m_OutputPath = newPath;
                //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
            }
        }
        private void BrowseForApkOutput()
        {
            var newPath = EditorUtility.OpenFolderPanel("Apk Folder", ApkOutputPath, string.Empty);
            if (!string.IsNullOrEmpty(newPath))
            {
                var gamePath = System.IO.Path.GetFullPath(".");
                gamePath = gamePath.Replace("\\", "/");
                if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length)
                    newPath = newPath.Remove(0, gamePath.Length + 1);
                ApkOutputPath = newPath;
            }
        }
        private void BrowseForSDKProject()
        {
            var newPath = EditorUtility.OpenFolderPanel("Apk Folder", ClientPackage.SDK_PLUGIN_PROJECT, string.Empty);
            if (!string.IsNullOrEmpty(newPath))
            {
                var gamePath = System.IO.Path.GetFullPath(".");
                gamePath = gamePath.Replace("\\", "/");
                if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length)
                    newPath = newPath.Remove(0, gamePath.Length + 1);
                ClientPackage.SDK_PLUGIN_PROJECT = newPath;
            }
        }
        private void ResetPathToDefault()
        {
            m_UserData.m_UseDefaultPath = true;
            m_UserData.m_OutputPath = "AssetBundles/";
            m_UserData.m_OutputPath += m_UserData.m_BuildTarget.ToString();
            //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
        }
        //Note: this is the provided BuildTarget enum with some entries removed as they are invalid in the dropdown
        public enum ValidBuildTarget
        {
            //NoTarget = -2,        --doesn't make sense
            //iPhone = -1,          --deprecated
            //BB10 = -1,            --deprecated
            //MetroPlayer = -1,     --deprecated
            StandaloneOSXUniversal = 2,
            StandaloneOSXIntel = 4,
            StandaloneWindows = 5,
            WebPlayer = 6,
            WebPlayerStreamed = 7,
            iOS = 9,
            PS3 = 10,
            XBOX360 = 11,
            Android = 13,
            StandaloneLinux = 17,
            StandaloneWindows64 = 19,
            WebGL = 20,
            WSAPlayer = 21,
            StandaloneLinux64 = 24,
            StandaloneLinuxUniversal = 25,
            WP8Player = 26,
            StandaloneOSXIntel64 = 27,
            BlackBerry = 28,
            Tizen = 29,
            PSP2 = 30,
            PS4 = 31,
            PSM = 32,
            XboxOne = 33,
            SamsungTV = 34,
            N3DS = 35,
            WiiU = 36,
            tvOS = 37,
            Switch = 38
        }
        [System.Serializable]
        public class BuildTabData
        {
            public List<string> m_OnToggles;
            public ValidBuildTarget m_BuildTarget = ValidBuildTarget.StandaloneWindows;
            public CompressOptions m_Compression = CompressOptions.StandardCompression;
            public string m_OutputPath = string.Empty;
            public bool m_UseDefaultPath = true;
        }
    }
        static int packageIndex
        {
            get { return LocalSave.GetInt("ClientPackageIndex", 1); }
            set { LocalSave.SetInt("ClientPackageIndex", value); }
        }
        private void ExecuteBuildClientPackageIpaAppend()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, false);
        }
        private void ExecuteBuildClientPackageIpaReplace()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, true);
        }
        private void ExecuteBuildClientPackageApk()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, false, false);
        }
        private void ExecuteBuildClientPackageDevelopApk()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage.BuildPublishers(ClientPackage.SDK_PLUGIN_PROJECT, outputPath, ApkOutputPath, publishers, packageIndex, true, false);
        }
        private void ExecuteBuildClientPackageStandalone()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage_Standalone.Build(new ClientPackage_Standalone.BuildParams()
            {
                assetBundle = outputPath,
                output = ApkOutputPath,
                buildIndex = packageIndex,
                development = false,
                publisher = publishers,
            });
        }
        private void ExecuteBuildClientPackageStandaloneDevelopment()
        {
            packageIndex++;
            var outputPath = Application.dataPath.Replace("Assets", m_UserData.m_OutputPath);
            ClientPackage_Standalone.Build(new ClientPackage_Standalone.BuildParams()
            {
                assetBundle = outputPath,
                output = ApkOutputPath,
                buildIndex = packageIndex,
                development = true,
                publisher = publishers,
            });
        }
        private void ExecuteSwitchVersionConfig()
        {
            var newVersionConfigPath = StringUtility.Contact("Assets/Resources/ScriptableObject/Config/VersionConfig", ".asset");
            var versionsFilePath = Application.dataPath + Path.DirectorySeparatorChar + "Editor/VersionConfigs/Versions.txt";
            var lines = File.ReadAllLines(versionsFilePath);
            for (int i = 2; i < lines.Length; i++)
            {
                var line = lines[i];
                var lineStrings = line.Split('\t');
                if (lineStrings[0] == publishers)
                {
                    VersionConfig.Get().Read(line);
                    break;
                }
            }
        }
        private static void DirectoryCopy(string sourceDirName, string destDirName, string excludeEx = null)
        {
            // Get the subdirectories for the specified directory.
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);
            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }
            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string temppath = Path.Combine(destDirName, file.Name);
                if (excludeEx == null || file.Extension != excludeEx)
                    file.CopyTo(temppath, false);
            }
            DirectoryInfo[] dirs = dir.GetDirectories();
            foreach (DirectoryInfo subdir in dirs)
            {
                string temppath = Path.Combine(destDirName, subdir.Name);
                DirectoryCopy(subdir.FullName, temppath);
            }
        }
        private void BrowseForFolder()
        {
            m_UserData.m_UseDefaultPath = false;
            var newPath = EditorUtility.OpenFolderPanel("Bundle Folder", m_UserData.m_OutputPath, string.Empty);
            if (!string.IsNullOrEmpty(newPath))
            {
                var gamePath = System.IO.Path.GetFullPath(".");
                gamePath = gamePath.Replace("\\", "/");
                if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length)
                    newPath = newPath.Remove(0, gamePath.Length + 1);
                m_UserData.m_OutputPath = newPath;
                //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
            }
        }
        private void BrowseForApkOutput()
        {
            var newPath = EditorUtility.OpenFolderPanel("Apk Folder", ApkOutputPath, string.Empty);
            if (!string.IsNullOrEmpty(newPath))
            {
                var gamePath = System.IO.Path.GetFullPath(".");
                gamePath = gamePath.Replace("\\", "/");
                if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length)
                    newPath = newPath.Remove(0, gamePath.Length + 1);
                ApkOutputPath = newPath;
            }
        }
        private void BrowseForSDKProject()
        {
            var newPath = EditorUtility.OpenFolderPanel("Apk Folder", ClientPackage.SDK_PLUGIN_PROJECT, string.Empty);
            if (!string.IsNullOrEmpty(newPath))
            {
                var gamePath = System.IO.Path.GetFullPath(".");
                gamePath = gamePath.Replace("\\", "/");
                if (newPath.StartsWith(gamePath) && newPath.Length > gamePath.Length)
                    newPath = newPath.Remove(0, gamePath.Length + 1);
                ClientPackage.SDK_PLUGIN_PROJECT = newPath;
            }
        }
        private void ResetPathToDefault()
        {
            m_UserData.m_UseDefaultPath = true;
            m_UserData.m_OutputPath = "AssetBundles/";
            m_UserData.m_OutputPath += m_UserData.m_BuildTarget.ToString();
            //EditorUserBuildSettings.SetPlatformSettings(EditorUserBuildSettings.activeBuildTarget.ToString(), "AssetBundleOutputPath", m_OutputPath);
        }
        //Note: this is the provided BuildTarget enum with some entries removed as they are invalid in the dropdown
        public enum ValidBuildTarget
        {
            //NoTarget = -2,        --doesn't make sense
            //iPhone = -1,          --deprecated
            //BB10 = -1,            --deprecated
            //MetroPlayer = -1,     --deprecated
            StandaloneOSXUniversal = 2,
            StandaloneOSXIntel = 4,
            StandaloneWindows = 5,
            WebPlayer = 6,
            WebPlayerStreamed = 7,
            iOS = 9,
            PS3 = 10,
            XBOX360 = 11,
            Android = 13,
            StandaloneLinux = 17,
            StandaloneWindows64 = 19,
            WebGL = 20,
            WSAPlayer = 21,
            StandaloneLinux64 = 24,
            StandaloneLinuxUniversal = 25,
            WP8Player = 26,
            StandaloneOSXIntel64 = 27,
            BlackBerry = 28,
            Tizen = 29,
            PSP2 = 30,
            PS4 = 31,
            PSM = 32,
            XboxOne = 33,
            SamsungTV = 34,
            N3DS = 35,
            WiiU = 36,
            tvOS = 37,
            Switch = 38
        }
        [System.Serializable]
        public class BuildTabData
        {
            public List<string> m_OnToggles;
            public ValidBuildTarget m_BuildTarget = ValidBuildTarget.StandaloneWindows;
            public CompressOptions m_Compression = CompressOptions.StandardCompression;
            public string m_OutputPath = string.Empty;
            public bool m_UseDefaultPath = true;
        }
    }
}
Assets/Editor/ScriptTemplate/ConfigDataTemplate.txt
@@ -9,7 +9,6 @@
using System;
using UnityEngine;
using LitJson;
using System.Linq;
public partial class #ClassName#
{
@@ -126,10 +125,6 @@
                try 
                {
                    var line = lines[i];
                    if (!AssetSource.refdataFromEditor)
                    {
                        line = new string(line.Reverse().ToArray());
                    }
                    var index = line.IndexOf("\t");
                    if (index == -1)
                    {
@@ -157,7 +152,6 @@
        }
        else
        {
            bool isEditor = AssetSource.refdataFromEditor;
            ThreadPool.QueueUserWorkItem((object _object) =>
            {
                var lines = File.ReadAllLines(path);
@@ -169,11 +163,7 @@
                {
                    try 
                    {
                        var line = lines[i];
                        if (!isEditor)
                        {
                            line = new string(line.Reverse().ToArray());
                        }
                       var line = lines[i];
                        var index = line.IndexOf("\t");
                        if (index == -1)
                        {
Assets/Editor/Tool/AssetBundleBuildExtersion.cs
@@ -3,8 +3,6 @@
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System.Linq;
public class AssetBundleBuildExtersion
{
@@ -44,17 +42,16 @@
        for (int i = 0; i < targetAssetBundles.Count; i++)
        {
            var assetBundleBuild = new AssetBundleBuild();
            assetBundleBuild.assetBundleName = AssetVersionUtility.EncodeFileName(targetAssetBundles[i]);
            assetBundleBuild.assetBundleName = targetAssetBundles[i];
            assetBundleBuild.assetNames = AssetDatabase.GetAssetPathsFromAssetBundle(targetAssetBundles[i]);
            assets.Add(assetBundleBuild);
        }
        var rootPath = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, category);
        var mainFile = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, GetMainFestFileName(buildTarget));//改名字前
        var mainFileRename = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, AssetVersionUtility.EncodeFileName(category), "_abundle");//改名字后
        var mainFileRename = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, category, "_assetbundle");//改名字后
        var manifest = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, GetMainFestFileName(buildTarget), ".manifest");
        var manifestRename = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, AssetVersionUtility.EncodeFileName(category), "_abundle.manifest");
        var manifestRename = StringUtility.Contact(output, Path.AltDirectorySeparatorChar, category, "_assetbundle.manifest");
        if (rebuild && Directory.Exists(rootPath))
            Directory.Delete(rootPath, true);
Assets/Editor/Tool/AssetsVersionCmpMaker.cs
@@ -1,13 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using UnityEngine;
//放在Resources下 用于对比随包资源是否下载
public class AssetsVersionCmpMaker
{
{
    public static void WriteAssetsVersionFile(string _path, List<FileInfo> _fileInfos)
    {
        var relativePath = string.Empty;
@@ -19,12 +19,12 @@
        for (int i = 0; i < _fileInfos.Count; i++)
        {
            var fileInfo = _fileInfos[i];
            if (fileInfo.Name == "AVersion.txt")
            if (fileInfo.Name == "AssetsVersion.txt")
            {
                continue;
            }
            if (fileInfo.Name == "AVersionCmp.txt")
            if (fileInfo.Name == "AssetsVersionCmp.txt")
            {
                continue;
            }
@@ -38,7 +38,7 @@
            {
                continue;
            }
            if (fileInfo.FullName.Contains("daimazijie"))
            if (fileInfo.FullName.Contains("logicbytes"))
            {
                continue;
            }
@@ -51,13 +51,13 @@
            lines.Add(StringUtility.Contact(relativePath, "\t", extersion, "\t", fileSize, "\t", md5));
        }
        var assetVersionFile = StringUtility.Contact(Application.dataPath, "/Resources/AVersionCmp.txt");
        var assetVersionFile = StringUtility.Contact(Application.dataPath, "/Resources/AssetsVersionCmp.txt");
        if (File.Exists(assetVersionFile))
        {
            File.Delete(assetVersionFile);
        }
        File.WriteAllText(assetVersionFile, string.Join(FileExtersion.lineSplit, lines.ToArray()));
    }
}
    }
}
Assets/Editor/Tool/AssetsVersionMaker.cs
@@ -1,10 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
public class AssetsVersionMaker
{
{
    public static void WriteAssetsVersionFile(string _path, List<FileInfo> _fileInfos)
    {
        var relativePath = string.Empty;
@@ -16,11 +16,11 @@
        for (int i = 0; i < _fileInfos.Count; i++)
        {
            var fileInfo = _fileInfos[i];
            if (fileInfo.Name == "AVersion.txt")
            if (fileInfo.Name == "AssetsVersion.txt")
            {
                continue;
            }
            if (fileInfo.Name == "AVersionCmp.txt")
            if (fileInfo.Name == "AssetsVersionCmp.txt")
            {
                continue;
            }
@@ -29,7 +29,7 @@
            {
                continue;
            }
            if (fileInfo.FullName.Contains("daimazijie"))
            if (fileInfo.FullName.Contains("logicbytes"))
            {
                continue;
            }
@@ -42,13 +42,13 @@
            lines.Add(StringUtility.Contact(relativePath, "\t", extersion, "\t", fileSize, "\t", md5));
        }
        var assetVersionFile = StringUtility.Contact(_path, Path.DirectorySeparatorChar, "AVersion.txt");
        var assetVersionFile = StringUtility.Contact(_path, Path.DirectorySeparatorChar, "AssetsVersion.txt");
        if (File.Exists(assetVersionFile))
        {
            File.Delete(assetVersionFile);
        }
        File.WriteAllText(StringUtility.Contact(_path, Path.DirectorySeparatorChar, "AVersion.txt"), string.Join(FileExtersion.lineSplit, lines.ToArray()));
    }
}
        File.WriteAllText(StringUtility.Contact(_path, Path.DirectorySeparatorChar, "AssetsVersion.txt"), string.Join(FileExtersion.lineSplit, lines.ToArray()));
    }
}
Assets/Editor/Tool/BytesVersionMaker.cs
@@ -1,10 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
public class BytesVersionMaker
{
{
    public static void WriteAssetsVersionFile(string _path, List<FileInfo> _fileInfos)
    {
        var relativePath = string.Empty;
@@ -16,7 +16,7 @@
        for (int i = 0; i < _fileInfos.Count; i++)
        {
            var fileInfo = _fileInfos[i];
            if (fileInfo.Name == "daimazijie.txt")
            if (fileInfo.Name == "logicbytes.txt")
            {
                continue;
            }
@@ -34,13 +34,13 @@
            lines.Add(StringUtility.Contact(relativePath, "\t", extersion, "\t", fileSize, "\t", md5));
        }
        var assetVersionFile = StringUtility.Contact(_path, Path.DirectorySeparatorChar, "daimazijie.txt");
        var assetVersionFile = StringUtility.Contact(_path, Path.DirectorySeparatorChar, "logicbytes.txt");
        if (File.Exists(assetVersionFile))
        {
            File.Delete(assetVersionFile);
        }
        File.WriteAllText(StringUtility.Contact(_path, Path.DirectorySeparatorChar, "daimazijie.txt"), string.Join(FileExtersion.lineSplit, lines.ToArray()));
    }
}
        File.WriteAllText(StringUtility.Contact(_path, Path.DirectorySeparatorChar, "logicbytes.txt"), string.Join(FileExtersion.lineSplit, lines.ToArray()));
    }
}
Assets/Editor/Tool/ClientPackage.cs
@@ -16,26 +16,31 @@
    public static string auditOutTime = string.Empty;
    public static string SDK_PLUGIN_PROJECT {
    public static string SDK_PLUGIN_PROJECT
    {
        get { return LocalSave.GetString("SDK_PROJECT_PATH"); }
        set { LocalSave.SetString("SDK_PROJECT_PATH", value); }
    }
    public static bool obfuscatorEnabled {
    public static bool obfuscatorEnabled
    {
        get { return LocalSave.GetBool("obfuscatorEnabled", false); }
        set { LocalSave.SetBool("obfuscatorEnabled", value); }
    }
    public static bool includeConfig {
    public static bool includeConfig
    {
        get { return LocalSave.GetBool("client_pg_includeConfig", false); }
        set { LocalSave.SetBool("client_pg_includeConfig", value); }
    }
    public static bool includeUI {
    public static bool includeUI
    {
        get { return LocalSave.GetBool("client_pg_includeUI", false); }
        set { LocalSave.SetBool("client_pg_includeUI", value); }
    }
    public static int AssetPrior {
    public static int AssetPrior
    {
        get { return LocalSave.GetInt("HalfAssetPrior", 1); }
        set { LocalSave.SetInt("HalfAssetPrior", value); }
    }
@@ -199,7 +204,7 @@
            {
                var extersion = Path.GetExtension(file.FullName);
                var fileName = Path.GetFileNameWithoutExtension(file.FullName);
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Mob, AssetVersionUtility.DecodeFileName(fileName));
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Mob, fileName);
                if (prior > AssetPrior)
                {
                    excludeFileFullNames.Add(file.FullName);
@@ -212,7 +217,7 @@
            {
                var extersion = Path.GetExtension(file.FullName);
                var fileName = Path.GetFileNameWithoutExtension(file.FullName);
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Scene, AssetVersionUtility.DecodeFileName(fileName));
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Scene, fileName);
                if (prior > AssetPrior)
                {
                    excludeFileFullNames.Add(file.FullName);
@@ -225,7 +230,7 @@
            {
                var extersion = Path.GetExtension(file.FullName);
                var fileName = Path.GetFileNameWithoutExtension(file.FullName);
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Audio, AssetVersionUtility.DecodeFileName(fileName));
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Audio, fileName);
                if (prior > AssetPrior)
                {
                    excludeFileFullNames.Add(file.FullName);
@@ -238,7 +243,7 @@
            {
                var extersion = Path.GetExtension(file.FullName);
                var fileName = Path.GetFileNameWithoutExtension(file.FullName);
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Effect, AssetVersionUtility.DecodeFileName(fileName));
                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Effect, fileName);
                if (prior > AssetPrior)
                {
                    excludeFileFullNames.Add(file.FullName);
@@ -255,7 +260,7 @@
                {
                    var extersion = Path.GetExtension(file.FullName);
                    var fileName = Path.GetFileNameWithoutExtension(file.FullName);
                    var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Video, AssetVersionUtility.DecodeFileName(fileName));
                    var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Video, fileName);
                    if (prior > AssetPrior)
                    {
                        excludeFileFullNames.Add(file.FullName);
@@ -478,7 +483,7 @@
        copySdkFile = StringUtility.Contact(_sdkPath, "/Channel/Android/", versionConfig.appId, "/mainTemplate.gradle");
        File.Copy(copySdkFile, File_mainTemplate);
        DebugEx.LogFormat("Android 清单等文件拷贝成功");
        if (Directory.Exists(channelSdkPath))
@@ -574,13 +579,13 @@
    //该文件在打包时生成 记录随包的所有资源的信息
    //该文件记录的资源在包中肯定存在,所以不用去取指定的资源文件获得FileInfo 计算MD5
    //通过文件和AssetsVersion.txt的文件做比较,来判断是否需要下载资源
    //daimazijie.txt 包含元数据和代码 如果不随包也要处理
    //logicbytes.txt 包含元数据和代码 如果不随包也要处理
    static void MakePackageMD5File()
    {
        var fileInfos = new List<FileInfo>();
        FileExtersion.GetAllDirectoryFileInfos(ResourcesPath.Instance.StreamingAssetPath, fileInfos);
        AssetsVersionCmpMaker.WriteAssetsVersionFile(ResourcesPath.Instance.StreamingAssetPath, fileInfos);
        Debug.Log("--生成AVersionCmp.txt文件完毕");
        Debug.Log("--生成AssetsVersionCmp.txt文件完毕");
    }
    private static void PreBuild(string _publisher, int _buildIndex)
@@ -622,7 +627,7 @@
        SetIconAndSplashImage(versionName);
        //SetCreateRoleAnimation();
        PlayerSettings.companyName = "desj";
        PlayerSettings.companyName = "SW";
        PlayerSettings.productName = newVersionConfig.productName;
        PlayerSettings.applicationIdentifier = newVersionConfig.bundleIdentifier;
        PlayerSettings.defaultInterfaceOrientation = UIOrientation.AutoRotation;
Assets/Editor/Tool/InGameDownTestWindow.cs
@@ -1,14 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class InGameDownTestWindow : EditorWindow
{
    static InGameDownTestWindow window;
    [MenuItem("程序/下载测试")]
{
    static InGameDownTestWindow window;
    [MenuItem("程序/下载测试")]
    public static void Open()
    {
        window = GetWindow(typeof(InGameDownTestWindow), false, "下载测试") as InGameDownTestWindow;
@@ -53,7 +53,7 @@
        EditorGUILayout.Space();
        EditorGUILayout.Space();
        InGameDownTestUtility.isReadVesionEx = EditorGUILayout.Toggle("是否下载热更代码", InGameDownTestUtility.isReadVesionEx);
        EditorGUILayout.TextField("开启下载热更代码,会读取VersionConfigEx.txt 分支需配置正确, 检测daimazijie.txt");
        EditorGUILayout.TextField("开启下载热更代码,会读取VersionConfigEx.txt 分支需配置正确, 检测logicbytes.txt");
    }
}
}
Assets/Editor/Tool/TableTool.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityEditor;
@@ -75,34 +74,34 @@
        }
        GUILayout.EndHorizontal();
//        GUILayout.BeginHorizontal();
//        if (GUILayout.Button("导出IL表"))
//        {
//            isIL = true;
//            ReadAllTxt();
//            GenAllClass();
//            MessageBox.Show("导出IL表成功!");
//            AssetDatabase.Refresh();
//            isIL = false;
//        }
//        GUILayout.EndHorizontal();
        //        GUILayout.BeginHorizontal();
        //        if (GUILayout.Button("导出IL表"))
        //        {
        //            isIL = true;
        //            ReadAllTxt();
        //            GenAllClass();
        //            MessageBox.Show("导出IL表成功!");
        //            AssetDatabase.Refresh();
        //            isIL = false;
        //        }
        //        GUILayout.EndHorizontal();
//        if (GUILayout.Button("选择路径"))
//        {
//#if UNITY_EDITOR
//            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
        //        if (GUILayout.Button("选择路径"))
        //        {
        //#if UNITY_EDITOR
        //            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
//            if (folderBrowserDialog.ShowDialog() == DialogResult.OK || folderBrowserDialog.ShowDialog() == DialogResult.Yes)
//            {
//                _tablePath = folderBrowserDialog.SelectedPath + "\\";
//                PathCache(_tablePath);
//            }
        //            if (folderBrowserDialog.ShowDialog() == DialogResult.OK || folderBrowserDialog.ShowDialog() == DialogResult.Yes)
        //            {
        //                _tablePath = folderBrowserDialog.SelectedPath + "\\";
        //                PathCache(_tablePath);
        //            }
//            folderBrowserDialog.Dispose();
//#endif
        //            folderBrowserDialog.Dispose();
        //#endif
//        }
        //        }
        GUIUtility.ExitGUI();
    }
@@ -212,7 +211,7 @@
        foreach (var file in configFiles)
        {
            var fileInfo = new FileInfo(file.FullName);
            CopyTxtBuild(fileInfo);
            CopyTxt(fileInfo);
        }
    }
@@ -257,43 +256,6 @@
        }
        File.Copy(fileInfo.FullName, filePath);
    }
    private static void CopyTxtBuild(FileInfo fileInfo)
    {
        string fileName = fileInfo.Name.Split('.')[0];
        if (!Directory.Exists(configOutPutPath))
        {
            Directory.CreateDirectory(configOutPutPath);
        }
        string filePath = configOutPutPath + "/" + AssetVersionUtility.EncodeFileName(fileName) + ".txt";
        if (File.Exists(filePath))
        {
            File.Delete(filePath);
        }
        if (fileName.Contains("MapData_"))
        {
            File.Copy(fileInfo.FullName, filePath);
        }
        else
        {
            //按行读取文件,并将每行内容倒序写入新文件
            using (StreamReader sr = new StreamReader(fileInfo.FullName, Encoding.UTF8))
            {
                using (StreamWriter sw = new StreamWriter(filePath, false, Encoding.UTF8))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        sw.WriteLine(new string(line.Reverse().ToArray()));
                    }
                }
            }
        }
    }
    /// <summary>
Assets/Launch/AssetVersion.cs
@@ -5,7 +5,7 @@
{
    public class AssetVersion
    {
        //参考文本 daimazijie/Assembly-CSharp.dll.bytes    .bytes    7360512    71157bfdecb53e8a580432621f3725c7
        //参考文本 logicbytes/Assembly-CSharp.dll.bytes    .bytes    7360512    71157bfdecb53e8a580432621f3725c7
        string m_RelativePath = string.Empty;
        public string relativePath { get { return m_RelativePath; } }
Assets/Launch/InitialFunctionConfig.cs
@@ -7,7 +7,7 @@
using System.IO;
using System;
using UnityEngine;
using System.Linq;
namespace StartAot
{
@@ -122,9 +122,6 @@
                int lineIndex = 0;
                while ((line = reader.ReadLine()) != null)
                {
#if !UNITY_EDITOR
                    line = new string(line.Reverse().ToArray());
#endif
                    lineIndex++;
                    if (lineIndex <= 3)
                    {
Assets/Launch/LoadDll.cs
@@ -58,7 +58,7 @@
        private string GetWebRequestPath(string asset)
        {
            var path = ResourcesModel.Instance.GetAssetFilePath(string.Concat(ResourcesModel.bytesFolderName, asset), false);
            var path = ResourcesModel.Instance.GetAssetFilePath(string.Concat(ResourcesModel.bytesFolderName, asset));
            if (!path.Contains("file:"))
            {
@@ -108,10 +108,15 @@
                {
                    // 特殊处理
                    byte[] assetData;
                    assetData = new byte[www.downloadHandler.data.Length - 3];
                    Array.Copy(www.downloadHandler.data, 3, assetData, 0, assetData.Length);
                    if (asset == "Assembly-CSharp.dll.bytes")
                    {
                        assetData = new byte[www.downloadHandler.data.Length - 3];
                        Array.Copy(www.downloadHandler.data, 3, assetData, 0, assetData.Length);
                    }
                    else
                    {
                        assetData = www.downloadHandler.data;
                    }
                    Debug.Log($"dll:{asset}  size:{assetData.Length}");
                    s_assetDatas[asset] = assetData;
@@ -137,7 +142,7 @@
            HomologousImageMode mode = HomologousImageMode.SuperSet;
            foreach (var aotDllName in AOTMetaAssemblyFiles)
            {
                if (aotDllName == ResourcesModel.Instance.EncodeFileName("Assembly-CSharp.dll.bytes"))
                if (aotDllName == "Assembly-CSharp.dll.bytes")
                    continue;
                // 加载assembly对应的dll,会自动为它hook。一旦aot泛型函数的native函数不存在,用解释器版本代码
                LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(ReadBytesFromStreamingAssets(aotDllName), mode);
@@ -149,7 +154,7 @@
        {
#if !UNITY_EDITOR
        LoadMetadataForAOTAssemblies();
        _hotUpdateAss = Assembly.Load(ReadBytesFromStreamingAssets(ResourcesModel.Instance.EncodeFileName("Assembly-CSharp.dll.bytes")));
        _hotUpdateAss = Assembly.Load(ReadBytesFromStreamingAssets("Assembly-CSharp.dll.bytes"));
        s_assetDatas = null;
#else
            if (_hotUpdateAss == null)
Assets/Launch/ResourcesModel.cs
@@ -5,8 +5,8 @@
using LitJsonForAot;
using System.Collections;
using UnityEngine.Networking;
using System.Linq;
using StartAotSDK;
namespace StartAot
{
@@ -14,7 +14,7 @@
    {
        //不下载时本地安卓测试路径
        public string assetBundlesPath { get; private set; }
        public static string bytesFolderName = "daimazijie/";
        public static string bytesFolderName = "logicbytes/";
        public string StreamingAssetPath { get; private set; }
        public string ExternalStorePath { get; private set; }
@@ -31,7 +31,10 @@
        public int debugBranch { get; private set; }
        public class DebugBranch
        {
            public int branch = -1;
        }
        private int urlIndex = 0;
        private string versionUrl;
@@ -62,7 +65,7 @@
        string assetBytesUrl;
        //从网络获取的资源版本信息
        public Dictionary<string, AssetVersion> assetVersions = new Dictionary<string, AssetVersion>();
        //本地daimazijie文件和 assetVersions 比较是否需要下载
        //本地LogicBytes文件和 assetVersions 比较是否需要下载
        public Dictionary<string, AssetVersion> localAssetVersions = new Dictionary<string, AssetVersion>();
        public static string versionUrlResult { get; private set; }
@@ -204,49 +207,33 @@
            }
        }
        //将文件名倒序,加上_aop后缀
        public string EncodeFileName(string name)
        public class VersionInfo
        {
            name = name.Replace("\\", "/");
            int index = name.LastIndexOf("/");
            string headString;
            if (index >= 0)
            public JsonData notice_flag;
            public JsonData resource_url; //这里只用到这个取下载地址
            public string ResourceAward;
            public int downAsset = 1;
            public string downUrl;
            public int VersionCount;
            public string GetResourcesURL(int _branch)
            {
                int dotLastIndex = name.LastIndexOf(".");
                if (dotLastIndex == -1)
                if (resource_url != null)
                {
                    headString = name.Substring(0, index);
                    name = name.Substring(index + 1);
                    return StringUtility.Contact(headString, "/", new string(name.Reverse().ToArray()), "_aop");
                    return resource_url[_branch.ToString()].ToString();
                }
                else
                {
                    headString = name.Substring(0, index);
                    var ext = name.Substring(dotLastIndex);
                    name = name.Substring(index + 1, dotLastIndex - index - 1);
                    return StringUtility.Contact(headString, "/", new string(name.Reverse().ToArray()), "_aop", ext);
                }
            }
            else
            {
                int dotLastIndex = name.LastIndexOf(".");
                if (dotLastIndex == -1)
                    return StringUtility.Contact(new string(name.Reverse().ToArray()), "_aop");
                else
                {
                    var ext = name.Substring(dotLastIndex);
                    name = name.Substring(0, dotLastIndex);
                    return StringUtility.Contact(new string(name.Reverse().ToArray()), "_aop", ext);
                    return string.Empty;
                }
            }
        }
        public string GetAssetFilePath(string _assetKey, bool reverse = true)
        public string GetAssetFilePath(string _assetKey)
        {
            if (reverse)
                _assetKey = EncodeFileName(_assetKey);
            var path = Path.Combine(ExternalStorePath, _assetKey);
            if (!File.Exists(path))
            {
@@ -347,7 +334,7 @@
        //LogicBytes文件的MD5信息
        public void RequestLogicBytes()
        {
            var remoteURL = string.Concat(versionInfo.GetResourcesURL(VersionConfigEx.Get().branch), fixPath, "/daimazijie.txt");
            var remoteURL = string.Concat(versionInfo.GetResourcesURL(VersionConfigEx.Get().branch), fixPath, "/logicbytes.txt");
            //var localURL = string.Concat(.ExternalStorePath, "/logicbytes.txt");
            assetBytesUrl = remoteURL;
            Debug.Log("http地址:logicbytesUrl  " + assetBytesUrl);
@@ -448,7 +435,7 @@
            if (isPCTestDownLoad || Application.isMobilePlatform)
            {
                //读取的一定是StreamingAssetPath路径
                StartCoroutine(ReadText("daimazijie", (isOK, value) =>
                StartCoroutine(ReadText("logicbytes", (isOK, value) =>
                {
                    if (isOK)
                        InitLocalLogicbytes(value);
@@ -480,38 +467,6 @@
                        Debug.LogError(ex);
                    }
                }
            }
        }
    }
}
namespace StartAotSDK
{
    public class DebugBranch
    {
        public int branch = -1;
    }
    public class VersionInfo
    {
        public JsonData notice_flag;
        public JsonData resource_url; //这里只用到这个取下载地址
        public string ResourceAward;
        public int downAsset = 1;
        public string downUrl;
        public int VersionCount;
        public string GetResourcesURL(int _branch)
        {
            if (resource_url != null)
            {
                return resource_url[_branch.ToString()].ToString();
            }
            else
            {
                return string.Empty;
            }
        }