| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 | using GFGGame.Launcher;using VEngine;using System.Collections;using UnityEngine;using System.Reflection;namespace GFGGame{    public class VersionController : SingletonMonoBase<VersionController>    {        private UpdateVersions updateVersions;        public void Init()        {            StartCoroutine(InitVersion());        }        public IEnumerator InitVersion()        {            Versions.DownloadURL = LauncherConfig.CDN_ROOT;            var operation = Versions.InitializeAsync(LauncherConfig.CDN_ROOT);            yield return operation;            VEngine.Logger.I("Initialize: {0}", operation.status);            VEngine.Logger.I("API Version: {0}", Versions.APIVersion);            VEngine.Logger.I("AppVersion: {0}", Versions.Manifest.appVersion);            VEngine.Logger.I("Manifests Version: {0}", Versions.ManifestsVersion);            VEngine.Logger.I("PlayerDataPath: {0}", Versions.PlayerDataPath);            VEngine.Logger.I("DownloadDataPath: {0}", Versions.DownloadDataPath);            VEngine.Logger.I("DownloadURL: {0}", Versions.DownloadURL);            StartUpdateManifest();        }        private void CheckApkVersion()        {            var versionTarget = Versions.Manifest.appVersion;            var version = Application.version;            if(VersionUtil.compare(version, versionTarget))            {                DownloadApk();            }            else            {                DownloadRes();            }        }        private void StartUpdateManifest()        {            StartCoroutine(CheckManifestVersion());        }        private IEnumerator CheckManifestVersion()        {            if (!Versions.OfflineMode)            {                // TODO:生产环境这里的清单名字应该使用带 hash 的版本                updateVersions = Versions.UpdateAsync(nameof(Manifest));                while(!updateVersions.isDone)                {                    if(updateVersions.asset != null && updateVersions.asset.assetVersion != null)                    {                                                var max = updateVersions.asset.assetVersion.size;                        LauncherView.Instance.SetDesc($"获取版本文件...", $"{Utility.FormatBytes(max)}");                        LauncherView.Instance.SetProgress((int)(updateVersions.asset.progress * 100));                    }                    yield return updateVersions;                };                if (updateVersions.status == OperationStatus.Failed)                {                    yield return Alert.Show("更新版本信息失败,请检测网络链接后重试。")                        .SetLeftButton(true, "重试", (data) => { StartUpdateManifest(); });                    yield break;                }                CheckApkVersion();                yield break;            }            OnComplete();        }        private void DownloadApk()        {            Alert.Show("需要安装新的安装包,请联系研发获取。")                    .SetLeftButton(true, "知道了", (data) => {                        Application.Quit();                    });        }        private void DownloadRes()        {            StartCoroutine(GetDownloadSize());        }        private IEnumerator GetDownloadSize()        {            Debug.Log("VersionController GetDownloadSize");            var getDownloadSize = Versions.GetDownloadSizeAsync(updateVersions);            var totalCount = getDownloadSize.bundles.Count;            while(!getDownloadSize.isDone)            {                var remainCount = getDownloadSize.bundles.Count;                LauncherView.Instance.SetDesc($"正在计算更新内容大小...", $"{ totalCount - remainCount }/{totalCount}");                yield return getDownloadSize;            }            Debug.Log("VersionController GetDownloadSize tips");            if (getDownloadSize.totalSize > 0 || updateVersions.changed)            {                string message = $"游戏有新的版本,需要更新{Utility.FormatBytes(getDownloadSize.totalSize)}大小的内容";                yield return Alert.Show(message)                    .SetLeftButton(true, "更新", (data) => {                        StartDownload(getDownloadSize);                    });                yield break;            }            OnComplete();        }        private void StartDownload(GetDownloadSize getDownloadSize)        {            StartCoroutine(Downloading(getDownloadSize));        }        private IEnumerator Downloading(GetDownloadSize getDownloadSize)        {            LauncherView.Instance.SetProgress((int)(updateVersions.asset.progress * 100));            var downloadAsync = Versions.DownloadAsync(getDownloadSize.result.ToArray());            downloadAsync.updated += downloadAsync =>            {                var current = downloadAsync.downloadedBytes;                  var max = downloadAsync.totalSize;                var speed = Download.TotalBandwidth;                LauncherView.Instance.SetDesc($"正在下载资源,速度 {Utility.FormatBytes(speed)}/s", $"{Utility.FormatBytes(current)}/{Utility.FormatBytes(max)}");                 LauncherView.Instance.SetProgress((int)(downloadAsync.progress * 100));            };            yield return downloadAsync;            if (downloadAsync.status == OperationStatus.Failed)            {                yield return Alert.Show("下载失败!请检查网络状态后重试。")                    .SetLeftButton(true, "重试", (data) => {                         StartDownload(getDownloadSize);                     });                yield break;            }            OnComplete();        }        private void OnComplete()        {            if(updateVersions != null)            {                updateVersions.Override();            }            LauncherView.Instance.SetDesc($"正在启动游戏...");            LauncherView.Instance.SetProgress(100, () =>            {                StartCoroutine(StartLoadAssemblyHotfix());            });        }        IEnumerator StartLoadAssemblyHotfix()        {            Debug.LogFormat("ILRuntimeLauncher StartLoadAssemblyHotfix");            yield return new WaitForSeconds(0.1f);            var dllPath = "Assets/Res/Code/Game.HotUpdate.dll.bytes";            var asset = GFGAsset.Load<TextAsset>(dllPath);            byte[] assBytes = asset.bytes;            //Debug.LogFormat("assBytes != null {0}", assBytes != null);            //Debug.LogFormat("assBytes.Length {0}", assBytes.Length);            //yield return new WaitForSeconds(0.1f);            var pdbPath = "Assets/Res/Code/Game.HotUpdate.pdb.bytes";            asset = GFGAsset.Load<TextAsset>(pdbPath);            byte[] pdbBytes = asset.bytes;            //Debug.LogFormat("pdbBytes != null {0}", pdbBytes != null);            //Debug.LogFormat("pdbBytes.Length {0}", pdbBytes.Length);            if(LauncherConfig.ILRuntimeMode)            {                Debug.LogFormat("Assembly Mode ILRuntime");                ILRuntimeLauncher.Instance.LoadAssembly(assBytes, pdbBytes);            }            else            {                Debug.LogFormat("Assembly Mode Jit");                StartCoroutine(LoadAssemblyJustInTime(assBytes, pdbBytes));            }            GFGAsset.Release(dllPath);            GFGAsset.Release(pdbPath);        }        IEnumerator LoadAssemblyJustInTime(byte[] assBytes, byte[] pdbBytes)        {            //yield return new WaitForSeconds(0.1f);            //mono模式            var assembly = Assembly.Load(assBytes, pdbBytes);            //Debug.LogFormat("assembly != null {0}", assembly != null);            //yield return new WaitForSeconds(0.1f);            System.Type type = assembly.GetType("GFGGame.HotUpdate.HotUpdateEntry");            //Debug.LogFormat("type != null {0}", type != null);            //yield return new WaitForSeconds(0.1f);            type.GetMethod("Start").Invoke(type, null);            yield break;        }    }}
 |