require("Base/GlobalFunctions.lua") local tUpdateConfig = { -- ignoreUpdate = true, ignoreUpdate = false, hotfixLuaUrl = "http://192.168.1.135:80/files/sframework_update/hotfix.lua", httpRequestTimeoutTime = 3, resourceVersionUrlBase = "http://192.168.1.135:80/files/sframework_update/Bundles/"; resourceVersionName = "version.json", } local SUpdateManager = SUpdateManager or {} local tUpdateState = { usInvaild = "usInvaild", usStart = "usStart", usShowUI = "usShowUI", usHotfixLua = "usHotfixLua", usGetResVersion = "usGetResVersion", usCalcUpdateResInfo = "usCalcUpdateResInfo", usDownloadResource = "usDownloadResource", usFinish = "usFinish" } SUpdateManager._updateState = tUpdateState.usInvaild SUpdateManager._rVersionInfo = nil SUpdateManager._lVersionInfo = nil SUpdateManager._rVersionInfoJson = nil SUpdateManager._willDownloadBytes = 0 SUpdateManager._willDownloadFileList = nil local function stepState(newState) local oldState = SUpdateManager._updateState print("----> SUpdateManager StepState " .. oldState .. " -> " .. newState) SUpdateManager._updateState = newState end local function retryUpdate() print("----------> retryUpdate") require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) end function SUpdateManager.Awake(luaRoot) print("SUpdateManager.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 SUpdateManager.Start(luaRoot) print("SUpdateManager.Start ~") stepState(tUpdateState.usStart) -- Register Event local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:RegisterEvent(eventDispatchCenter.EventType.UPDATE_RETRY, retryUpdate) -- Process Show Update UI. require("Base/UIHelper.lua"):OpenUI("Update/SUIPanelUpdate.lua") stepState(tUpdateState.usShowUI) -- Check Ignore Update. if tUpdateConfig.ignoreUpdate == true then stepState(tUpdateState.usFinish) print("SUpdateManager.ignoreUpdate == true, Jump Update!") require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) return end -- Process Update. stepState(tUpdateState.usHotfixLua) require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) end function SUpdateManager.OnDestroy() print("SUpdateManager.OnDestroy ~") local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:UnregisterEvent(eventDispatchCenter.EventType.UPDATE_RETRY, retryUpdate) end function SUpdateManager.tryHotfixLuaLogic() print("----> Process usHotfixLua Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Communication With Server ...") require("Base/CoroutineHelper.lua"):Wait(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) if luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ConnectionError or luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ProtocolError then Warn("SUpdateManager -> UpdateLogic luaRequest Error -> " .. tostring(luaRequest.error)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Communication With Server ... Error: " .. tostring(luaRequest.error)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_SHOW_TIPS, "Connect Failed", "Connection To Resrouce Server Failed!\nPlease Check Your Network State.\nClick Yes Try Again. Click No Exit Game.") --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, "Communication With Server ... Success") require("Base/CoroutineHelper.lua"):Wait(1) stepState(tUpdateState.usGetResVersion) require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) end function SUpdateManager.tryGetResVersionLogic() print("----> Process usGetResVersion Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Communication With Resource Server ...") require("Base/CoroutineHelper.lua"):Wait(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) if luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ConnectionError or luaRequest.result == CS.UnityEngine.Networking.UnityWebRequest.Result.ProtocolError then -- Notice User, Choose; Warn("SUpdateManager -> UpdateLogic resVersionRequest Error -> " .. tostring(luaRequest.error)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Communication With Resource Server ... Error: " .. 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("Remote Version: %d Local Version: %d", rversion, lversion) print(stateMessage) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, stateMessage) SUpdateManager._lVersionInfo = localVersionInfo SUpdateManager._rVersionInfo = remoteVersionInfo SUpdateManager._rVersionInfoJson = remoteVersionJson require("Base/CoroutineHelper.lua"):Wait(1) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Commuication With ResourceServer ... Success") require("Base/CoroutineHelper.lua"):Wait(1) if rversion == lversion then print("lversion == rversion no need update.") stepState(tUpdateState.usFinish) require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) return end print("----> Process usGetResVersion Finish ...") --require("Base/CoroutineHelper.lua"):Wait(1) stepState(tUpdateState.usCalcUpdateResInfo) require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) end function SUpdateManager.tryCalcUpdateResInfoLogic() print("----> Process usCalcUpdateResInfo Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Prepare Calc Update Resource ...") require("Base/CoroutineHelper.lua"):Wait(1) local lVersionInfo = SUpdateManager._lVersionInfo local rVersionInfo = SUpdateManager._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 SUpdateManager._willDownloadBytes = willDownloadBytes SUpdateManager._willDownloadFileList = willDownloadFileList SUpdateManager._willDownloadFileCount = willDownloadFileCount print("----> will download file count: " .. tostring(willDownloadFileCount)) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Prepare Calc Update Resource ... Success") local totalSize = CS.System.Math.Round(willDownloadBytes / 1024 / 1024, 2) local tipsInfo = string.format( "Found new version:%s ...\nFile Count:%d FileSize:%s MB", rVersionInfo.version, willDownloadFileCount, tostring(totalSize) ) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_SHOW_TIPS, "Download Tips", tipsInfo) print("----> Process usCalcUpdateResInfo Finish ...") stepState(tUpdateState.usDownloadResource) --require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) end function SUpdateManager.tryDownloadResourceLogic() print("----> Process usDownloadResource Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "Prepare To Clean Local Resources ...") require("Base/CoroutineHelper.lua"):Wait(1) local willDownloadByte = SUpdateManager._willDownloadBytes local willDownloadFileList = SUpdateManager._willDownloadFileList local willDownloadFileCount = SUpdateManager._willDownloadFileCount -- 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(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(1) -- 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(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(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(1) -- Step 3: Try Write version.json(Remote Version) To PersistentPath. CS.SFramework.SResourceManagerR.SaveRemoteVersionJson(SUpdateManager._rVersionInfoJson) eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "All Files Download Finish ...") print("----> Process usDownloadResource Finish ...") require("Base/CoroutineHelper.lua"):Wait(1) -- Step 4: Change currentState And retry stepState(tUpdateState.usFinish) require("Base/CoroutineHelper.lua"):Start(SUpdateManager.ProcessUpdate) end function SUpdateManager.tryFinishLogic() print("----> Process usFinish Start ...") require("Base/CoroutineHelper.lua"):WaitForEndOfFrame() local eventDispatchCenter = require("Base/SEventDispatchCenter.lua") eventDispatchCenter:DispatchEvent(eventDispatchCenter.EventType.UPDATE_STATE_INFO, "All Data Updated ... Success") require("Base/CoroutineHelper.lua"):Wait(1) print("----> Process usFinish Finish ...") require("Base/CoroutineHelper.lua"):Wait(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 SUpdateManager.ProcessUpdate() local currentState = SUpdateManager._updateState print("SUpdateManager.ProcessUpdate Start ... ... State: " .. tostring(currentState)) if currentState == tUpdateState.usHotfixLua then require("Base/CoroutineHelper.lua"):Start(SUpdateManager.tryHotfixLuaLogic) return end if currentState == tUpdateState.usGetResVersion then require("Base/CoroutineHelper.lua"):Start(SUpdateManager.tryGetResVersionLogic) return end if currentState == tUpdateState.usCalcUpdateResInfo then require("Base/CoroutineHelper.lua"):Start(SUpdateManager.tryCalcUpdateResInfoLogic) return end if currentState == tUpdateState.usDownloadResource then require("Base/CoroutineHelper.lua"):Start(SUpdateManager.tryDownloadResourceLogic) return end if currentState == tUpdateState.usFinish then require("Base/CoroutineHelper.lua"):Start(SUpdateManager.tryFinishLogic) return end print("SUpdateManager.ProcessUpdate All Step Finish But Run ... ... Error State: " .. tostring(currentState)) end return SUpdateManager