Esempio n. 1
0
        /// <summary>
        /// 脚本加载入口
        /// </summary>
        /// <param name="loadPathTypeType"></param>
        /// <param name="runMode"></param>
        /// <param name="mainProjectTypes">UPM隔离了dll,需要手动传入</param>
        static public void Init(AssetLoadPathType loadPathTypeType,
                                HotfixCodeRunMode runMode,
                                Type[] mainProjectTypes,
                                Action <bool> clrBindingAction)
        {
            CLRBindAction = clrBindingAction;

            if (loadPathTypeType == AssetLoadPathType.Editor)
            {
                BDebug.Log("【ScriptLaunch】Editor(非热更)模式!");
                //反射调用,防止编译报错
                var assembly = Assembly.GetExecutingAssembly();
                var type     = assembly.GetType("BDLauncherBridge");
                var method   = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                //添加框架部分的type,热更下不需要,打包会把框架的部分打进去
                var list = new List <Type>();
                list.AddRange(mainProjectTypes);
                list.AddRange(typeof(BDLauncher).Assembly.GetTypes());
                method.Invoke(null, new object[] { list.ToArray(), null });
            }
            else
            {
                BDebug.Log("【ScriptLaunch】热更模式!");
                var path = GameConfig.GetLoadPath(loadPathTypeType);
                path = Path.Combine(path, BApplication.GetRuntimePlatformPath());
                //加载dll
                var dllPath = Path.Combine(path, DLL_PATH);
                LoadHotfixDLL(dllPath, runMode, mainProjectTypes);
            }
        }
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="source"></param>
        /// <param name="copyto"></param>
        /// <returns></returns>
        static IEnumerator IE_LoadScript(string root, HotfixCodeRunMode mode)
        {
            string dllPath = "";

            if (Application.isEditor)
            {
                dllPath = root + "/" + BDUtils.GetPlatformPath(Application.platform) + "/hotfix/hotfix.dll";
            }
            else
            {
                //这里情况比较复杂,Mobile上基本认为Persistent才支持File操作,
                //可寻址目录也只有 StreamingAsset
                var firstPath = Application.persistentDataPath + "/" + BDUtils.GetPlatformPath(Application.platform) +
                                "/hotfix/hotfix.dll";
                var secondPath = Application.streamingAssetsPath + "/" + BDUtils.GetPlatformPath(Application.platform) +
                                 "/hotfix/hotfix.dll";
                if (!File.Exists(firstPath))
                {
                    var www = new WWW(secondPath);
                    yield return(www);

                    if (www.isDone && www.error == null)
                    {
                        FileHelper.WriteAllBytes(firstPath, www.bytes);
                    }
                }
                dllPath = firstPath;
            }

            //反射执行
            if (mode == HotfixCodeRunMode.ByReflection)
            {
                var bytes = File.ReadAllBytes(dllPath);
                var mdb   = dllPath + ".mdb";
                if (File.Exists(mdb))
                {
                    var bytes2 = File.ReadAllBytes(mdb);
                    Assembly = Assembly.Load(bytes, bytes2);
                }
                else
                {
                    Assembly = Assembly.Load(bytes);
                }
                var type   = Assembly.GetType("BDLauncherBridge");
                var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                method.Invoke(null, new object[] { false, true });
            }
            //解释执行
            else if (mode == HotfixCodeRunMode.ByILRuntime)
            {
                //解释执行模式
                ILRuntimeHelper.LoadHotfix(dllPath);
                ILRuntimeHelper.AppDomain.Invoke("BDLauncherBridge", "Start", null, new object[] { true, false });
            }
        }
        /// <summary>
        /// 开始热更脚本逻辑
        /// </summary>
        static public void Load(string root, HotfixCodeRunMode mode)
        {
            if (root != "")
            {
                IEnumeratorTool.StartCoroutine(IE_LoadScript(root, mode));
            }
            else
            {
#if UNITY_EDITOR
                BDebug.Log("内置code模式!");
                BDLauncherBridge.Start();
#endif
            }
        }
Esempio n. 4
0
        /// <summary>
        /// 更新服务器配置
        /// </summary>
        /// <param name="callback"></param>
        /// <returns></returns>
        private IEnumerator UpdateServerConfig(Action callback)
        {
            var url = string.Format("{0}/{1}/{2}", FileServerUrl, BDUtils.GetPlatformPath(Application.platform), "GameConfig.json");

            Debug.Log(url);
            UnityWebRequest uwq     = UnityWebRequest.Get(url);
            GameConfig      gconfig = null;

            yield return(uwq.SendWebRequest());

            if (uwq.isDone && uwq.error == null)
            {
                var text = uwq.downloadHandler.text;
                if (!string.IsNullOrEmpty(text))
                {
                    gconfig = JsonMapper.ToObject <GameConfig>(text);
                    BDebug.Log("使用服务器配置:\n" + text);
                }
            }
            else
            {
                BDebug.LogError("Game配置无法更新,使用本地");
            }


            //TODO 未来改成反射实现,暂时用这一版
            if (gconfig != null)
            {
                this.CodeRoot = (AssetLoadPath)gconfig.CodeRoot;
                this.SQLRoot  = (AssetLoadPath)gconfig.SQLRoot;
                this.ArtRoot  = (AssetLoadPath)gconfig.ArtRoot;
                //
                this.CodeRunMode = (HotfixCodeRunMode)gconfig.CodeRunMode;
                //ip相关
                this.FileServerUrl = gconfig.FileServerUrl;
                this.IsHotfix      = gconfig.IsHotfix;
                this.GateServerIp  = gconfig.GateServerIp;
                this.Port          = gconfig.Port;
                if (!Application.isEditor)
                {
                    this.IsHotfix = this.IsNeedNet = true;
                }
            }

            if (callback != null)
            {
                callback();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// 脚本加载入口
        /// </summary>
        /// <param name="loadPath"></param>
        /// <param name="runMode"></param>
        /// <param name="mainProjectTypes">UPM隔离了dll,需要手动传入</param>
        static public void Load(AssetLoadPath loadPath,
                                HotfixCodeRunMode runMode,
                                Type[] mainProjectTypes,
                                Action <bool> clrBindingAction)
        {
            CLRBindAction = clrBindingAction;

            if (loadPath == AssetLoadPath.Editor)
            {
                BDebug.Log("Editor code模式!");
                //反射调用,防止编译报错
                var assembly = Assembly.GetExecutingAssembly();
                var type     = assembly.GetType("BDLauncherBridge");
                var method   = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                //添加框架部分的type,热更下不需要,打包会把框架的部分打进去
                var list = new List <Type>();
                list.AddRange(mainProjectTypes);
                list.AddRange(typeof(BDLauncher).Assembly.GetTypes());
                method.Invoke(null, new object[] { list.ToArray(), null });
            }
            else
            {
                var path = "";
                if (Application.isEditor)
                {
                    if (loadPath == AssetLoadPath.Persistent)
                    {
                        path = Path.Combine(Application.persistentDataPath,
                                            BDApplication.GetPlatformPath(Application.platform));
                    }
                    else if (loadPath == AssetLoadPath.StreamingAsset)
                    {
                        path = Path.Combine(Application.streamingAssetsPath,
                                            BDApplication.GetPlatformPath(Application.platform));
                    }
                }
                else
                {
                    //真机环境,代码在persistent下,因为需要io
                    path = Path.Combine(Application.persistentDataPath,
                                        BDApplication.GetPlatformPath(Application.platform));
                }

                //加载dll
                var dllPath = Path.Combine(path, DLLPATH);
                LoadHotfixDLL(dllPath, runMode, mainProjectTypes);
            }
        }
Esempio n. 6
0
 /// <summary>
 /// 开始热更脚本逻辑
 /// </summary>
 static public void Load(string root, HotfixCodeRunMode mode)
 {
     if (root != "")
     {
         IEnumeratorTool.StartCoroutine(IE_LoadScript(root, mode));
     }
     else
     {
         BDebug.Log("内置code模式!");
         //反射调用,防止编译报错
         var assembly = Assembly.GetExecutingAssembly();
         var type     = assembly.GetType("BDLauncherBridge");
         var method   = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
         method.Invoke(null, new object[] { false, false });
     }
 }
Esempio n. 7
0
 /// <summary>
 /// 加载
 /// </summary>
 /// <param name="source"></param>
 /// <param name="copyto"></param>
 /// <returns></returns>
 static void LoadHotfixDLL(string dllPath, HotfixCodeRunMode mode, Type[] mainProjecTypes)
 {
     //反射执行
     if (mode == HotfixCodeRunMode.Huatuo)
     {
         new NotSupportedException("暂未实现");
         // BDebug.Log("【ScriptLaunch】反射Dll路径:" + dllPath, "red");
         // Assembly Assembly;
         // var dllBytes = File.ReadAllBytes(dllPath);
         // var pdbPath = dllPath + ".pdb";
         // if (File.Exists(pdbPath))
         // {
         //     var pdbBytes = File.ReadAllBytes(pdbPath);
         //     Assembly = Assembly.Load(dllBytes, pdbBytes);
         // }
         // else
         // {
         //     Assembly = Assembly.Load(dllBytes);
         // }
         //
         // BDebug.Log("【ScriptLaunch】反射加载成功,开始执行Start");
         // var type = typeof(ScriptLoder).Assembly.GetType("BDLauncherBridge");
         // var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
         //
         // method.Invoke(null, new object[] {mainProjecTypes, Assembly.GetTypes()});
     }
     //解释执行
     else if (mode == HotfixCodeRunMode.ILRuntime)
     {
         BDebug.Log("【ScriptLaunch】热更Dll路径:" + dllPath, "red");
         //解释执行模式
         ILRuntimeHelper.LoadHotfix(dllPath, CLRBindAction);
         var hotfixTypes = ILRuntimeHelper.GetHotfixTypes().ToArray();
         ILRuntimeHelper.AppDomain.Invoke("BDLauncherBridge", "Start", null,
                                          new object[] { mainProjecTypes, hotfixTypes });
     }
     else
     {
         BDebug.Log("【ScriptLaunch】Dll路径:内置", "red");
     }
 }
Esempio n. 8
0
 /// <summary>
 /// 使用新的配置
 /// </summary>
 /// <param name="newConfig"></param>
 private void SetNewConfig(GameConfig newConfig)
 {
     //TODO 未来改成反射实现,暂时用这一版
     if (newConfig != null)
     {
         this.CodeRoot = (AssetLoadPath)newConfig.CodeRoot;
         this.SQLRoot  = (AssetLoadPath)newConfig.SQLRoot;
         this.ArtRoot  = (AssetLoadPath)newConfig.ArtRoot;
         //
         this.CodeRunMode = (HotfixCodeRunMode)newConfig.CodeRunMode;
         //ip相关
         this.FileServerUrl = newConfig.FileServerUrl;
         this.IsHotfix      = newConfig.IsHotfix;
         this.GateServerIp  = newConfig.GateServerIp;
         this.Port          = newConfig.Port;
         if (!Application.isEditor)
         {
             this.IsHotfix = this.IsNeedNet = true;
         }
     }
 }
Esempio n. 9
0
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="source"></param>
        /// <param name="copyto"></param>
        /// <returns></returns>
        static void LoadHotfixDLL(string dllPath, HotfixCodeRunMode mode, Type[] mainProjecTypes)
        {
            //反射执行
            if (mode == HotfixCodeRunMode.ByReflection)
            {
                BDebug.Log("反射Dll路径:" + dllPath, "red");
                Assembly Assembly;
                var      dllBytes = File.ReadAllBytes(dllPath);
                var      pdbPath  = dllPath + ".pdb";
                if (File.Exists(pdbPath))
                {
                    var pdbBytes = File.ReadAllBytes(pdbPath);
                    Assembly = Assembly.Load(dllBytes, pdbBytes);
                }
                else
                {
                    Assembly = Assembly.Load(dllBytes);
                }

                BDebug.Log("反射加载成功,开始执行Start");
                var type   = typeof(ScriptLoder).Assembly.GetType("BDLauncherBridge");
                var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);

                method.Invoke(null, new object[] { mainProjecTypes, Assembly.GetTypes() });
            }
            //解释执行
            else if (mode == HotfixCodeRunMode.ByILRuntime)
            {
                BDebug.Log("热更Dll路径:" + dllPath, "red");
                //解释执行模式
                ILRuntimeHelper.LoadHotfix(dllPath, GamelogicILRBindAction);
                var hotfixTypes = ILRuntimeHelper.GetHotfixTypes().ToArray();
                ILRuntimeHelper.AppDomain.Invoke("BDLauncherBridge", "Start", null,
                                                 new object[] { mainProjecTypes, hotfixTypes });
            }
            else
            {
                BDebug.Log("Dll路径:内置", "red");
            }
        }
Esempio n. 10
0
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="source"></param>
        /// <param name="copyto"></param>
        /// <returns></returns>
        static void LoadDLL(string dllPath, HotfixCodeRunMode mode)
        {
            //反射执行
            if (mode == HotfixCodeRunMode.ByReflection)
            {
                BDebug.Log("Dll路径:" + dllPath, "red");
                var dllBytes = File.ReadAllBytes(dllPath);
                var pdbPath  = dllPath + ".pdb";
                if (File.Exists(pdbPath))
                {
                    var pdbBytes = File.ReadAllBytes(pdbPath);
                    Assembly = Assembly.Load(dllBytes, pdbBytes);
                }
                else
                {
                    Assembly = Assembly.Load(dllBytes);
                }

                BDebug.Log("代码加载成功,开始执行Start");
                var type   = Assembly.GetType("BDLauncherBridge");
                var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                method.Invoke(null, new object[] { false, true });
            }
            //解释执行
            else if (mode == HotfixCodeRunMode.ByILRuntime)
            {
                BDebug.Log("Dll路径:" + dllPath, "red");
                //解释执行模式
                ILRuntimeHelper.LoadHotfix(dllPath);
                ILRuntimeHelper.AppDomain.Invoke("BDLauncherBridge", "Start", null, new object[] { true, false });
            }
            else
            {
                BDebug.Log("Dll路径:内置", "red");
            }
        }
Esempio n. 11
0
        /// <summary>
        /// 开始热更脚本逻辑
        /// </summary>
        static public void Load(AssetLoadPath loadPath, HotfixCodeRunMode runMode)
        {
            if (loadPath == AssetLoadPath.Editor)
            {
                BDebug.Log("内置code模式!");
                //反射调用,防止编译报错
                var assembly = Assembly.GetExecutingAssembly();
                var type     = assembly.GetType("BDLauncherBridge");
                var method   = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                method.Invoke(null, new object[] { false, false });
            }
            else
            {
                var path = "";
                if (Application.isEditor)
                {
                    if (loadPath == AssetLoadPath.Persistent)
                    {
                        path = Path.Combine(Application.persistentDataPath, BDApplication.GetPlatformPath(Application.platform));
                    }
                    else if (loadPath == AssetLoadPath.StreamingAsset)
                    {
                        path = Path.Combine(Application.streamingAssetsPath, BDApplication.GetPlatformPath(Application.platform));
                    }
                }
                else
                {
                    //真机环境,代码在persistent下,因为需要io
                    path = Path.Combine(Application.persistentDataPath, BDApplication.GetPlatformPath(Application.platform));
                }

                //加载dll
                var dllPath = Path.Combine(path, DLLPATH);
                LoadDLL(dllPath, runMode);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// 加载Dll热更脚本
        /// </summary>
        /// <param name="root">路径</param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public IEnumerator IE_LoadScript(HotfixCodeRunMode mode)
        {
            string dllPath = "";

            if (Application.isEditor)
            {
                //这里情况比较复杂,Mobile上基本认为Persistent才支持File操作,
                dllPath = Application.streamingAssetsPath + "/Hotfix/" + LWUtility.HotfixFileName;
            }
            else
            {
                //这里情况比较复杂,Mobile上基本认为Persistent才支持File操作,
                //可寻址目录也只有 StreamingAsset
                var firstPath  = FileTool.CombinePaths(LWUtility.updatePath, LWUtility.HotfixFileName);                                                             //LWUtility.updatePath + "/" + LWUtility.HotfixFileName;
                var secondPath = FileTool.CombinePaths(Application.streamingAssetsPath, LWUtility.AssetBundles, LWUtility.GetPlatform(), LWUtility.HotfixFileName); // Application.streamingAssetsPath + "/" + LWUtility.AssetBundles + "/" + LWUtility.GetPlatform() + "/" + LWUtility.HotfixFileName;
                if (!File.Exists(firstPath))
                {
                    var request = UnityWebRequest.Get(secondPath);
                    LWDebug.Log("firstPath:" + firstPath);
                    LWDebug.Log("secondPath:" + secondPath);
                    yield return(request.SendWebRequest());

                    if (request.isDone && request.error == null)
                    {
                        LWDebug.Log("request.downloadHandler.data:" + request.downloadHandler.data.Length);
                        LWDebug.Log("拷贝dll成功:" + firstPath);
                        byte[] results = request.downloadHandler.data;
                        FileTool.WriteByteToFile(firstPath, results, "");
                    }
                }

                dllPath = firstPath;
            }

            LWDebug.Log("Dll路径:" + dllPath);
            //反射执行
            if (mode == HotfixCodeRunMode.ByReflection)
            {
                var bytes = File.ReadAllBytes(dllPath);
                var mdb   = dllPath + ".mdb";
                if (File.Exists(mdb))
                {
                    var bytes2 = File.ReadAllBytes(mdb);
                    Assembly = Assembly.Load(bytes, bytes2);
                }
                else
                {
                    Assembly = Assembly.Load(bytes);
                }

                //Debug.Log("反射模式,开始执行Start");
                //var type = Assembly.GetType("StartupBridge_Hotfix");
                //var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                //method.Invoke(null, new object[] { false });
                StartupBridge_Hotfix.StartReflection(Assembly);
            }
#if ILRUNTIME
            //解释执行
            else if (mode == HotfixCodeRunMode.ByILRuntime)
            {
                //解释执行模式
                //    ILRuntimeHelper.LoadHotfix(dllPath);
                //     ILRuntimeHelper.AppDomain.Invoke("StartupBridge_Hotfix", "Start", null, new object[] { true });
            }
#endif
            else if (mode == HotfixCodeRunMode.ByCode)
            {
                LWDebug.Log("内置code模式!", LogColor.green);
                StartupBridge_Hotfix.StartCode();
                //反射调用,防止编译报错
                //Assembly assembly = Assembly.GetExecutingAssembly();
                //var type = assembly.GetType("StartupBridge_Hotfix");
                //var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                //method.Invoke(null, new object[] { false });
            }
        }
Esempio n. 13
0
        /// <summary>
        /// 开始热更脚本逻辑
        /// </summary>
        static public void Load(string root, HotfixCodeRunMode mode)
        {
            if (root != "")
            {
                string dllPath = root + "/" + BDUtils.GetPlatformPath(Application.platform) + "/hotfix/hotfix.dll";

                //反射
                if (mode == HotfixCodeRunMode.ByReflection &&
                    (Application.isEditor || Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.WindowsPlayer))
                {
                    //反射模式只支持Editor PC Android
                    if (File.Exists(dllPath)) //支持File操作 或者存在
                    {
                        var bytes    = File.ReadAllBytes(dllPath);
                        var bytes2   = File.ReadAllBytes(dllPath + ".mdb");
                        var assembly = Assembly.Load(bytes, bytes2);
                        var type     = assembly.GetType("BDLauncherBridge");
                        var method   = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                        method.Invoke(null, new object[] { false, true });
                    }
                    else
                    {
                        //不支持file操作 或者不存在,继续尝试
                        IEnumeratorTool.StartCoroutine(IE_LoadDLL_AndroidOrPC(dllPath));
                    }
                }
                //ILR
                else
                {
                    //
                    //ILRuntime基于文件流,所以不支持file操作的,得拷贝到支持File操作的目录

                    //这里情况比较复杂,Mobile上基本认为Persistent才支持File操作,
                    //可寻址目录也只有 StreamingAsset
                    var firstPath  = Application.persistentDataPath + "/" + BDUtils.GetPlatformPath(Application.platform) + "/hotfix/hotfix.dll";
                    var secondPath = Application.streamingAssetsPath + "/" + BDUtils.GetPlatformPath(Application.platform) + "/hotfix/hotfix.dll";

                    if (!File.Exists(dllPath)) //仅当指定的路径不存在(或者不支持File操作)时,再进行可寻址
                    {
                        dllPath = firstPath;
                        if (!File.Exists(firstPath))
                        {
                            //验证 可寻址目录2
                            IEnumeratorTool.StartCoroutine(IE_CopyDLL_WhithLaunch(secondPath, firstPath));
                            return;
                        }
                    }

                    //解释执行模式
                    ILRuntimeHelper.LoadHotfix(dllPath);
                    ILRuntimeHelper.AppDomain.Invoke("BDLauncherBridge", "Start", null, new object[] { true, false });
                }
            }
            else
            {
                //PC模式

                //这里用反射是为了 不访问逻辑模块的具体类,防止编译失败
                var assembly = Assembly.GetExecutingAssembly();
                //
                var type   = assembly.GetType("BDLauncherBridge");
                var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static);
                method.Invoke(null, new object[] { false, false });
            }
        }