873 lines
No EOL
35 KiB
Lua
873 lines
No EOL
35 KiB
Lua
local UnityApplication = CS.UnityEngine.Application
|
||
|
||
local CsApplication = CS.XApplication
|
||
local CsLog = CS.XLog
|
||
local CsRemoteConfig = CS.XRemoteConfig
|
||
local CsTool = CS.XTool
|
||
local CsGameEventManager = CS.XGameEventManager.Instance
|
||
|
||
local CsInfo = CS.XInfo
|
||
|
||
local CsDownloadService = CS.XDownloadService.Instance
|
||
local DownloadState = {
|
||
NONE = -1,
|
||
DONE = 0,
|
||
ING = 1,
|
||
FAIL = 2
|
||
}
|
||
|
||
local IosDownloadState = {
|
||
PreparingLocalFiles = 0,
|
||
PreparingDownload = 1,
|
||
Downloading = 2,
|
||
AppendDownloading = 3,
|
||
Verifying = 4,
|
||
Finished = 5
|
||
}
|
||
|
||
-- 版更时需要强清本地资源的版本
|
||
local ForceVersion = {["1.22.0"] = true}
|
||
local ForceVersionNum = 22
|
||
|
||
|
||
local SPECIAL_DELETE_MATRIX_PREF_KEY = "__Kuro__reset_Matrix_files_"
|
||
local UNCHECKED_FILE_EXTENSION = ".unchecked"
|
||
|
||
local module_creator = function()
|
||
local XLaunchFileModule = {}
|
||
|
||
local MESSAGE_PACK_MODULE_NAME = "XLaunchCommon/XMessagePack"
|
||
require(MESSAGE_PACK_MODULE_NAME)
|
||
|
||
|
||
local XLaunchDlcManager = require("XLaunchDlcManager")
|
||
|
||
local SIZE = 10 * 1024 * 1024
|
||
local TIMEOUT = 5 * 1000
|
||
local READ_TIMEOUT = 10 * 1000
|
||
local RETRY = 10
|
||
|
||
local INDEX = "index"
|
||
|
||
local ResFileType
|
||
local AppPathModule
|
||
local AppVersionModule
|
||
local OnCompleteCallback
|
||
local OnProgressCallback
|
||
local OnExitCallback
|
||
|
||
local ApplicationFilePath
|
||
local DocumentFilePath
|
||
local DocumentUrl
|
||
|
||
local DocumentIndexDir
|
||
local DocumentIndexPath
|
||
|
||
local NewVersion
|
||
local NeedUpdate
|
||
local HasUpdated
|
||
|
||
-- common
|
||
local ApplicationIndexTable
|
||
local DocumentIndexTable
|
||
|
||
local DlcIndexTable
|
||
local DlcCommonIdList
|
||
|
||
local CurrentFileTable = nil
|
||
local AllFileTableDlc = nil
|
||
local NeedFileSet = nil
|
||
|
||
local UpdateTable = {}
|
||
local UpdateTableCount = 0
|
||
local UpdateSize = 0
|
||
|
||
local AllUpdateTable = {}
|
||
local AllUpdateTableCount = 0
|
||
local AllUpdateSize = 0
|
||
|
||
local CurrentUpdateSize = 0
|
||
--
|
||
local HasLocalFiles = false
|
||
|
||
-- Local Function
|
||
local CheckIndexFile
|
||
local ResolveResIndex
|
||
local PrepareDownload
|
||
local DownloadFiles
|
||
local CompleteDownload
|
||
local OnCompleteResFilesInit
|
||
local LoadIndexTable
|
||
local LoadIndexTableWithDlcInfo
|
||
local InitDocumentIndex
|
||
local DownloadDlcIndexs
|
||
local DoPrepareDownload
|
||
local OnNotifyEvent
|
||
|
||
local IsDlcBuild = false
|
||
local NeedShowSelect = false
|
||
|
||
function XLaunchFileModule.Check(resFileType, appPathModule, appVersionModule, completeCb,progressCb,exitCb)
|
||
ResFileType = resFileType
|
||
AppPathModule = appPathModule
|
||
AppVersionModule = appVersionModule
|
||
OnCompleteCallback = completeCb
|
||
OnProgressCallback = progressCb
|
||
OnExitCallback = exitCb
|
||
|
||
ApplicationFilePath = AppPathModule.GetApplicationFilePath()
|
||
DocumentFilePath = AppPathModule.GetDocumentFilePath()
|
||
DocumentUrl = AppPathModule.GetDocumentUrl()
|
||
|
||
IsDlcBuild = CsInfo.IsDlcBuild
|
||
XLaunchDlcManager.SetIsDlcBuild(IsDlcBuild)
|
||
|
||
DocumentIndexDir = DocumentFilePath .. "/" .. ResFileType .. "/"
|
||
DocumentIndexPath= DocumentIndexDir .. INDEX
|
||
|
||
|
||
NeedUpdate = false
|
||
NeedShowSelect = false
|
||
|
||
if ResFileType == RES_FILE_TYPE.LAUNCH_MODULE then
|
||
NeedUpdate = AppVersionModule.CheckLaunchModuleUpdate()
|
||
HasUpdated = AppVersionModule.HasLaunchModuleUpdated()
|
||
NewVersion = AppVersionModule.GetNewLaunchModuleVersion()
|
||
elseif ResFileType == RES_FILE_TYPE.MATRIX_FILE then
|
||
|
||
NeedUpdate = AppVersionModule.CheckDocUpdate()
|
||
HasUpdated = AppVersionModule.HasDocUpdated()
|
||
NewVersion = AppVersionModule.GetNewDocVersion()
|
||
|
||
NeedShowSelect = XLaunchDlcManager.NeedShowSelectDownloadPart(CsInfo.Version) and IsDlcBuild -- 每个大版本只会弹出一次选择更新,小更新沿用选择结果
|
||
end
|
||
|
||
if CS.XRemoteConfig.IsHideFunc then
|
||
--NeedUpdate = false
|
||
end
|
||
|
||
CsLog.Debug("NeedUpdate:"..tostring(NeedUpdate)..",type:"..ResFileType)
|
||
--
|
||
CheckIndexFile()
|
||
end
|
||
|
||
-- function XLaunchFileModule.GetOffset()
|
||
-- return OFFSET
|
||
-- end
|
||
|
||
DownloadDlcIndexs = function(cb)
|
||
if not IsDlcBuild then
|
||
cb()
|
||
return
|
||
end
|
||
|
||
DocumentIndexTable, DlcIndexTable, DlcCommonIdList = LoadIndexTableWithDlcInfo(DocumentIndexPath)
|
||
|
||
local count = 0
|
||
local totalCount = 0
|
||
if DlcIndexTable then
|
||
for _, _ in pairs(DlcIndexTable) do
|
||
totalCount = totalCount + 1
|
||
end
|
||
end
|
||
if totalCount > 0 then
|
||
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, totalCount, false, CsApplication.GetText("UpdateIndex") .. "(%d/%d)") -- 检查更新(0/10)
|
||
CsApplication.SetProgress(0)
|
||
end
|
||
local iter, t, key = pairs(DlcIndexTable)
|
||
local info
|
||
|
||
local iterKey = nil
|
||
local Loop
|
||
Loop = function()
|
||
key, info = iter(t, iterKey)
|
||
|
||
if not key then
|
||
CsApplication.SetProgress(1)
|
||
cb()
|
||
return
|
||
end
|
||
|
||
local id = key
|
||
local name = info[1]
|
||
local sha1 = info[2]
|
||
local cache = true -- 本地缓存 校验通过不重复下载
|
||
|
||
local str = string.format("%s/%s/%s/%s", DocumentUrl, NewVersion, ResFileType, name)
|
||
local str2 = DocumentFilePath .. "/" .. ResFileType .. "/" .. name
|
||
local downloader = CS.XUriPrefixDownloader(str, str2, cache, sha1, TIMEOUT, RETRY, READ_TIMEOUT)
|
||
local size = 0
|
||
--CsLog.Debug("DocumentUrl:"..DocumentUrl)
|
||
--CsLog.Debug("str:"..str)
|
||
--CsLog.Debug("str2:"..str2)
|
||
CsTool.WaitCoroutinePerFrame(downloader:Send(), function(isComplete)
|
||
if not isComplete then
|
||
--
|
||
else
|
||
if downloader.State ~= CS.XDownloaderState.Success then
|
||
local msg = "XFileManager Download error, state error, state: " .. tostring(downloader.State)
|
||
CsLog.Error(msg)
|
||
local dict = {}
|
||
dict.file_name = name
|
||
dict.file_size = 1
|
||
CS.XRecord.Record(dict, "80007", "XFileManagerDownloadError")
|
||
ShowStartErrorDialog("FileManagerInitFileTableDownloadError", CsApplication.Exit, function()
|
||
Loop()
|
||
end, CsApplication.GetText("Retry")) -- 重试
|
||
return
|
||
end
|
||
|
||
count = count + 1
|
||
CsApplication.SetProgress(count / totalCount)
|
||
CsLog.Debug("[] EVENT_LAUNCH_START_DOWNLOAD count:" .. tostring(count))
|
||
iterKey = key
|
||
Loop()
|
||
end
|
||
end)
|
||
end
|
||
|
||
Loop()
|
||
end
|
||
|
||
-- 检测资源列表文件
|
||
CheckIndexFile = function()
|
||
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Version_Checking_Start)
|
||
local documentFilePath = DocumentFilePath .. "/" .. ResFileType .. "/" .. INDEX
|
||
local keepLocalIndex = CS.System.IO.File.Exists(DocumentFilePath .. "/DevelopmentIndex") -- 用于Release环境不清理本地index文件(兼顾覆盖安装和手动放资源的情况)
|
||
|
||
CsLog.Debug("[Download] CheckIndexFile:"..ResFileType .. ", documentFilePath:" .. tostring(CS.System.IO.File.Exists(documentFilePath))
|
||
.. ", Debug:" .. tostring(CsRemoteConfig.Debug) .. ", NeedUpdate:" .. tostring(NeedUpdate) .. ", keepLocalIndex:" .. tostring(keepLocalIndex))
|
||
if not NeedUpdate then
|
||
if CS.System.IO.File.Exists(documentFilePath) and not CsRemoteConfig.Debug then -- debug情况下不需更新但要保留本地index
|
||
if not keepLocalIndex then
|
||
CS.XFileTool.DeleteFile(documentFilePath)
|
||
end
|
||
end
|
||
-- 原始版本,直接进
|
||
ResolveResIndex()
|
||
return
|
||
end
|
||
|
||
-- 下载/检测 当前index文件是否最新
|
||
local sha1 = "empty"
|
||
local newVersion = ""
|
||
if ResFileType == RES_FILE_TYPE.LAUNCH_MODULE then
|
||
sha1 = CsRemoteConfig.LaunchIndexSha1
|
||
newVersion = CsRemoteConfig.LaunchModuleVersion
|
||
elseif ResFileType == RES_FILE_TYPE.MATRIX_FILE then
|
||
sha1 = CsRemoteConfig.IndexSha1
|
||
newVersion = CsRemoteConfig.DocumentVersion
|
||
end
|
||
|
||
if HasUpdated and CS.XFileTool.CheckSha1(documentFilePath, sha1) then
|
||
CsLog.Debug("[Download] HasUpdated:" .. tostring(HasUpdated))
|
||
ResolveResIndex()
|
||
return
|
||
end
|
||
--CsLog.Debug("index download DocumentUrl:"..DocumentUrl)
|
||
local uriPrefixStr = DocumentUrl .. "/" .. newVersion .. "/" .. ResFileType .. "/" .. INDEX
|
||
local downloader = CS.XUriPrefixDownloader(uriPrefixStr, documentFilePath, false, sha1)
|
||
CsTool.WaitCoroutine(downloader:Send(), function()
|
||
if downloader.State ~= CS.XDownloaderState.Success then
|
||
ShowStartErrorDialog("FileManagerInitVersionDownLoadError")
|
||
else
|
||
if ResFileType == RES_FILE_TYPE.LAUNCH_MODULE then
|
||
AppVersionModule.UpdateLaunchVersion()
|
||
ResolveResIndex()
|
||
elseif ResFileType == RES_FILE_TYPE.MATRIX_FILE then
|
||
|
||
DownloadDlcIndexs(function()
|
||
AppVersionModule.UpdateDocVersion()
|
||
ResolveResIndex()
|
||
end)
|
||
end
|
||
|
||
end
|
||
end)
|
||
end
|
||
|
||
LoadIndexTable = function(indexPath)
|
||
local assetBundle = CS.UnityEngine.AssetBundle.LoadFromFile(indexPath)
|
||
if (assetBundle and assetBundle:Exist()) then
|
||
local assetName = assetBundle:GetAllAssetNames()[0]
|
||
local asset = assetBundle:LoadAsset(assetName, typeof(CS.UnityEngine.TextAsset))
|
||
local indexFile = XMessagePack.Decode(asset.bytes)
|
||
local indexTable = indexFile[1]
|
||
assetBundle:Unload(true)
|
||
return indexTable
|
||
end
|
||
return nil
|
||
end
|
||
|
||
LoadIndexTableWithDlcInfo = function(indexPath)
|
||
local assetBundle = CS.UnityEngine.AssetBundle.LoadFromFile(indexPath)
|
||
if (assetBundle and assetBundle:Exist()) then
|
||
local assetName = assetBundle:GetAllAssetNames()[0]
|
||
local asset = assetBundle:LoadAsset(assetName, typeof(CS.UnityEngine.TextAsset))
|
||
local indexFile = XMessagePack.Decode(asset.bytes)
|
||
local indexTable = indexFile[1]
|
||
local dlcIndexTable = indexFile[2] or {}
|
||
local dlcCommonIdList = indexFile[3] or {}
|
||
assetBundle:Unload(true)
|
||
return indexTable, dlcIndexTable, dlcCommonIdList
|
||
end
|
||
return nil
|
||
end
|
||
|
||
-- 解析doc目录下index
|
||
InitDocumentIndex = function()
|
||
if not CS.System.IO.File.Exists(DocumentIndexPath) then
|
||
CsLog.Error("[Download] Init DocumentIndex Failed, file not exist: " .. tostring(DocumentIndexPath))
|
||
return
|
||
end
|
||
|
||
if not DocumentIndexTable then
|
||
if IsDlcBuild then
|
||
DocumentIndexTable, DlcIndexTable, DlcCommonIdList = LoadIndexTableWithDlcInfo(DocumentIndexPath)
|
||
else
|
||
DocumentIndexTable = LoadIndexTable(DocumentIndexPath) -- {[assetPath] = value{[1] = Name, [2] = Sha1, [3] = Size}, ... }
|
||
end
|
||
end
|
||
|
||
CurrentFileTable = {} -- 当前需下载资源
|
||
AllFileTableDlc = {} -- DLC完整资源
|
||
|
||
local count = 0
|
||
NeedFileSet = {} -- 需下载标记
|
||
|
||
-- 基础补丁
|
||
for asset, info in pairs(DocumentIndexTable) do
|
||
NeedFileSet[info[1]] = true
|
||
CurrentFileTable[asset] = info
|
||
AllFileTableDlc[asset] = info
|
||
end
|
||
|
||
-- 统计资源
|
||
if IsDlcBuild then
|
||
XLaunchDlcManager.Init(DlcIndexTable, DlcCommonIdList)
|
||
|
||
-- 分包补丁
|
||
for dlcId, dlcIndexInfo in pairs(DlcIndexTable) do
|
||
local dlcIndexPath = DocumentIndexDir .. dlcIndexInfo[1]
|
||
local dlcTable = LoadIndexTable(dlcIndexPath)
|
||
XLaunchDlcManager.SetDlcIndexInfo(dlcId, dlcTable)
|
||
|
||
-- 历史选择的分包下载记录(不弹出选择框是用于默认下载)
|
||
local hasDownloadDlc = (not NeedShowSelect) and XLaunchDlcManager.HasStartDownloadDlc(dlcId)
|
||
CsLog.Debug("[DLC] dlcId: ".. tostring(dlcId) .. ", hasDownloadDlc: " .. tostring(hasDownloadDlc) .. ", NeedShowSelect:" .. tostring(NeedShowSelect))
|
||
|
||
for asset, info in pairs(dlcTable) do
|
||
NeedFileSet[info[1]] = true
|
||
|
||
if hasDownloadDlc then
|
||
CurrentFileTable[asset] = info
|
||
end
|
||
AllFileTableDlc[asset] = info
|
||
end
|
||
end
|
||
|
||
-- 剔除包内已有资源(需asset与Name都对应)
|
||
for asset, info in pairs(ApplicationIndexTable) do
|
||
local value = AllFileTableDlc[asset]
|
||
if value and value[1] == info[1] then
|
||
AllFileTableDlc[asset] = nil
|
||
CurrentFileTable[asset] = nil
|
||
count = count + 1
|
||
end
|
||
end
|
||
else
|
||
CurrentFileTable = DocumentIndexTable
|
||
|
||
-- 剔除包内已有资源(需asset与Name都对应)
|
||
for asset, info in pairs(ApplicationIndexTable) do
|
||
local value = CurrentFileTable[asset]
|
||
if value and value[1] == info[1] then
|
||
CurrentFileTable[asset] = nil
|
||
count = count + 1
|
||
end
|
||
end
|
||
end
|
||
|
||
CsLog.Debug("[Download] 包内已有资源数量:" .. count)
|
||
end
|
||
|
||
|
||
ResolveResIndex = function()
|
||
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Version_Checking_End)
|
||
local applicationIndexPath = ApplicationFilePath .. "/" .. ResFileType .. "/" .. INDEX
|
||
ApplicationIndexTable = LoadIndexTable(applicationIndexPath)
|
||
|
||
CsLog.Debug("[Download] ResolveResIndex. NeedUpdate:" .. tostring(NeedUpdate) .. ", applicationIndexPath:" .. applicationIndexPath .. ", documentIndexPath:" .. DocumentIndexPath)
|
||
if not NeedUpdate then -- 原始版本
|
||
if CS.System.IO.File.Exists(DocumentIndexPath) then
|
||
CsLog.Debug("Local index:" .. DocumentIndexPath)
|
||
InitDocumentIndex()
|
||
HasLocalFiles = true
|
||
end
|
||
|
||
OnCompleteResFilesInit() -- 无需更新,直接完成
|
||
return
|
||
end
|
||
|
||
InitDocumentIndex()
|
||
|
||
UpdateSize = 0
|
||
UpdateTableCount = 0
|
||
UpdateTable = {}
|
||
for _, info in pairs(CurrentFileTable) do
|
||
if UpdateTable[info[1]] then
|
||
local dict = {}
|
||
dict["file_name"] = info[1]
|
||
CS.XRecord.Record(dict, "80006", "UpdateTableAddFileError")
|
||
CsLog.Error("repeat update file:" .. tostring(info[1]))
|
||
ShowStartErrorDialog("FileManagerInitFileTableUpdateTableError")
|
||
return
|
||
end
|
||
|
||
UpdateTable[info[1]] = info
|
||
UpdateTableCount = UpdateTableCount + 1
|
||
UpdateSize = UpdateSize + info[3]
|
||
end
|
||
|
||
AllUpdateSize = 0
|
||
AllUpdateTable = {}
|
||
AllUpdateTableCount = 0
|
||
if NeedShowSelect then
|
||
for _, info in pairs(AllFileTableDlc) do
|
||
AllUpdateTable[info[1]] = info
|
||
AllUpdateTableCount = AllUpdateTableCount + 1
|
||
AllUpdateSize = AllUpdateSize + info[3]
|
||
end
|
||
end
|
||
|
||
CsLog.Debug("[Download] IsDlcBuild:" .. tostring(IsDlcBuild))
|
||
CsLog.Debug(string.format("[Download] UpdateSize: %d, UpdateTableCount: %d, AllUpdateSize: %d, AllUpdateTableCount: %d", UpdateSize, UpdateTableCount, AllUpdateSize, AllUpdateTableCount)) -- 2166 -- 基础包补丁
|
||
|
||
local deleteKey = SPECIAL_DELETE_MATRIX_PREF_KEY .. tostring(AppVersionModule.GetAppVersion())
|
||
local isMatrix = ResFileType == "matrix"
|
||
local cleanFlag = CS.UnityEngine.PlayerPrefs.GetInt(deleteKey, 0)
|
||
local checkClean = (isMatrix and (not cleanFlag or cleanFlag ~= 1))
|
||
local isForceClean = ForceVersion[CsInfo.Version]
|
||
|
||
if isMatrix and not isForceClean then -- 补充强删资源逻辑
|
||
|
||
local theDeleteKey = SPECIAL_DELETE_MATRIX_PREF_KEY .. "1." .. ForceVersionNum .. ".0"
|
||
local theCleanFlag = CS.UnityEngine.PlayerPrefs.GetInt(theDeleteKey, 0)
|
||
CsLog.Debug("key:" .. theDeleteKey .. ", cleanFlag:" .. tostring(cleanFlag) .. ", force cleanFlag :" .. tostring(theCleanFlag))
|
||
|
||
if cleanFlag ~= 1 and (theCleanFlag ~= 1) then -- 首次检测当前版本、 且没经历过强删版本
|
||
for versionNum = ForceVersionNum - 1, 10, -1 do -- 经历过再之前版本 -- 属于旧包覆盖安装,需要强清资源
|
||
local lastDeleteKey = SPECIAL_DELETE_MATRIX_PREF_KEY .. "1." .. versionNum .. ".0"
|
||
local lastCleanFlag = CS.UnityEngine.PlayerPrefs.GetInt(lastDeleteKey, 0)
|
||
CsLog.Debug("[Download] Check Force Clean Key:" .. lastDeleteKey .. ", cleanFlag:" .. tostring(lastCleanFlag) .. ", " .. type(lastCleanFlag))
|
||
|
||
if lastCleanFlag == 1 then
|
||
isForceClean = true
|
||
CsLog.Debug("[Download] 过旧版本 需要全面清理资源, version:" .. lastDeleteKey)
|
||
|
||
-- 完成后增加强删版本的标记
|
||
CS.UnityEngine.PlayerPrefs.SetInt(theDeleteKey, 1)
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
CsLog.Debug("[Download] 上一版本资源key: " .. tostring(deleteKey) .. ", type: " .. tostring(ResFileType) .. ", checkClean: " .. tostring(checkClean) .. ", force:" .. tostring(isForceClean) .. ", CsInfo.Version:" .. tostring(CsInfo.Version))
|
||
|
||
local files = CS.XFileTool.GetFiles(DocumentFilePath .. "/" .. ResFileType)
|
||
|
||
local lastVerCount = 0
|
||
local otherCount = 0
|
||
local totalCount = 0
|
||
|
||
--是否启用IOS后台下载
|
||
--在启用时,由于IOS校验流程的统一需要,因此文件下载完可能还未校验,需要假设资源是完整的
|
||
--在以上条件下,需要合理估计仍然需要下载的文件大小,因此需要减去对仅未验证的文件的大小
|
||
local isUseIosDownloadService = (CS.XRemoteConfig.DownloadMethod == 0) and AppPathModule.IsIos()
|
||
|
||
for i = 0, files.Length - 1 do
|
||
local file = files[i]
|
||
local name = CS.XFileTool.GetFileName(file)
|
||
totalCount = totalCount + 1
|
||
|
||
local isIndex = IsDlcBuild and (string.sub(name,1,5) == INDEX) or (name == INDEX)
|
||
if isIndex then
|
||
goto CONTINUE
|
||
end
|
||
|
||
if checkClean then
|
||
if isForceClean or not NeedFileSet[name] then
|
||
CsLog.Debug("[Download] 清理上一版本资源" .. tostring(name) .. ", need:" .. tostring((not NeedFileSet[name])))
|
||
CS.XFileTool.DeleteFile(file)
|
||
lastVerCount = lastVerCount + 1
|
||
goto CONTINUE
|
||
end
|
||
end
|
||
-- 检查更新文件是否存在
|
||
local hasUpdated = false
|
||
|
||
local info = UpdateTable[name]
|
||
if info then
|
||
UpdateTable[name] = nil
|
||
UpdateTableCount = UpdateTableCount - 1
|
||
UpdateSize = UpdateSize - info[3]
|
||
hasUpdated = true
|
||
end
|
||
if NeedShowSelect then
|
||
local infoDlc = AllUpdateTable[name]
|
||
if infoDlc then
|
||
AllUpdateTable[name] = nil
|
||
AllUpdateTableCount = AllUpdateTableCount - 1
|
||
AllUpdateSize = AllUpdateSize - infoDlc[3]
|
||
hasUpdated = true
|
||
end
|
||
end
|
||
if hasUpdated then
|
||
goto CONTINUE
|
||
end
|
||
|
||
local nameWithOutExtension = CS.XFileTool.GetFileNameWithoutExtension(file)
|
||
if UpdateTable[nameWithOutExtension] then -- 下载时临时文件(name.download)将会保留
|
||
info = UpdateTable[nameWithOutExtension]
|
||
if isUseIosDownloadService then
|
||
if CS.XFileTool.GetFileExtension(file) == UNCHECKED_FILE_EXTENSION then
|
||
UpdateSize = UpdateSize - info[3]
|
||
end
|
||
end
|
||
goto CONTINUE
|
||
end
|
||
|
||
otherCount = otherCount + 1
|
||
CS.XFileTool.DeleteFile(file)
|
||
|
||
:: CONTINUE ::
|
||
end
|
||
|
||
CsLog.Debug(string.format("[Download] 资源清理 本地总数:%d, 清理上版本数:%d, 其他清理:%d, 需更新: %d, dlc需更新:%d",
|
||
totalCount, lastVerCount, otherCount, UpdateTableCount, AllUpdateTableCount))
|
||
|
||
if checkClean then
|
||
CsLog.Debug("[Download] 清理上一版本资源完成。")
|
||
CS.UnityEngine.PlayerPrefs.SetInt(deleteKey, 1)
|
||
CS.UnityEngine.PlayerPrefs.Save()
|
||
end
|
||
|
||
PrepareDownload()
|
||
end
|
||
|
||
local GetSizeAndUnit = function(size)
|
||
local unit = "k"
|
||
local num = size / 1024
|
||
if (num > 100) then
|
||
unit = "MB"
|
||
num = num / 1024
|
||
end
|
||
return unit,num
|
||
end
|
||
|
||
OnDoneSelect = function(isFullDownload)
|
||
DlcManager.DoneSelectDownloadPart(CsInfo.Version)
|
||
if isFullDownload then
|
||
DlcManager.SetAllNeedDownload()
|
||
UpdateTable = AllUpdateTable
|
||
end
|
||
|
||
DoPrepareDownload()
|
||
end
|
||
|
||
PrepareDownload = function()
|
||
if UpdateTableCount <= 0 and (not NeedShowSelect or AllUpdateTableCount <=0) then
|
||
OnCompleteResFilesInit()
|
||
return
|
||
end
|
||
|
||
--todo 如果是dlc打包,显示选择框,选择完重新下载
|
||
if NeedShowSelect then
|
||
CsGameEventManager:RegisterEvent(CS.XEventId.EVENT_LAUNCH_DONE_DOWNLOAD_SELECT, function(evt,data)
|
||
OnDoneSelect(data[0])
|
||
end)
|
||
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_SHOW_DOWNLOAD_SELECT,UpdateSize,AllUpdateSize)
|
||
else
|
||
DoPrepareDownload()
|
||
end
|
||
end
|
||
|
||
DoPrepareDownload = function()
|
||
local dict = {["type"] = ResFileType, ["version"] = NewVersion}
|
||
CS.XRecord.Record(dict, "80011", "StartDownloadNewFiles")
|
||
|
||
local unit,num = GetSizeAndUnit(UpdateSize)
|
||
-- 日服不做热更时网络状态判断
|
||
--if (UnityApplication.internetReachability == CS.UnityEngine.NetworkReachability.ReachableViaCarrierDataNetwork and UpdateSize > SIZE) then
|
||
--BDC
|
||
-- CS.XHeroBdcAgent.BdcUpdateGame("203", "1", "0")
|
||
-- local tmpStr = string.format("%0.2f%s%s", num, unit, CsApplication.GetText("UpdateCheck"))
|
||
-- CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"), tmpStr, CsApplication.Exit, function()
|
||
-- DownloadFiles()
|
||
-- end))
|
||
-- return
|
||
--end
|
||
|
||
--BDC
|
||
CS.XHeroBdcAgent.BdcUpdateGame("203", "1", "0")
|
||
local tmpStr = string.format("%s%0.2f %s", CsApplication.GetText("UpdateCheck"), num, unit) -- 海外调整热更文本 -- #104203 文本最后与单位新增一个空格
|
||
CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"), tmpStr, CsApplication.Exit, function()
|
||
DownloadFiles()
|
||
end))
|
||
return
|
||
end
|
||
|
||
local AndroidBackgroundDownload = function()
|
||
--android background download todo
|
||
--1.组建好一个数组,传给backgroud download组件,开始下载
|
||
--2.每帧获取下载状态,更新界面(当前下载文件,下载进度)
|
||
--3.重试状态
|
||
--4.下载完成状态
|
||
local urlPrefix = string.format("%s/%s/%s/", DocumentUrl, NewVersion, ResFileType)
|
||
local downloadDir = DocumentFilePath .. "/" .. ResFileType .. "/"
|
||
|
||
local allNameTable = {}
|
||
local allSha1Table = {}
|
||
local allSizeTable = {}
|
||
|
||
for name, info in pairs(UpdateTable) do
|
||
table.insert(allNameTable, info[1])
|
||
table.insert(allSha1Table, info[2])
|
||
table.insert(allSizeTable, info[3])
|
||
end
|
||
|
||
local names = table.concat(allNameTable,";")
|
||
local sha1s = table.concat(allSha1Table,";")
|
||
local sizes = table.concat(allSizeTable,";")
|
||
|
||
CsDownloadService:Download(urlPrefix, downloadDir, names, sha1s, TIMEOUT, RETRY, sizes)
|
||
|
||
local waitTimeCnt = 0
|
||
local updateInfoCb = nil
|
||
updateInfoCb = function()
|
||
-- 下载进度
|
||
local state = CsDownloadService:GetDownloadState()
|
||
local fileSize = CsDownloadService:GetCurrentFileSize()
|
||
local curDoneSize = CsDownloadService:GetCurrentDownloadSize()
|
||
if state == DownloadState.ING then
|
||
waitTimeCnt = 0
|
||
local updateProgress = UpdateSize == 0 and 0 or curDoneSize / UpdateSize
|
||
if updateProgress>1 then updateProgress =1 end
|
||
|
||
CsApplication.SetProgress(updateProgress)
|
||
if OnProgressCallback then
|
||
OnProgressCallback(updateProgress)
|
||
end
|
||
elseif state == DownloadState.FAIL or (state == DownloadState.NONE and waitTimeCnt > 20) then
|
||
CsTool.RemoveUpdateEvent(updateInfoCb)
|
||
local errMsg = CsDownloadService:GetExceptionInfo()
|
||
local name = CsDownloadService:GetCurrentFileName()
|
||
CsLog.Error("[Download] Android Download error, state error, state: " .. tostring(state)..", err:" .. errMsg .. ", name:" .. tostring(name) .. ", fileSize:" .. tostring(fileSize))
|
||
local exitCb = OnExitCallback or CsApplication.Exit
|
||
|
||
CsLog.Debug("[Download Android Backgroud] Istate " .. tostring(state) .. ",waitTimeCnt: " .. tostring(waitTimeCnt))
|
||
ShowStartErrorDialog("FileManagerInitFileTableDownloadError", exitCb, function()
|
||
CheckIndexFile()
|
||
end, CsApplication.GetText("Retry"))
|
||
|
||
elseif state == DownloadState.DONE then
|
||
CsLog.Debug("[Download Android Backgroud] Istate == DownloadState.DONE! ")
|
||
CsTool.RemoveUpdateEvent(updateInfoCb)
|
||
CompleteDownload()
|
||
elseif state == DownloadState.NONE then
|
||
waitTimeCnt = waitTimeCnt + CS.UnityEngine.Time.deltaTime
|
||
end
|
||
end
|
||
CsTool.AddUpdateEvent(updateInfoCb)
|
||
end
|
||
|
||
local IosBackgroundDownload = function()
|
||
local urlPrefix = string.format("%s/%s/%s", DocumentUrl, NewVersion, ResFileType)
|
||
CS.XIOSDownloadConfig.PrepareCNDList(urlPrefix);
|
||
local taskArr = {}
|
||
for _,v in pairs(UpdateTable) do
|
||
table.insert(taskArr, string.format("%s %s %s", v[1], v[3], v[2]))
|
||
end
|
||
local taskInfo = table.concat(taskArr,"\n")
|
||
CS.XIOSDownloadCustomer.Instance:SetTaskInfo(taskInfo)
|
||
local manager = CS.XIOSDownloadManager.Instance
|
||
local verifier = CS.XIOSDownloadVerifier.Instance
|
||
|
||
local updateEvent
|
||
updateEvent = function()
|
||
if manager.StateInt == IosDownloadState.PreparingLocalFiles then
|
||
--Nothing Here
|
||
elseif manager.StateInt == IosDownloadState.PreparingDownload then
|
||
--Nothing Here
|
||
elseif manager.StateInt == IosDownloadState.Downloading or manager.StateInt == IosDownloadState.AppendDownloading then
|
||
if manager.StateInt == IosDownloadState.AppendDownloading and manager.TotalTaskBytes ~= 0 then
|
||
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, manager.TotalTaskBytes)
|
||
end
|
||
local progress = manager.CurDownloadedBytes / manager.TotalTaskBytes;
|
||
if progress and progress ~= math.huge then
|
||
CsApplication.SetProgress(progress)
|
||
end
|
||
if OnProgressCallback then
|
||
OnProgressCallback(progress)
|
||
end
|
||
elseif manager.StateInt == IosDownloadState.Verifying then
|
||
CS.XGameEventManager.Instance:Notify(CS.XEventId.EVENT_LAUNCH_START_LOADING)
|
||
CsApplication.SetMessage(string.format("正在校验中(%d/%d)", verifier.CurrentCheckCount, verifier.TotalNeedCheckCount))
|
||
CsApplication.SetProgress(verifier.CurrentCheckCount / verifier.TotalNeedCheckCount)
|
||
elseif manager.StateInt == IosDownloadState.Finished then
|
||
CsTool.RemoveUpdateEvent(updateEvent)
|
||
manager:Clear()
|
||
CompleteDownload()
|
||
end
|
||
end
|
||
|
||
manager:Prepare()
|
||
|
||
manager:SetDownloadErrorHandler(function(file)
|
||
local exitCb = OnExitCallback or CsApplication.Exit
|
||
ShowStartErrorDialog("FileManagerInitFileTableDownloadError", exitCb, function()
|
||
manager:ContinueDownloading()
|
||
end, CsApplication.GetText("Retry")) -- 重试
|
||
end)
|
||
|
||
CsTool.AddUpdateEvent(updateEvent)
|
||
end
|
||
|
||
local TraditionalDownload = function()
|
||
local updateFileText = CsApplication.GetText("UpdateFile")
|
||
local iter, t, key = pairs(UpdateTable)
|
||
local info
|
||
local iterKey = nil
|
||
local Loop
|
||
Loop = function()
|
||
key, info = iter(t, iterKey)
|
||
|
||
if not key then
|
||
CompleteDownload()
|
||
return
|
||
end
|
||
|
||
local name = info[1]
|
||
local sha1 = info[2] -- 补丁index中记录的sha1,和下载后文件sha1对比
|
||
|
||
CsApplication.SetMessage(updateFileText .. ": " .. name)
|
||
|
||
local str = string.format("%s/%s/%s/%s", DocumentUrl, NewVersion, ResFileType, name)
|
||
local str2 = DocumentFilePath .. "/" .. ResFileType .. "/" .. name
|
||
local downloader = CS.XUriPrefixDownloader(str, str2, true, sha1, TIMEOUT, RETRY, READ_TIMEOUT)
|
||
local size = 0
|
||
|
||
CsTool.WaitCoroutinePerFrame(downloader:Send(), function(isComplete)
|
||
if not isComplete then
|
||
--
|
||
CurrentUpdateSize = CurrentUpdateSize - size + downloader.CurrentSize
|
||
size = downloader.CurrentSize
|
||
local updateProgress = UpdateSize == 0 and 0 or CurrentUpdateSize / UpdateSize
|
||
CsApplication.SetProgress(updateProgress)
|
||
|
||
if OnProgressCallback then
|
||
OnProgressCallback(updateProgress)
|
||
end
|
||
else
|
||
if downloader.State ~= CS.XDownloaderState.Success then
|
||
local msg = "[Download] error, state error, state: " .. tostring(downloader.State)
|
||
CsLog.Error(msg)
|
||
local dict = {}
|
||
dict.file_name = name
|
||
dict.file_size = info[3]
|
||
CS.XRecord.Record(dict, "80007", "XFileManagerDownloadError")
|
||
local exitCb = OnExitCallback or CsApplication.Exit
|
||
|
||
ShowStartErrorDialog("FileManagerInitFileTableDownloadError",exitCb, function()
|
||
Loop()
|
||
end, CsApplication.GetText("Retry")) -- 重试
|
||
return
|
||
end
|
||
|
||
CurrentUpdateSize = CurrentUpdateSize - size + downloader.Size
|
||
iterKey = key
|
||
Loop()
|
||
end
|
||
end)
|
||
end
|
||
Loop()
|
||
end
|
||
|
||
DownloadFiles = function()
|
||
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, UpdateSize)
|
||
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Resource_Download_Start)
|
||
CS.XHeroBdcAgent.BdcUpdateGame("204", "1", "0")
|
||
CsApplication.SetMessage(CsApplication.GetText("GameUpdate"))
|
||
CsApplication.SetProgress(0)
|
||
|
||
local isUseAndroidDownloadService = (CS.XRemoteConfig.DownloadMethod == 0) and AppPathModule.IsAndroid()
|
||
local isUseIosDownloadService = (CS.XRemoteConfig.DownloadMethod == 0) and AppPathModule.IsIos()
|
||
|
||
if isUseAndroidDownloadService and ResFileType == RES_FILE_TYPE.MATRIX_FILE then
|
||
CsLog.Debug("安卓后台下载模式")
|
||
AndroidBackgroundDownload()
|
||
elseif isUseIosDownloadService and ResFileType == RES_FILE_TYPE.MATRIX_FILE then
|
||
CsLog.Debug("IOS后台下载模式")
|
||
IosBackgroundDownload()
|
||
else
|
||
CsLog.Debug("传统下载模式")
|
||
TraditionalDownload()
|
||
end
|
||
end
|
||
|
||
CompleteDownload = function()
|
||
CsApplication.SetProgress(1)
|
||
local dict = {["type"] = ResFileType, ["version"] = NewVersion}
|
||
CS.XRecord.Record(dict, "80012", "DownloadNewFilesEnd")
|
||
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Resource_Download_End)
|
||
OnCompleteResFilesInit()
|
||
end
|
||
|
||
OnCompleteResFilesInit = function()
|
||
local urlTable = {}
|
||
|
||
if IsDlcBuild then
|
||
if AllFileTableDlc then
|
||
for asset, info in pairs(AllFileTableDlc) do
|
||
urlTable[asset] = DocumentFilePath .. "/" .. ResFileType .. "/" .. info[1]
|
||
end
|
||
XLaunchDlcManager.DoneDownload()
|
||
end
|
||
else
|
||
if DocumentIndexTable then
|
||
for asset, info in pairs(DocumentIndexTable) do
|
||
urlTable[asset] = DocumentFilePath .. "/" .. ResFileType .. "/" .. info[1]
|
||
end
|
||
end
|
||
end
|
||
|
||
for asset, info in pairs(ApplicationIndexTable) do
|
||
if not urlTable[asset] or HasLocalFiles then -- 包体资源优先于本地测试资源
|
||
urlTable[asset] = ApplicationFilePath .. "/" .. ResFileType .. "/" .. info[1]
|
||
end
|
||
end
|
||
|
||
ApplicationIndexTable = nil
|
||
DocumentIndexTable = nil
|
||
CurrentFileTable = nil
|
||
|
||
DlcIndexTable = nil
|
||
AllFileTableDlc = nil
|
||
|
||
if NeedShowSelect then
|
||
CsGameEventManager:RemoveEvent(CS.XEventId.EVENT_LAUNCH_DONE_DOWNLOAD_SELECT, OnNotifyEvent)
|
||
XLaunchDlcManager.DoneSelectDownloadPart(CsInfo.Version) -- 下载完成后才记录选择记录
|
||
end
|
||
|
||
-- 完成回调
|
||
if OnCompleteCallback then
|
||
OnCompleteCallback(urlTable, NeedUpdate, HasLocalFiles)
|
||
end
|
||
end
|
||
|
||
return XLaunchFileModule
|
||
end
|
||
|
||
return module_creator |