using UnityEngine; using System.Collections; using Snxxz.UI; using System; using TableConfig; using System.Collections.Generic; using System.IO; public class Launch : MonoBehaviour { static LaunchStage m_CurrentStage = LaunchStage.None; public static ProgressInfo progressInfo { get; private set; } private void Awake() { ResourcesPath.Instance.Init(); SnxxzGame.Instance.gameObject.name = "__SnxxzGame__"; Screen.sleepTimeout = SleepTimeout.NeverSleep; SDKUtility.Instance.Init(); #if UNITY_ANDROID && !UNITY_EDITOR if (!SDKUtility.builtinAssetCopyFinished) { SDKUtility.Instance.CopyOneAsset("builtin_assetbundle.7z"); SDKUtility.Instance.CopyOneAsset("builtin_assetbundle.manifest.7z"); SDKUtility.Instance.CopyOneAsset("builtin/musics.7z"); SDKUtility.Instance.CopyOneAsset("builtin/musics.manifest.7z"); SDKUtility.Instance.CopyOneAsset("builtin/prefabs.7z"); SDKUtility.Instance.CopyOneAsset("builtin/prefabs.manifest.7z"); SDKUtility.Instance.CopyOneAsset("builtin/sprites.7z"); SDKUtility.Instance.CopyOneAsset("builtin/sprites.manifest.7z"); SDKUtility.Instance.CopyOneAsset("builtin/animationclips.7z"); SDKUtility.Instance.CopyOneAsset("builtin/animationclips.manifest.7z"); SDKUtility.Instance.CopyOneAsset("builtin/materials.7z"); SDKUtility.Instance.CopyOneAsset("builtin/materials.manifest.7z"); SDKUtility.Instance.CopyOneAsset("builtin/scriptableobjects.7z"); SDKUtility.Instance.CopyOneAsset("builtin/scriptableobjects.manifest.7z"); SDKUtility.Instance.CopyOneAsset("config/Contact.txt.7z"); SDKUtility.Instance.CopyOneAsset("config/HelpInfo.txt.7z"); SDKUtility.Instance.CopyOneAsset("config/PriorBundle.txt.7z"); SDKUtility.Instance.CopyOneAsset("config/PriorLanguage.txt.7z"); SDKUtility.Instance.CopyOneAsset("config/ApkUpdateUrl.txt.7z"); AssetDeCompressTask.Decompress(ResourcesPath.Instance.ExternalStorePath); LocalSave.SetString("BuiltInAssetCopyCompleted_Android", VersionConfig.Get().version); } #endif #if UNITY_IOS && !UNITY_EDITOR if (!VersionUtility.Instance.InIosAuditTime()) { if (!SDKUtility.builtinAssetCopyFinished) { var targetDirectory = ResourcesPath.Instance.ExternalStorePath; if (!Directory.Exists(targetDirectory)) { Directory.CreateDirectory(targetDirectory); } var fileNames = new List(); var files = new List(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, "builtin"), files); foreach (var file in files) { var name = Path.GetFileName(file.FullName); fileNames.Add(StringUtility.Contact("builtin", Path.DirectorySeparatorChar, name)); } fileNames.Add("builtin_assetbundle"); fileNames.Add("builtin_assetbundle.manifest"); var configFiles = new List(); FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, "config"), configFiles); foreach (var file in configFiles) { var name = Path.GetFileName(file.FullName); fileNames.Add(StringUtility.Contact("config", Path.DirectorySeparatorChar, name)); } foreach (var item in fileNames) { var fromPath = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, item); var toPath = StringUtility.Contact(targetDirectory, item); var destDirectoryName = Path.GetDirectoryName(toPath); if (!Directory.Exists(destDirectoryName)) { Directory.CreateDirectory(destDirectoryName); } File.Copy(fromPath, toPath, true); } LocalSave.SetString("BuiltInAssetCopyCompleted_IOS", VersionConfig.Get().version); } } #endif if (!AssetSource.builtInFromEditor) { AssetBundleUtility.Instance.InitBuiltInAsset(); } ShaderUtility.InitGlobalParams(); SoundPlayer.CreateSoundPlayer(); SystemSetting.Instance.SetSoundVolume(SystemSetting.Instance.GetSoundVolume()); SystemSetting.Instance.SetSoundEffect(SystemSetting.Instance.GetSoundEffect()); SystemSetting.Instance.SetGameFps(SystemSetting.Instance.GetGameFps()); GameObjectPoolManager.Instance.gameObject.name = "GameObjectPool"; GameObjectPoolManager.Instance.Initialize(); ExceptionCatcher.Init(); ExceptionCatcher.Catch(); DebugUtility.Instance.Init(); GlobalTimeEvent.Instance.Begin(); } float timer = 0f; Queue tasks = new Queue(); LaunchTask currentTask = null; bool launchComplete = false; float surplusProgress = 0f; float surplusTime = 0f; void Start() { Application.backgroundLoadingPriority = ThreadPriority.High; SoundPlayer.Instance.PlayLoginMusic(); Config.Instance.PreLoadConfigs(); SystemSetting.Instance.LetFPSUnLimit(); Config.Instance.RegisterGlobalEvent(); PackageRegedit.Init(); DebugUtility.Instance.CreateDebugRoot(); WindowCenter.Instance.OpenFromLocal(); var sdkInitedTask = new SDKInitedTask(); var assetCopyTask = new AssetCopyTask(); var assetDecompressTask = new AssetDecompressTask(); var getVersionInfoTask = new GetVersionInfoTask(); var checkAssetValidTask = new CheckAssetValidTask(); var downLoadAssetTask = new DownLoadAssetTask(); var assetBundleInitTask = new AssetBundleInitTask(); var configInitTask = new ConfigInitTask(); var launchFadeOutTask = new LaunchFadeOutTask(); #if !UNITY_EDITOR tasks.Enqueue(sdkInitedTask); #endif #if UNITY_ANDROID #if !UNITY_EDITOR tasks.Enqueue(assetCopyTask); tasks.Enqueue(assetDecompressTask); #endif tasks.Enqueue(getVersionInfoTask); #endif #if UNITY_IOS tasks.Enqueue(getVersionInfoTask); tasks.Enqueue(assetCopyTask); #endif tasks.Enqueue(checkAssetValidTask); tasks.Enqueue(downLoadAssetTask); tasks.Enqueue(assetBundleInitTask); tasks.Enqueue(configInitTask); tasks.Enqueue(launchFadeOutTask); CalculateExpectTotalTime(); } void Update() { if (!launchComplete) { if (currentTask == null) { if (tasks.Count > 0) { currentTask = tasks.Dequeue(); currentTask.Begin(); } else { launchComplete = true; } } if (currentTask != null) { currentTask.Update(); } if (currentTask != null && currentTask.done) { currentTask.End(); CalculateExpectTotalTime(); currentTask = null; } if (m_CurrentStage == LaunchStage.DownLoad) { progressInfo = new ProgressInfo(m_CurrentStage, progressInfo.totalProgress, 0f); } else { timer += Time.deltaTime; var progress = progressInfo.totalProgress + surplusProgress * (Time.deltaTime / surplusTime); progress = Mathf.Clamp(progress, 0, 0.95f); var partProgress = 0f; if (currentTask == null) { partProgress = 0f; } else { var temp = currentTask.timer / Mathf.Min(1f, currentTask.duration); partProgress = temp - (int)temp; } progressInfo = new ProgressInfo(m_CurrentStage, Mathf.Clamp01(progress), partProgress); } } if (launchComplete) { Debug.LogFormat("启动耗时:{0}", timer); progressInfo = new ProgressInfo(m_CurrentStage, 1f, 1f); this.enabled = false; StageManager.Instance.LoadLoginStage(); } } void CalculateExpectTotalTime() { surplusTime = 0f; foreach (var item in tasks) { surplusTime += item.expectTime; } surplusProgress = 1 - progressInfo.totalProgress; } public enum LaunchStage { None = 0, SDKInit = 1, AssetCopy = 2, ClientVersion = 3, CheckAsset = 4, DownLoad = 5, AssetBundleInit = 6, ConfigInit = 7, Complete = 8, } public abstract class LaunchTask { public float timer { get; protected set; } public float duration { get; protected set; } bool exceptionReported = false; public bool done { get; protected set; } public float progress { get; protected set; } public virtual float expectTime { get; protected set; } protected float outTime = 15f; public abstract void Begin(); public abstract void Update(); public abstract void End(); public void ExceptionReport() { if (!exceptionReported && timer > outTime && !done) { var content = string.Format("任务:{0};网络状态:{1}", this.GetType().Name, Application.internetReachability); ExceptionCatcher.ReportException("游戏启动执行超时!", content); exceptionReported = true; } } } public class SDKInitedTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("SDKInitedTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("SDKInitedTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.SDKInit; duration = Mathf.Max(0.1f, expectTime); } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); OperationLogCollect.Instance.RecordLauchEvent(1); OperationLogCollect.Instance.RecordEvent(1); var cpu = 2; var memory = 2048; DeviceUtility.GetCpuAndMemory(out cpu, out memory); DebugEx.LogFormat("获得机器信息:cpu {0}----内存 {1}", cpu, memory); GameNotice.OpenGameNotice(); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (SDKUtility.Instance.InitFinished) { done = true; } else { done = false; progress = timer / duration; } ExceptionReport(); } } public class AssetCopyTask : LaunchTask { int completedCount = 0; int totalCount = 1; List copyTasks = new List(); public override float expectTime { get { return LocalSave.GetFloat("AssetCopyTask_ExpectTime", 30f); } protected set { LocalSave.SetFloat("AssetCopyTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.AssetCopy; duration = Mathf.Max(0.1f, expectTime); outTime = 50f; #if UNITY_ANDROID switch (VersionConfig.Get().assetAccess) { case InstalledAsset.FullAsset: case InstalledAsset.HalfAsset: case InstalledAsset.IngoreDownLoad: if (!SDKUtility.Instance.AssetCopyFinished) { SDKUtility.Instance.CopyAsset(); done = false; progress = 0f; } else { done = true; } break; case InstalledAsset.NullAsset: done = true; break; } #endif #if UNITY_IOS if (VersionUtility.Instance.versionInfo != null && VersionUtility.Instance.versionInfo.downAsset == 1) { switch (VersionConfig.Get().assetAccess) { case InstalledAsset.FullAsset: case InstalledAsset.HalfAsset: case InstalledAsset.IngoreDownLoad: if (!SDKUtility.Instance.AssetCopyFinished) { copyTasks = new List(); FileExtersion.GetAllDirectoryFileInfos(ResourcesPath.Instance.StreamingAssetPath, copyTasks); for (var i = copyTasks.Count - 1; i >= 0; i--) { var fileInfo = copyTasks[i]; var destPath = fileInfo.FullName.Replace(ResourcesPath.Instance.StreamingAssetPath, ResourcesPath.Instance.ExternalStorePath); if (File.Exists(destPath)) { copyTasks.RemoveAt(i); } } completedCount = 0; totalCount = copyTasks.Count; } if (totalCount > 0) { done = false; progress = 0f; } else { done = true; } break; case InstalledAsset.NullAsset: done = true; break; } } else { done = true; } #endif } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); #if UNITY_IOS LocalSave.SetString("AssetCopyCompleted_IOS", VersionConfig.Get().version); #endif } public override void Update() { if (done) { return; } timer += Time.deltaTime; #if UNITY_ANDROID if (!SDKUtility.Instance.AssetCopyFinished) { done = false; progress = timer / duration; } else { done = true; } #endif #if UNITY_IOS if (totalCount > 0) { if (completedCount < totalCount) { var fileInfo = copyTasks[0]; var destPath = fileInfo.FullName.Replace(ResourcesPath.Instance.StreamingAssetPath, ResourcesPath.Instance.ExternalStorePath); var destDirectoryName = Path.GetDirectoryName(destPath); if (!Directory.Exists(destDirectoryName)) { Directory.CreateDirectory(destDirectoryName); } DebugEx.LogFormat("拷贝文件:{0}", fileInfo.Name); File.Copy(fileInfo.FullName, destPath, true); copyTasks.RemoveAt(0); completedCount++; done = false; progress = (float)completedCount / totalCount; } else { done = true; } } else { done = true; } } #endif ExceptionReport(); } } public class AssetDecompressTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("AssetDecompressTask_ExpectTime", 5f); } protected set { LocalSave.SetFloat("AssetDecompressTask_ExpectTime", value); } } AssetDeCompressTask.DecompressProgress deCompressProgress = null; float waitTimer = 0f; public override void Begin() { m_CurrentStage = LaunchStage.AssetCopy; duration = Mathf.Max(0.1f, expectTime); if (!AssetDeCompressTask.assetDeCompressCompleted) { deCompressProgress = AssetDeCompressTask.DecompressAync(ResourcesPath.Instance.ExternalStorePath); done = false; } else { done = true; } } public override void End() { AssetDeCompressTask.assetDeCompressVersion = VersionConfig.Get().version; AssetDeCompressTask.Delete7zFiles(ResourcesPath.Instance.ExternalStorePath); } public override void Update() { if (done) { return; } timer += Time.deltaTime; progress = timer / duration; if (deCompressProgress == null || deCompressProgress.done) { waitTimer += Time.deltaTime; if (waitTimer > 2f) { done = true; } } } } public class GetVersionInfoTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("GetVersionInfoTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("GetVersionInfoTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.ClientVersion; duration = expectTime; #if UNITY_ANDROID if (InGameDownTestUtility.enable || !Application.isEditor) { VersionUtility.Instance.RequestVersionCheck(); done = false; progress = 0f; } else { done = true; } #endif #if UNITY_IOS if (!VersionUtility.Instance.InIosAuditTime()) { VersionUtility.Instance.RequestVersionCheck(); done = false; progress = 0f; } else { done = true; } #endif } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!VersionUtility.Instance.completed) { done = false; progress = timer / expectTime; } else { done = true; } ExceptionReport(); } } public class CheckAssetValidTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("CheckAssetValidTask_ExpectTime", 3f); } protected set { LocalSave.SetFloat("CheckAssetValidTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.CheckAsset; duration = Mathf.Max(0.1f, expectTime); ServerListCenter.Instance.RequestJumpUrl(); OperationLogCollect.Instance.RecordLauchEvent(2); OperationLogCollect.Instance.RecordEvent(2); if (VersionUtility.Instance.NeedDownAsset()) { AssetVersionUtility.GetAssetVersionFile(); done = false; progress = 0f; } else { done = true; } } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!AssetVersionUtility.checkAssetCompleted) { done = false; progress = timer / expectTime; } else { done = true; } ExceptionReport(); } } public class DownLoadAssetTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("DownLoadAssetTask_ExpectTime", 3f); } protected set { LocalSave.SetFloat("DownLoadAssetTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.DownLoad; duration = Mathf.Max(0.1f, expectTime); if (VersionUtility.Instance.NeedDownAsset()) { if (!AssetVersionUtility.priorAssetDownLoadDone) { AssetVersionUtility.BeginDownLoadTask(true); done = false; progress = 0f; } else { done = true; } } else { done = true; } } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); if (!AssetVersionUtility.unPriorAssetDownLoadDone) { AssetVersionUtility.BeginDownLoadTask(false); } } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!AssetVersionUtility.priorAssetDownLoadDone) { done = false; progress = 0f; } else { done = true; } ExceptionReport(); } } public class AssetBundleInitTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("AssetBundleInitTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("AssetBundleInitTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.AssetBundleInit; duration = Mathf.Max(0.1f, expectTime); if (!AssetSource.allFromEditor) { AssetBundleUtility.Instance.Sync_LoadAll("ui/prioritywindow"); SnxxzGame.Instance.StartCoroutine(AssetBundleUtility.Instance.Initialize()); SnxxzGame.Instance.StartCoroutine(AssetBundleUtility.Instance.InitalizeUIResources()); done = false; progress = 0f; } else { done = true; } } public override void End() { expectTime = timer; UILoader.LoadWindowAsync("LaunchBackGroundWin", null); DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); } public override void Update() { if (done) { return; } if (AssetBundleUtility.Instance.initialized && AssetBundleUtility.Instance.initializedUIAssetBundle) { done = true; } else { done = false; progress = timer / duration; } ExceptionReport(); } } public class ConfigInitTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("ConfigInitTask_ExpectTime", inferredTime); } protected set { LocalSave.SetFloat("ConfigInitTask_ExpectTime", value); } } float threshold = 1f; float inferredTime = 3f; public override void Begin() { inferredTime = LocalSave.GetFloat("AssetCopyTask_ExpectTime", 30f) / 30f * 10f; m_CurrentStage = LaunchStage.ConfigInit; duration = Mathf.Max(0.1f, expectTime); threshold = Application.platform == RuntimePlatform.WindowsEditor ? 1f : 0.9f; LaunchPostProcess.Instance.Begin(); } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); OperationLogCollect.Instance.RecordLauchEvent(3); OperationLogCollect.Instance.RecordEvent(3); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (!LaunchPostProcess.Instance.completed && LaunchPostProcess.Instance.progress < threshold) { done = false; progress = timer / duration; } else { done = true; } ExceptionReport(); } } public class LaunchFadeOutTask : LaunchTask { public override float expectTime { get { return LocalSave.GetFloat("LaunchFadeOutTask_ExpectTime", 1f); } protected set { LocalSave.SetFloat("LaunchFadeOutTask_ExpectTime", value); } } public override void Begin() { m_CurrentStage = LaunchStage.Complete; duration = Mathf.Max(0.1f, expectTime); LuaUtility.Instance.Init(); CSharpCallLua.Init(); ShaderUtility.WarmUpAll(); SpeechTranslate.Instance.RequestGetToken(); UI3DModelExhibition.CreateStage(); var launchWin = WindowCenter.Instance.Get(); if (launchWin != null) { launchWin.FadeOut(); } WindowCenter.Instance.Open(true); } public override void End() { expectTime = timer; DebugEx.LogFormat("{0}执行时长:{1};", this.GetType().Name, timer); var launchBackGroundWin = WindowCenter.Instance.Get(); launchBackGroundWin.transform.SetAsFirstSibling(); } public override void Update() { if (done) { return; } timer += Time.deltaTime; if (timer >= expectTime) { done = true; } else { done = false; progress = Mathf.Clamp01(timer / expectTime); } ExceptionReport(); } } public class WaitTask : LaunchTask { public WaitTask(float seconds) { expectTime = Mathf.Max(0.1f, seconds); } public override void Begin() { } public override void End() { } public override void Update() { timer += Time.deltaTime; if (timer >= expectTime) { done = true; } else { done = false; progress = Mathf.Clamp01(timer / expectTime); } } } public struct ProgressInfo { public LaunchStage stage; public float totalProgress; public float partProgress; public ProgressInfo(LaunchStage stage, float totalProgress, float partProgress) { this.stage = stage; this.totalProgress = totalProgress; this.partProgress = partProgress; } } }