Пример #1
0
        private static void BuildAssetBundles()
        {
            DLLMgr.Delete("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
            DLLMgr.Delete(Directory.GetParent(Application.dataPath) + "/Assets/XAsset/ScriptableObjects/Rules.asset");
            DLLMgr.Delete(Directory.GetParent(Application.dataPath) + "/Assets/XAsset/ScriptableObjects/Manifest.asset");


            CryptoWindow.ShowWindow();
            CryptoWindow.Build = s =>
            {
                var watch = new Stopwatch();
                watch.Start();
                var bytes  = DLLMgr.FileToByte(DLLMgr.DllPath);
                var result = DLLMgr.ByteToFile(CryptoHelper.AesEncrypt(bytes, s), "Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
                watch.Stop();
                Log.Print("Convert Dlls in: " + watch.ElapsedMilliseconds + " ms.");
                if (!result)
                {
                    Log.PrintError("DLL转Byte[]出错!");
                }

                watch = new Stopwatch();
                watch.Start();
                BuildScript.ApplyBuildRules();
                watch.Stop();
                Log.Print("ApplyBuildRules in: " + watch.ElapsedMilliseconds + " ms.");

                watch = new Stopwatch();
                watch.Start();
                BuildScript.BuildAssetBundles();
                watch.Stop();
                Log.Print("BuildAssetBundles in: " + watch.ElapsedMilliseconds + " ms.");
            };
        }
Пример #2
0
        private static void CleanBundles()
        {
            var watch = new Stopwatch();

            watch.Start();
            DLLMgr.Delete(Directory.GetParent(Application.dataPath) + "/DLC");
            watch.Stop();
            Log.Print("Clean bundles in: " + watch.ElapsedMilliseconds + " ms.");
        }
Пример #3
0
        static void Update()
        {
            if (!isDone)
            {
                return;
            }

            if (!Directory.Exists("Assets/HotUpdateResources/Dll/Hidden~"))
            {
                Directory.CreateDirectory("Assets/HotUpdateResources/Dll/Hidden~");
            }

            DirectoryInfo di    = new DirectoryInfo("Assets/HotUpdateResources/Dll/Hidden~");
            var           files = di.GetFiles();

            if (files.Length > 1)
            {
                isDone = false;
                int counts = 0;
                var watch  = new Stopwatch();
                watch.Start();
                foreach (var file in files)
                {
                    var name = file.Name;
                    if (!file.Name.Contains("HotUpdateScripts"))
                    {
                        DLLMgr.Delete(file.FullName);
                        counts++;
                    }
                }

                watch.Stop();
                if (counts > 0)
                {
                    Log.Print("Cleaned: " + counts + " files in: " + watch.ElapsedMilliseconds + " ms.");
                    DLLMgr.Delete("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
                    watch = new Stopwatch();
                    DLLMgr.MakeBytes();
                    watch.Stop();
                    Log.Print("Convert DLL in: " + watch.ElapsedMilliseconds + " ms.");
                    AssetDatabase.Refresh();
                }

                isDone = true;
            }

            if (!File.Exists("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes"))
            {
                isDone = false;
                var watch = new Stopwatch();
                DLLMgr.MakeBytes();
                watch.Stop();
                Log.Print("Convert DLL in: " + watch.ElapsedMilliseconds + " ms.");
                AssetDatabase.Refresh();
                isDone = true;
            }
        }
Пример #4
0
        private static void BuildAssetBundles()
        {
            DLLMgr.Delete("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
            // DLLMgr.Delete(Directory.GetParent(Application.dataPath)+"/Assets/XAsset/ScriptableObjects/Rules.asset");
            // DLLMgr.Delete(Directory.GetParent(Application.dataPath)+"/Assets/XAsset/ScriptableObjects/Manifest.asset");

            Action <string> buildAct = async s =>
            {
                var watch = new Stopwatch();
                watch.Start();
                var bytes  = DLLMgr.FileToByte(DLLMgr.DllPath);
                var result = DLLMgr.ByteToFile(CryptoHelper.AesEncrypt(bytes, s), "Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
                watch.Stop();
                Log.Print("Convert Dlls in: " + watch.ElapsedMilliseconds + " ms.");
                if (!result)
                {
                    Log.PrintError("DLL转Byte[]出错!");
                    return;
                }

                Setting.EncryptPassword = s;

                await Task.Delay(3);

                AssetDatabase.Refresh();

                watch = new Stopwatch();
                watch.Start();
                BuildScript.ApplyBuildRules();
                watch.Stop();
                Log.Print("ApplyBuildRules in: " + watch.ElapsedMilliseconds + " ms.");

                watch = new Stopwatch();
                watch.Start();
                BuildScript.BuildAssetBundles();
                watch.Stop();
                Log.Print("BuildAssetBundles in: " + watch.ElapsedMilliseconds + " ms.");
            };

            if (string.IsNullOrEmpty(Setting.EncryptPassword))
            {
                CryptoWindow.ShowWindow();
                CryptoWindow.Build = buildAct;
            }
            else
            {
                buildAct.Invoke(Setting.EncryptPassword);
            }
        }
Пример #5
0
    void LoadHotFixAssembly()
    {
        appdomain = new AppDomain();

        pdb = null;

        //编译模式
        if (!Assets.runtimeMode)
        {
            if (File.Exists(dllPath))
            {
                fs = new MemoryStream(DLLMgr.FileToByte(dllPath));
            }
            else
            {
                Log.PrintError("DLL文件不存在");
                return;
            }

            //查看是否有PDB文件
            if (File.Exists(pdbPath) && UsePdb && (File.GetLastWriteTime(dllPath) - File.GetLastWriteTime(pdbPath)).Seconds < 30)
            {
                pdb = new MemoryStream(DLLMgr.FileToByte(pdbPath));
            }
        }
        else//解密加载
        {
            var dllAsset = Assets.LoadAsset("HotUpdateScripts.bytes", typeof(TextAsset));
            if (dllAsset.error != null)
            {
                Log.PrintError(dllAsset.error);
                return;
            }
            var dll = (TextAsset)dllAsset.asset;
            try
            {
                var original = CryptoHelper.AesDecrypt(dll.bytes, Key);
                fs = new MemoryStream(original);
            }
            catch (Exception ex)
            {
                Log.PrintError("加载热更DLL失败,可能是解密密码不正确");
                Log.PrintError("加载热更DLL错误:\n" + ex.Message);
                return;
            }
        }

        try
        {
            appdomain.LoadAssembly(fs, pdb, new PdbReaderProvider());
        }
        catch (Exception e)
        {
            if (!UsePdb)
            {
                Log.PrintError("加载热更DLL失败,请确保HotUpdateResources/Dll里面有HotUpdateScripts.bytes文件,并且Build Bundle后将DLC传入服务器");
                Log.PrintError("加载热更DLL错误:\n" + e.Message);
                return;
            }

            Log.PrintError("PDB不可用,可能是DLL和PDB版本不一致,可能DLL是Release,如果是Release出包,请取消UsePdb选项,本次已跳过使用PDB");
            UsePdb = false;
            LoadHotFixAssembly();
        }

        InitILrt.InitializeILRuntime(appdomain);
        OnHotFixLoaded();
    }
Пример #6
0
        static void Update()
        {
            if (!isDone || EditorApplication.isPlaying)
            {
                return;
            }

            if (!Directory.Exists("Assets/HotUpdateResources/Dll/Hidden~")) //DLL导入到隐藏文件夹,防止每次加载浪费时间
            {
                Directory.CreateDirectory("Assets/HotUpdateResources/Dll/Hidden~");
            }

            if (!File.Exists(DLLMgr.DllPath)) //没热更dll就返回
            {
                return;
            }

            //有的话比较日期
            DateTime lastModified    = File.GetLastWriteTime(DLLMgr.DllPath);
            string   lastModifiedStr = lastModified.ToString(JEngineSetting.GetString(JEngineSetting.DATE_FORMAT));

            if (JEngineSetting.LastDLLCleanUpTime != lastModifiedStr) //不一样再处理
            {
                var           files     = di.GetFiles();
                var           watch     = new Stopwatch();
                int           counts    = 0;
                List <string> fileNames = Directory.GetFiles("Assets/",
                                                             "*.dll", SearchOption.AllDirectories).ToList();

                DLLMgr.Delete("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
                watch = new Stopwatch();
                DLLMgr.MakeBytes();
                watch.Stop();
                if (watch.ElapsedMilliseconds > 0)
                {
                    Log.Print("Convert DLL in: " + watch.ElapsedMilliseconds + " ms.");
                }

                AssetDatabase.Refresh();

                JEngineSetting.LastDLLCleanUpTime = lastModifiedStr;

                isDone    = false;
                fileNames = fileNames.FindAll((x) => !x.Contains("~"));

                watch.Start();
                foreach (var file in files)
                {
                    var name = file.Name;
                    if (!File.Exists(library.FullName + "/" + name) && !name.Contains("netstandard") &&
                        !name.Contains("HotUpdateScripts") && !name.Contains("Unity") && !name.Contains("System") &&
                        ((name.Contains(".pdb") || name.Contains(".dll"))))
                    {
                        if (fileNames.Find(x => x.Contains(name)) == null) //不存在就添加
                        {
                            DLLMgr.Delete(file.FullName.Replace("Hidden~", "../Dll"));
                            File.Move(file.FullName, file.FullName.Replace("Hidden~", "../Dll"));
                            Log.Print(
                                $"Find new referenced dll `{name}`, note that your hot update code may not be able " +
                                $"to run without rebuild application\n" +
                                $"发现新的引用DLL`{name}`,请注意,游戏可能需要重新打包,否则热更代码无法将有可能运行");
                        }
                        else //存在就删了
                        {
                            DLLMgr.Delete(file.FullName);
                            counts++;
                        }
                    }
                    else if (!name.Contains("HotUpdateScripts"))
                    {
                        DLLMgr.Delete(file.FullName);
                        counts++;
                    }
                    else
                    {
                        if (!name.Contains("HotUpdateScripts"))
                        {
                            Log.PrintError($"无法删除{file.FullName},请手动删除");
                        }
                    }
                }

                watch.Stop();
                if (counts > 0) //如果删除过东西,就代表DLL更新了,就需要生成文件
                {
                    Log.Print("Cleaned: " + counts + " files in: " + watch.ElapsedMilliseconds + " ms.");
                }

                isDone = true;
            }

            if (!File.Exists("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes"))
            {
                isDone = false;
                var watch = new Stopwatch();
                DLLMgr.MakeBytes();
                watch.Stop();
                Log.Print("Convert DLL in: " + watch.ElapsedMilliseconds + " ms.");
                AssetDatabase.Refresh();
                isDone = true;
            }
        }
Пример #7
0
        static void Update()
        {
            if (!isDone)
            {
                return;
            }

            if (!Directory.Exists("Assets/HotUpdateResources/Dll/Hidden~"))//DLL导入到隐藏文件夹,防止每次加载浪费时间
            {
                Directory.CreateDirectory("Assets/HotUpdateResources/Dll/Hidden~");
            }

            DirectoryInfo library = new DirectoryInfo(new DirectoryInfo(Application.dataPath).Parent.FullName + "/Library/ScriptAssemblies");
            DirectoryInfo di      = new DirectoryInfo("Assets/HotUpdateResources/Dll/Hidden~");
            var           files   = di.GetFiles();

            if (files.Length > 1)
            {
                isDone = false;
                int counts = 0;
                var watch  = new Stopwatch();
                watch.Start();
                foreach (var file in files)
                {
                    var name = file.Name;

                    if (!File.Exists(library.FullName + "/" + name) && !name.Contains("HotUpdateScripts") && !name.Contains("Unity") && (name.Contains(".pdb") || name.Contains(".dll")))//不存在就添加
                    {
                        File.Move(file.FullName, file.FullName.Replace("/Hidden~", ""));
                    }
                    else if (!name.Contains("HotUpdateScripts"))
                    {
                        DLLMgr.Delete(file.FullName);
                        counts++;
                    }
                }

                watch.Stop();
                if (counts > 0)//如果删除过东西,就代表DLL更新了,就需要生成文件
                {
                    Log.Print("Cleaned: " + counts + " files in: " + watch.ElapsedMilliseconds + " ms.");
                    DLLMgr.Delete("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes");
                    watch = new Stopwatch();
                    DLLMgr.MakeBytes();
                    watch.Stop();
                    if (watch.ElapsedMilliseconds > 0)
                    {
                        Log.Print("Convert DLL in: " + watch.ElapsedMilliseconds + " ms.");
                    }
                    AssetDatabase.Refresh();
                }

                isDone = true;
            }

            if (!File.Exists("Assets/HotUpdateResources/Dll/HotUpdateScripts.bytes"))
            {
                isDone = false;
                var watch = new Stopwatch();
                DLLMgr.MakeBytes();
                watch.Stop();
                Log.Print("Convert DLL in: " + watch.ElapsedMilliseconds + " ms.");
                AssetDatabase.Refresh();
                isDone = true;
            }
        }
Пример #8
0
    void LoadHotFixAssembly()
    {
        Appdomain = new AppDomain();
        _pdb      = null;

        byte[] buffer;

        //开发模式
        #if XASSET_PRO
        if (Assets.development)
        #else
        if (!Assets.runtimeMode)
        #endif
        {
            if (File.Exists(DLLPath))//直接读DLL
            {
                buffer = DLLMgr.FileToByte(DLLPath);

                //模拟加密
                buffer = CryptoHelper.AesEncrypt(buffer, key);
            }
            else
            {
                Log.PrintError("DLL文件不存在");
                return;
            }

            //查看是否有PDB文件
            if (File.Exists(PdbPath) && usePdb && (File.GetLastWriteTime(DLLPath) - File.GetLastWriteTime(PdbPath)).Seconds < 30)
            {
                _pdb = new MemoryStream(DLLMgr.FileToByte(PdbPath));
            }
        }
        else//真机模式解密加载
        {
            var dllAsset = Assets.LoadAsset("HotUpdateScripts.bytes", typeof(TextAsset));
            if (dllAsset.error != null)
            {
                Log.PrintError(dllAsset.error);
                return;
            }
            var dll = (TextAsset)dllAsset.asset;
            buffer = new byte[dll.bytes.Length];
            Array.Copy(dll.bytes, buffer, dll.bytes.Length);
            dllAsset.Release();//释放掉不需要再用的dll
        }
        try
        {
            // var original = CryptoHelper.AesDecrypt(dll.bytes, Key);以前的用法,过时了

            _fs = new JStream(buffer, key);

            /*
             * 如果一定要先解密,可以这样:
             * var original = CryptoHelper.AesDecrypt(dll.bytes, Key);
             * fs = new JStream(original, Key);
             * fs.Encrypted = false;
             */

            Appdomain.LoadAssembly(_fs, _pdb, new PdbReaderProvider());
        }
        catch (Exception e)
        {
            Log.PrintError("加载热更DLL错误:\n" + e);
            if (!usePdb)
            {
                Log.PrintError("加载热更DLL失败,请确保HotUpdateResources/Dll里面有HotUpdateScripts.bytes文件,并且Build Bundle后将DLC传入服务器");
            }
            else
            {
                Log.PrintError("PDB不可用,可能是DLL和PDB版本不一致,可能DLL是Release,如果是Release出包,请取消UsePdb选项,本次已跳过使用PDB");
                usePdb = false;
                LoadHotFixAssembly();
            }
            return;
        }

        Success = true;
        LoadILRuntime.InitializeILRuntime(Appdomain);
    }
Пример #9
0
        public static void Update()
        {
            if (!_isDone || EditorApplication.isPlaying)
            {
                return;
            }

            if (!HiddenDirectory.Exists)      //DLL导入到隐藏文件夹,防止每次加载浪费时间
            {
                HiddenDirectory.Create();
            }

            if (!File.Exists(DLLMgr.DllPath))      //没热更dll就返回
            {
                return;
            }

            //有的话比较日期
            DateTime lastModified    = File.GetLastWriteTime(DLLMgr.DllPath);
            string   lastModifiedStr = lastModified.ToString(Setting.GetString(SettingString.DateFormat));

            if (Setting.LastDLLCleanUpTime != lastModifiedStr)      //不一样再处理
            {
                var           files     = HiddenDirectory.GetFiles();
                int           counts    = 0;
                List <string> fileNames = Directory.GetFiles("Assets/",
                                                             "*.dll", SearchOption.AllDirectories).ToList();

                var watch = new Stopwatch();
                watch.Start();
                DLLMgr.MakeBytes();
                watch.Stop();
                if (watch.ElapsedMilliseconds > 0)
                {
                    Log.Print(String.Format(Setting.GetString(SettingString.DLLConvertLog),
                                            watch.ElapsedMilliseconds));
                }

                AssetDatabase.Refresh();

                Setting.LastDLLCleanUpTime = lastModifiedStr;

                _isDone   = false;
                fileNames = fileNames.FindAll(x => !x.Contains("~"));

                watch.Start();
                foreach (var file in files)
                {
                    var name    = file.Name;
                    var success = true;
                    if (!File.Exists(LibraryDirectory.FullName + "/" + name) && !name.Contains("netstandard") &&
                        !name.Contains(HotProjectName) && !name.Contains("Unity") && !name.Contains("System") &&
                        ((name.Contains(".pdb") || name.Contains(".dll"))))
                    {
                        if (fileNames.Find(x => x.Contains(name)) == null)      //不存在就添加
                        {
                            success = false;
                        }
                        else      //存在就删了
                        {
                            DLLMgr.Delete(file.FullName);
                            counts++;
                        }
                    }
                    else if (!name.Contains(HotProjectName))
                    {
                        try
                        {
                            DLLMgr.Delete(file.FullName);
                            counts++;
                        }
                        catch
                        {
                            Log.Print(String.Format(
                                          Setting.GetString(SettingString.DeleteErrorLog),
                                          file.Name));
                            success = false;
                        }
                    }

                    if (!success)
                    {
                        if (file.Directory != null)
                        {
                            DirectoryInfo newPath = new DirectoryInfo(file.Directory.FullName)?.Parent?.Parent?.Parent;
                            if (newPath != null)
                            {
                                File.Move(file.FullName, newPath.FullName + "/" + file.Name);
                                Log.Print(String.Format(
                                              Setting.GetString(SettingString.DLLNewReferenceLog),
                                              newPath.FullName + "/" + file.Name));
                            }
                        }
                    }
                }

                watch.Stop();
                if (counts > 0)      //如果删除过东西,就代表DLL更新了,就需要生成文件
                {
                    Log.Print(String.Format(Setting.GetString(SettingString.DLLCleanLog),
                                            counts,
                                            watch.ElapsedMilliseconds));
                }

                _isDone = true;
            }

            if (!HotFile.Exists)
            {
                _isDone = false;
                var watch = new Stopwatch();
                watch.Start();
                DLLMgr.MakeBytes();
                watch.Stop();
                Log.Print(String.Format(Setting.GetString(SettingString.DLLConvertLog),
                                        watch.ElapsedMilliseconds));
                AssetDatabase.Refresh();
                _isDone = true;
            }
        }
Пример #10
0
    void LoadHotFixAssembly()
    {
        Appdomain = new AppDomain();
        _pdb      = null;

        byte[] dll;

#if UNITY_EDITOR
        //开发模式
        if (!AssetMgr.RuntimeMode)
        {
            if (File.Exists(DLLPath)) //直接读DLL
            {
                dll = DLLMgr.FileToByte(DLLPath);

                //模拟加密
                dll = CryptoHelper.AesEncrypt(dll, key);
            }
            else
            {
                Log.PrintError("DLL文件不存在");
                return;
            }

            //查看是否有PDB文件
            if (File.Exists(PdbPath) && usePdb &&
                (File.GetLastWriteTime(DLLPath) - File.GetLastWriteTime(PdbPath)).Seconds < 30)
            {
                _pdb = new MemoryStream(DLLMgr.FileToByte(PdbPath));
            }
        }
        else //真机模式解密加载
#endif
        {
            var dllFile = (TextAsset)AssetMgr.Load(DllName, typeof(TextAsset));
            if (dllFile == null)
            {
                return;
            }

            dll = dllFile.bytes;
        }

        var buffer = new byte[dll.Length];
        Array.Copy(dll, buffer, dll.Length);
        AssetMgr.Unload(DllName, true);

        try
        {
            //这里默认用分块解密,JStream
            _fs = new JStream(buffer, key);

            /*
             * 如果一定要直接解密然后不进行分块解密加载Dll,可以这样:
             * var original = CryptoHelper.AesDecrypt(dll.bytes, Key);
             * _fs = new JStream(original, Key);
             * _fs.Encrypted = false;
             */

            Appdomain.LoadAssembly(_fs, _pdb, new PdbReaderProvider());
        }
        catch (Exception e)
        {
            Log.PrintError("加载热更DLL错误:\n" + e);
            if (!usePdb)
            {
                Log.PrintError(
                    "加载热更DLL失败,请确保HotUpdateResources/Dll里面有HotUpdateScripts.bytes文件,并且Build Bundle后将DLC传入服务器");
                Log.PrintError("也有可能是密码不匹配或密码包含特殊字符导致的");
            }
            else
            {
                Log.PrintError("PDB不可用,可能是DLL和PDB版本不一致,可能DLL是Release,如果是Release出包,请取消UsePdb选项,本次已跳过使用PDB");
                usePdb = false;
                LoadHotFixAssembly();
            }

            return;
        }

        Success = true;
        LoadILRuntime.InitializeILRuntime(Appdomain);
    }
Пример #11
0
    void LoadHotFixAssembly()
    {
        appdomain = new AppDomain();

        if (!Assets.runtimeMode)
        {
            DLLMgr.MakeBytes();
        }

        var dllAsset = Assets.LoadAsset("HotUpdateScripts.bytes", typeof(TextAsset));

        if (dllAsset.error != null)
        {
            Log.PrintError(dllAsset.error);
            return;
        }

        var dll = (TextAsset)dllAsset.asset;

        byte[] original = dll.bytes;
        try
        {
            if (!Assets.runtimeMode)
            {
                original = CryptoHelper.AesDecrypt(original, "DevelopmentMode.");
            }
            else
            {
                original = CryptoHelper.AesDecrypt(original, Key);
            }
        }
        catch (Exception ex)
        {
            Log.PrintError("加载热更DLL失败,可能是解密密码不正确");
            Log.PrintError("加载热更DLL错误:\n" + ex.Message);
            return;
        }

        fs = new MemoryStream(original);
        MemoryStream pdb = null;

#if UNITY_EDITOR
        if (File.Exists("Assets/HotUpdateResources/Dll/Hidden~/HotUpdateScripts.pdb"))
        {
            try
            {
                pdb = new MemoryStream(AssetDatabase.LoadAssetAtPath <TextAsset>("Assets/HotUpdateResources/Dll/Hidden~/HotUpdateScripts.pdb").bytes);
            }
            catch
            {
            }
        }
#endif

        try
        {
            appdomain.LoadAssembly(fs, pdb, new PdbReaderProvider());
        }
        catch (Exception e)
        {
            Log.PrintError("加载热更DLL失败,请确保HotUpdateResources/Dll里面有HotUpdateScripts.bytes文件,并且Build Bundle后将DLC传入服务器");
            Log.PrintError("加载热更DLL错误:\n" + e.Message);
            return;
        }


        InitILrt.InitializeILRuntime(appdomain);
        OnHotFixLoaded();
    }
Пример #12
0
    void LoadHotFixAssembly()
    {
        appdomain = new AppDomain();

        pdb = null;

        //编译模式
        if (!Assets.runtimeMode)
        {
            if (File.Exists("Assets/HotUpdateResources/Dll/Hidden~/HotUpdateScripts.dll"))
            {
                fs = new MemoryStream(DLLMgr.FileToByte("Assets/HotUpdateResources/Dll/Hidden~/HotUpdateScripts.dll"));
            }
            else
            {
                Log.PrintWarning("DLL文件不存在");
                return;
            }

            //查看是否有PDB文件
            if (File.Exists("Assets/HotUpdateResources/Dll/Hidden~/HotUpdateScripts.pdb"))
            {
                pdb = new MemoryStream(DLLMgr.FileToByte("Assets/HotUpdateResources/Dll/Hidden~/HotUpdateScripts.pdb"));
            }
        }
        else//解密加载
        {
            var dllAsset = Assets.LoadAsset("HotUpdateScripts.bytes", typeof(TextAsset));
            if (dllAsset.error != null)
            {
                Log.PrintError(dllAsset.error);
                return;
            }
            var dll = (TextAsset)dllAsset.asset;
            try
            {
                var original = CryptoHelper.AesDecrypt(dll.bytes, Key);
                fs = new MemoryStream(original);
            }
            catch (Exception ex)
            {
                Log.PrintError("加载热更DLL失败,可能是解密密码不正确");
                Log.PrintError("加载热更DLL错误:\n" + ex.Message);
                return;
            }
        }
        try
        {
            appdomain.LoadAssembly(fs, pdb, new PdbReaderProvider());
        }
        catch (Exception e)
        {
            Log.PrintError("加载热更DLL失败,请确保HotUpdateResources/Dll里面有HotUpdateScripts.bytes文件,并且Build Bundle后将DLC传入服务器");
            Log.PrintError("加载热更DLL错误:\n" + e.Message);
            return;
        }


        InitILrt.InitializeILRuntime(appdomain);
        OnHotFixLoaded();
    }