require("Base/GlobalFunctions.lua") -- my local serverIP = "http://192.168.1.187" local serverPort = "88" local filePath = "/files/sframework_test" -- local serverIP = "http://192.168.0.200" -- local serverPort = "80" -- local filePath = "/vr-meeting-hotfix/files/sframework_update" local serverHost = serverIP .. ":" ..serverPort local tUpdateConfig = { -- ignoreUpdate = true, ignoreUpdate = false, hotfixLuaUrl = serverHost .. filePath .. "/hotfix.lua", httpRequestTimeoutTime = 3, resourceVersionUrlBase = serverHost .. filePath .. "/Bundles/"; resourceVersionName = "version.json", } local ZUpdateManager = ZUpdateManager or {} local tUpdateState = { usInvaild = "usInvaild", usStart = "usStart", usShowUI = "usShowUI", usHotfixLua = "usHotfixLua", usGetResVersion = "usGetResVersion", usCalcUpdateResInfo = "usCalcUpdateResInfo", usDownloadResource = "usDownloadResource", usFinish = "usFinish" } ZUpdateManager._updateState = tUpdateState.usInvaild ZUpdateManager._rVersionInfo = nil ZUpdateManager._lVersionInfo = nil ZUpdateManager._rVersionInfoJson = nil ZUpdateManager._willDownloadBytes = 0 ZUpdateManager._willDownloadFileList = nil local function stepState(newState) local oldState = ZUpdateManager._updateState print("----> ZUpdateManager StepState " .. oldState .. " -> " .. newState) ZUpdateManager._updateState = newState end local function retryUpdate() print("----------> retryUpdate") require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) end function ZUpdateManager.Awake(luaRoot) print("ZUpdateManager.Awake ~") local dataPath = CS.UnityEngine.Application.dataPath local streamingAssetsPath = CS.UnityEngine.Application.streamingAssetsPath local persistentDataPath = CS.UnityEngine.Application.persistentDataPath print("Application.dataPath -> " .. dataPath) print("Application.streamingAssetsPath -> " .. streamingAssetsPath) print("Application.persistentDataPath -> " .. persistentDataPath) end function ZUpdateManager.Start(luaRoot) print("ZUpdateManager.Start ~") stepState(tUpdateState.usStart) -- Register Event local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") eventDispatchCenter:RegisterEvent(eventDispatchCenter.EventType.UPDATE_RETRY, retryUpdate) -- Process Show Update UI. require("Base/UIHelper.lua"):OpenUI("Update/ZUIPanelUpdate.lua") stepState(tUpdateState.usShowUI) -- Check Ignore Update. if tUpdateConfig.ignoreUpdate == true then stepState(tUpdateState.usFinish) print("ZUpdateManager.ignoreUpdate == true, Jump Update!") require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) return end -- Process Update. stepState(tUpdateState.usHotfixLua) require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) end function ZUpdateManager.OnDestroy() print("ZUpdateManager.OnDestroy ~") local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") eventDispatchCenter:UnregisterEvent(eventDispatchCenter.EventType.UPDATE_RETRY, retryUpdate) end local function GetbIsNetworkErrorVerson() local bIsNetworkError local szUnityVersion = CS.UnityEngine.Application.unityVersion -- 2020 luaRequest.result -- 2018, 2019 luaRequest.isNetworkError local nCheckYear = 2020 local szUnityVersionYear = require("Base/Utils.lua"):Sub(szUnityVersion, 1, 4) local nUnityVersionYear = tonumber(szUnityVersionYear) bIsNetworkError = nUnityVersionYear < nCheckYear return bIsNetworkError end function ZUpdateManager.tryHotfixLuaLogic() print("----> Process usHotfixLua Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "链接服务器 ...") require("Base/CoroutineHelper.lua"):Wait(0.1) local hotfixLuaUrl = tUpdateConfig.hotfixLuaUrl --print("-------------> hotfixLuaUrl: " .. hotfixLuaUrl) local luaRequest = CS.UnityEngine.Networking.UnityWebRequest.Get(hotfixLuaUrl) luaRequest.timeout = tUpdateConfig.httpRequestTimeoutTime require("Base/CoroutineHelper.lua"):WaitSendWebRequest(luaRequest) local bIsNetworkError = GetbIsNetworkErrorVerson() local bLuaRequestError if bIsNetworkError then bLuaRequestError = luaRequest.isNetworkError or luaRequest.isHttpError else bLuaRequestError = (luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ConnectionError or luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ProtocolError) end if bLuaRequestError then Warn("ZUpdateManager -> UpdateLogic luaRequest Error -> " .. tostring(luaRequest.error)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "链接服务器失败: " .. tostring(luaRequest.error)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_SHOW_TIPS, "链接失败", "链接服务器失败!\n请检查当前网络状态。") --print("-------> Hotfix Step Failed") return end local luaCode = luaRequest.downloadHandler.text CS.SFramework.SLuaEnv.Instance:DoString(luaCode) print("----> Process usHotfixLua Finish ...") -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "链接服务器成功") -- require("Base/CoroutineHelper.lua"):Wait(0.1) stepState(tUpdateState.usGetResVersion) require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) end function ZUpdateManager.tryGetResVersionLogic() print("----> Process usGetResVersion Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "链接资源服务 ...") require("Base/CoroutineHelper.lua"):Wait(0.1) local platformName = CS.SFramework.SPlatformInfoR.GetBuildPlatformName() local resVersionUrl = tUpdateConfig.resourceVersionUrlBase .. platformName .. "/" .. tUpdateConfig.resourceVersionName --print("------------> resVersionUrl: " .. tostring(resVersionUrl)) local luaRequest = CS.UnityEngine.Networking.UnityWebRequest.Get(resVersionUrl) luaRequest.timeout = tUpdateConfig.httpRequestTimeoutTime require("Base/CoroutineHelper.lua"):WaitSendWebRequest(luaRequest) local bIsNetworkError = GetbIsNetworkErrorVerson() local bLuaRequestError if bIsNetworkError then bLuaRequestError = luaRequest.isNetworkError or luaRequest.isHttpError else bLuaRequestError = (luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ConnectionError or luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ProtocolError) end if bLuaRequestError then -- Notice User, Choose; Warn("ZUpdateManager -> UpdateLogic resVersionRequest Error -> " .. tostring(luaRequest.error)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "链接资源服务失败: " .. tostring(luaRequest.error)) --print("-------> GetResVersion Step Failed") return end local jsonConverter = require("Base/json.lua") local remoteVersionJson = luaRequest.downloadHandler.text print("remoteVersionJson -> " .. remoteVersionJson) local localVersionJson = CS.SFramework.SResourceManagerR.GetLocalVersionJson() print("localVersionJson -> " .. localVersionJson) --require("Base/CoroutineHelper.lua"):Wait(1) local remoteVersionInfo = jsonConverter:decode(remoteVersionJson) local localVersionInfo = jsonConverter:decode(localVersionJson) local rversion = remoteVersionInfo.version local lversion = localVersionInfo.version local stateMessage = string.format("发行版本: %d 本地版本: %d", rversion, lversion) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, stateMessage) ZUpdateManager._lVersionInfo = localVersionInfo ZUpdateManager._rVersionInfo = remoteVersionInfo ZUpdateManager._rVersionInfoJson = remoteVersionJson require("Base/CoroutineHelper.lua"):Wait(0.1) -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "链接资源服务成功") -- require("Base/CoroutineHelper.lua"):Wait(0.1) if rversion == lversion then print("lversion == rversion no need update.") stepState(tUpdateState.usFinish) require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) return end print("----> Process usGetResVersion Finish ...") --require("Base/CoroutineHelper.lua"):Wait(1) stepState(tUpdateState.usCalcUpdateResInfo) require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) end function ZUpdateManager.tryCalcUpdateResInfoLogic() print("----> Process usCalcUpdateResInfo Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "资源校对中 ...") require("Base/CoroutineHelper.lua"):Wait(0.1) local lVersionInfo = ZUpdateManager._lVersionInfo local rVersionInfo = ZUpdateManager._rVersionInfo local localResourceCache = {} local localResourceCount = 0 for _, oneFileInfo in pairs(lVersionInfo.fileInfo) do localResourceCache[oneFileInfo.fileName] = oneFileInfo localResourceCount = localResourceCount + 1 end print("----> Cache Local Resource Count: " .. tostring(localResourceCount)) local willDownloadFileCount = 0 local willDownloadBytes = 0 local willDownloadFileList = {} for _, oneFileInfo in pairs(rVersionInfo.fileInfo) do local lFile = localResourceCache[oneFileInfo.fileName] -- lFile == nil => add file edit file if lFile == nil or (lFile ~= nil and lFile.hashInfo ~= oneFileInfo.hashInfo) then willDownloadFileCount = willDownloadFileCount + 1 willDownloadBytes = willDownloadBytes + oneFileInfo.fileSize willDownloadFileList[oneFileInfo.fileName] = oneFileInfo end -- remove file localResourceCache[oneFileInfo.fileName] = nil end for _, removeFileInfo in pairs(localResourceCache) do willDownloadFileCount = willDownloadFileCount + 1 willDownloadBytes = willDownloadBytes + removeFileInfo.fileSize willDownloadFileList[removeFileInfo.fileName] = removeFileInfo end ZUpdateManager._willDownloadBytes = willDownloadBytes ZUpdateManager._willDownloadFileList = willDownloadFileList ZUpdateManager._willDownloadFileCount = willDownloadFileCount print("----> will download file count: " .. tostring(willDownloadFileCount)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "资源校对完成") local totalSize = CS.System.Math.Round(willDownloadBytes / 1024 / 1024, 2) local tipsInfo = string.format( "发现新版本:%s \n 资源大小:%s MB", rVersionInfo.version, tostring(totalSize) ) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_SHOW_TIPS, "更新提示", tipsInfo) print("----> Process usCalcUpdateResInfo Finish ...") stepState(tUpdateState.usDownloadResource) --require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) end function ZUpdateManager.tryDownloadResourceLogic() print("----> Process usDownloadResource Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "正在准备资源...") require("Base/CoroutineHelper.lua"):Wait(0.1) local willDownloadFileList = ZUpdateManager._willDownloadFileList local willDownloadFileCount = ZUpdateManager._willDownloadFileCount -- for backups --[[ -- Step 1: Try To Delete All Local File(PersistentPath) That Need Update. local cleanedCount = 1 for fileName, fileInfo in pairs(willDownloadFileList) do CS.SFramework.SResourceManagerR.TryDeleteAssetBundle(fileInfo.fileName) local stateMessage = string.format("Clean Local Files(%d/%d) -> %s", cleanedCount, willDownloadFileCount, fileName) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, stateMessage) cleanedCount = cleanedCount + 1 eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, cleanedCount / willDownloadFileCount) require("Base/CoroutineHelper.lua"):Wait(0.1) end print("----> Success Clean Local File Count: " .. tostring(cleanedCount)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Clean All Local Resources ... Success") require("Base/CoroutineHelper.lua"):Wait(0.1) ]] -- for backups --[[ -- Step 2: Download Each File One By One And Write It On Right Path. eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Prepare To Download Remote Resources ...") local downloadStartTime = CS.UnityEngine.Time.realtimeSinceStartup local downloadedBytes = 0 local downloadSpeed = "" for fileName, fileInfo in pairs(willDownloadFileList) do local baseDownloadedBytes = downloadedBytes local platformName = CS.SFramework.SPlatformInfoR.GetBuildPlatformName() local donwloadLink = tUpdateConfig.resourceVersionUrlBase .. platformName .. "/" .. fileInfo.fileName local luaRequest = CS.UnityEngine.Networking.UnityWebRequest.Get(donwloadLink) luaRequest.timeout = tUpdateConfig.httpRequestTimeoutTime local downloadPercent = 0 eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, downloadPercent) luaRequest:SendWebRequest() repeat downloadPercent = luaRequest.downloadProgress if downloadPercent < 0 then downloadPercent = 0 end local fileDownloadBytes = baseDownloadedBytes + luaRequest.downloadedBytes downloadSpeed = CS.SFramework.SToolFunctionR.GetDownloadSpeed(fileDownloadBytes, CS.UnityEngine.Time.realtimeSinceStartup - downloadStartTime) -- update download info to show information. local stateMessage = string.format( "Downloading: %s From %s \nPercent: %.2f Speed:%s", fileName, donwloadLink, downloadPercent * 100, downloadSpeed ) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, stateMessage) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, downloadPercent) require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() until luaRequest.isDone eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, 1) downloadedBytes = downloadedBytes + luaRequest.downloadedBytes downloadSpeed = CS.SFramework.SToolFunctionR.GetDownloadSpeed(downloadedBytes, CS.UnityEngine.Time.realtimeSinceStartup - downloadStartTime) -- update download speed local stateMessage = string.format("Downloading: %s \nPercent: %.2f Speed:%s Success", fileName, downloadPercent * 100, downloadSpeed) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, stateMessage) require("Base/CoroutineHelper.lua"):Wait(0.1) CS.SFramework.SResourceManagerR.SaveAssetBundle(fileInfo.fileName, luaRequest.downloadHandler.data) stateMessage = string.format("Download And Save %s Success", fileName) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, stateMessage) require("Base/CoroutineHelper.lua"):Wait(0.1) end downloadSpeed = CS.SFramework.SToolFunctionR.GetDownloadSpeed(downloadedBytes, CS.UnityEngine.Time.realtimeSinceStartup - downloadStartTime) -- update download speed eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "All Remote Resource Download Compelete ... Speed: " .. tostring(downloadSpeed)) require("Base/CoroutineHelper.lua"):Wait(0.1) ]] -- Step 1: Try To Delete All Local File(PersistentPath) That Need Update local nCleanedCount = 0 for _, fileInfo in pairs(willDownloadFileList) do CS.SFramework.SResourceManagerR.TryDeleteAssetBundle(fileInfo.fileName) nCleanedCount = nCleanedCount + 1 local nDeletePercent = nCleanedCount / willDownloadFileCount -- local szStateMessage = string.format("资源加载中: %.2f", nDeletePercent * 100) -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, szStateMessage .. "%") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, nDeletePercent) require("Base/CoroutineHelper.lua"):Wait(0.01) end eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "资源准备完成") require("Base/CoroutineHelper.lua"):Wait(0.1) -- Step 2: Show All Download Percent local szStateMessage = "更新中..." eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, szStateMessage) require("Base/CoroutineHelper.lua"):Wait(0.1) local nDownloadStartTime = CS.UnityEngine.Time.realtimeSinceStartup local nWillDownloadBytes = ZUpdateManager._willDownloadBytes local nDownloadedBytes = 0 local szDownloadSpeed = "" for _, fileInfo in pairs(willDownloadFileList) do local szPlatformName = CS.SFramework.SPlatformInfoR.GetBuildPlatformName() local szDownloadFileLink = tUpdateConfig.resourceVersionUrlBase .. szPlatformName .. "/" .. fileInfo.fileName local luaRequest = CS.UnityEngine.Networking.UnityWebRequest.Get(szDownloadFileLink) luaRequest.timeout = tUpdateConfig.httpRequestTimeoutTime luaRequest:SendWebRequest() local nDownloadPercent = 0 local nDownloadFileBytes = fileInfo.fileSize local nCurrentDownloadedBytes = nDownloadedBytes repeat local nFileDownloadPercent = luaRequest.downloadProgress local nFileDownloadedBytes = nDownloadFileBytes * nFileDownloadPercent local nCurrentFileDownloadedBytes = nCurrentDownloadedBytes + nFileDownloadedBytes nDownloadPercent = nCurrentFileDownloadedBytes / nWillDownloadBytes eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, nDownloadPercent) -- szDownloadSpeed = CS.SFramework.SToolFunctionR.GetDownloadSpeed(nDownloadedBytes, CS.UnityEngine.Time.realtimeSinceStartup - nDownloadStartTime) -- local szStateMessage = string.format("Downloading Remote Resources. Speed: %s", szDownloadSpeed) -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, szStateMessage) require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() until luaRequest.isDone nDownloadedBytes = nDownloadedBytes + luaRequest.downloadedBytes local szDownloadPercent = string.format("%.2f", nDownloadPercent * 100) .. "%" szDownloadSpeed = CS.SFramework.SToolFunctionR.GetDownloadSpeed(nDownloadedBytes, CS.UnityEngine.Time.realtimeSinceStartup - nDownloadStartTime) local nDownloadSize = CS.System.Math.Round(nDownloadedBytes / 1024 / 1024, 2) local nTotleSize = CS.System.Math.Round(nWillDownloadBytes / 1024 / 1024, 2) -- local szStateMessage = string.format("更新中:%s (%s MB /%s MB)... 下载速度: %s", szDownloadPercent, tostring(nDownloadSize), tostring(nTotleSize), szDownloadSpeed) -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, szStateMessage) local szUpdateDetail = string.format("(%s MB /%s MB)", tostring(nDownloadSize), tostring(nTotleSize)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_SHOW_UPDATE_DETAIL, szDownloadPercent, szUpdateDetail, szDownloadSpeed) CS.SFramework.SResourceManagerR.SaveAssetBundle(fileInfo.fileName, luaRequest.downloadHandler.data) end local nDownloadPercent = 1 eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_PROGRESS_PERCENT, nDownloadPercent) local szStateMessage = "更新完成" eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, szStateMessage) require("Base/CoroutineHelper.lua"):Wait(0.1) -- Step 3: Try Write version.json(Remote Version) To PersistentPath. CS.SFramework.SResourceManagerR.SaveRemoteVersionJson(ZUpdateManager._rVersionInfoJson) -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "所有资源加载完成 ...") print("----> Process usDownloadResource Finish ...") require("Base/CoroutineHelper.lua"):Wait(1) -- Step 4: Change currentState And retry stepState(tUpdateState.usFinish) require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.ProcessUpdate) end function ZUpdateManager.tryFinishLogic() print("----> Process usFinish Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/ZEventDispatchCenter.lua") -- eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "更新成功!") -- require("Base/CoroutineHelper.lua"):Wait(0.1) print("----> Process usFinish Finish ...") require("Base/CoroutineHelper.lua"):Wait(0.1) -- jump scene -- LoadResource("Scenes/Start.unity") --LoadResource("scenes/gameb.unity") --CS.UnityEngine.SceneManagement.SceneManager.LoadScene("GameA") CS.UnityEngine.SceneManagement.SceneManager.LoadScene("Start") end function ZUpdateManager.ProcessUpdate() local currentState = ZUpdateManager._updateState print("ZUpdateManager.ProcessUpdate Start ... ... State: " .. tostring(currentState)) if currentState == tUpdateState.usHotfixLua then require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.tryHotfixLuaLogic) return end if currentState == tUpdateState.usGetResVersion then require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.tryGetResVersionLogic) return end if currentState == tUpdateState.usCalcUpdateResInfo then require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.tryCalcUpdateResInfoLogic) return end if currentState == tUpdateState.usDownloadResource then require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.tryDownloadResourceLogic) return end if currentState == tUpdateState.usFinish then require("Base/CoroutineHelper.lua"):Start(ZUpdateManager.tryFinishLogic) return end print("ZUpdateManager.ProcessUpdate All Step Finish But Run ... ... Error State: " .. tostring(currentState)) end return ZUpdateManager