using UnityEngine; using Cysharp.Threading; using Cysharp.Threading.Tasks; using System; using DG.Tweening; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using UnityEngine.Networking; using LaunchCommon; public class Launch : MonoBehaviour { #if UNITY_EDITOR public bool EnableNetLog = true; public bool EnableLog = true; public bool EnableLogWarning = true; public bool EnableLogError = true; #else public bool EnableNetLog = false; public bool EnableLog = false; public bool EnableLogWarning = false; public bool EnableLogError = false; #endif private static Assembly _hotUpdateAss; //网络获取 private static List AOTMetaAssemblyFiles { get; } = new List(); private static Dictionary s_assetDatas = new Dictionary(); public static Launch Instance { get { return m_Instance; } } private static Launch m_Instance; private void Awake() { if (m_Instance != null) { Debug.LogError("Launch Instance is not null"); return; } m_Instance = this; } // 启动入口 async void Start() { Debug.Log("Launch Start"); InitPlugins(); InitSetting(); SDKInit(); // 1. 打开加载界面 // LaunchLoadingWin.OpenWindow(); } private void InitSetting() { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US"); System.Globalization.CultureInfo.CurrentCulture = culture; System.Globalization.CultureInfo.CurrentUICulture = culture; System.Globalization.CultureInfo.DefaultThreadCurrentCulture = culture; System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = culture; System.Net.ServicePointManager.DefaultConnectionLimit = 100; #if UNITY_EDITOR //内网下载测试 _hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "Main"); Type type = _hotUpdateAss.GetType("InGameDownTestUtility"); LocalResManager.Instance.isPCTestDownLoad = (bool)type.GetMethod("GetReadVerionEx").Invoke(null, null); #endif SDKInit(); LocalResManager.Instance.Init(); LocalResManager.Instance.InitTable(() => { LocalResManager.Instance.InitDefaultLanguage(); LaunchLoadingWin.OpenWindow(); // LocalResManager.Instance.OpenWindow("LaunchExWin", m_UICanvas); #if !UNITY_EDITOR LocalResManager.step = LocalResManager.LoadDllStep.RequestVersion; #else if (LocalResManager.Instance.isPCTestDownLoad) { LocalResManager.step = LocalResManager.LoadDllStep.RequestVersion; } else { StartGame(); } #endif }); } private void InitPlugins() { DOTween.Init(); } private void SDKInit() { } private void StartGame() { #if !UNITY_EDITOR LoadMetadataForAOTAssemblies(); _hotUpdateAss = Assembly.Load(ReadBytesFromStreamingAssets("Main.dll.bytes")); s_assetDatas = null; #else if (_hotUpdateAss == null) _hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "Main"); #endif LocalResManager.step = LocalResManager.LoadDllStep.None; // m_UICanvas.gameObject.SetActive(false); DestroySingleton(); Type type = _hotUpdateAss.GetType("Launch"); GameObject go = new GameObject("Launch"); go.AddComponent(type); Debug.Log("进入游戏流程"); } private void DestroySingleton() { if (LocalResManager.IsValid()) { LocalResManager.Destroy(); } if (DownloadMgr.IsValid()) { Destroy(DownloadMgr.Instance); } if (LogicEngine.IsValid()) { Destroy(LogicEngine.Instance); } if (HttpRequest.IsValid()) { Destroy(HttpRequest.Instance); } if (DownLoadAndDiscompressTask.IsValid()) { DownLoadAndDiscompressTask.Destroy(); } stop = true; } bool stop = false; void Update() { if (stop) return; if (LocalResManager.step == LocalResManager.LoadDllStep.None || LocalResManager.step == LocalResManager.LoadDllStep.Wait) return; else if (LocalResManager.step == LocalResManager.LoadDllStep.RequestVersion) { LocalResManager.step = LocalResManager.LoadDllStep.Wait; LocalResManager.Instance.RequestVersionCheck(); } else if (LocalResManager.step == LocalResManager.LoadDllStep.PrepareDownLoad) { LocalResManager.step = LocalResManager.LoadDllStep.Wait; //下载前准备,读表判断是否需要多语言不同下载路径 PrepareDownLoad(); } else if (LocalResManager.step == LocalResManager.LoadDllStep.DownLoad) { LocalResManager.step = LocalResManager.LoadDllStep.Wait; BeginDownload(); } else if (LocalResManager.step == LocalResManager.LoadDllStep.ReadBytes) { LocalResManager.step = LocalResManager.LoadDllStep.Wait; ReadDllBytes(this.StartGame); } //else if (LocalResManager.step == LocalResManager.LoadDllStep.Completed) //{ // LocalResManager.step = LocalResManager.LoadDllStep.None; // m_UICanvas.gameObject.SetActive(false); // DestroySingleton(); //} } private string GetWebRequestPath(string asset) { var path = LocalResManager.Instance.GetAssetFilePath(string.Concat(LocalResManager.bytesFolderName, asset)); if (!path.Contains("file:")) { //ExternalStorePath 路径需要添加 path = "file://" + path; } return path; } private async void ReadDllBytes(Action callback) { foreach (var assetVersion in LocalResManager.Instance.assetVersions.Values) { if (assetVersion.localValid) { AOTMetaAssemblyFiles.Add(string.Concat(assetVersion.fileName, assetVersion.extersion)); } else { Debug.LogErrorFormat("文件无效 {0}", assetVersion.fileName); } } foreach (var asset in AOTMetaAssemblyFiles) { string dllPath = GetWebRequestPath(asset); Debug.Log($"dllPath:{dllPath}"); UnityWebRequest www = UnityWebRequest.Get(dllPath); await www.SendWebRequest(); #if UNITY_2020_1_OR_NEWER if (www.result != UnityWebRequest.Result.Success) { Debug.Log(www.error); } #else if (www.isHttpError || www.isNetworkError) { Debug.Log(www.error); } #endif else { // 特殊处理 byte[] assetData; 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; } } callback?.Invoke(); } private void PrepareDownLoad() { LocalResManager.Instance.RequestLogicBytes(); } private void BeginDownload() { List priorDownLoadAssetVersions = new List(); foreach (var assetVersion in LocalResManager.Instance.assetVersions.Values) { AssetVersion localAssetVersion = null; LocalResManager.Instance.localAssetVersions.TryGetValue(assetVersion.relativePath, out localAssetVersion); if (!assetVersion.CheckLocalFileValid(localAssetVersion)) { priorDownLoadAssetVersions.Add(assetVersion); assetVersion.localValid = false; } else { assetVersion.localValid = true; } } Debug.LogFormat("需要下载的文件数量:{0}", priorDownLoadAssetVersions.Count); if (priorDownLoadAssetVersions.Count == 0) { DownloadComplete(); return; } var targetDirectory = LocalResManager.Instance.ExternalStorePath; if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } DownLoadAndDiscompressTask.Instance.Prepare(priorDownLoadAssetVersions, DownloadComplete); } void DownloadComplete() { LocalResManager.step = LocalResManager.LoadDllStep.ReadBytes; } }