PGRData/Script/launch/XLaunchFileModule.lua
2024-09-01 22:49:41 +02:00

1412 lines
58 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 LAUNCH_PLAYED_CG = "LAUNCH_PLAYED_CG"
local UNCHECKED_FILE_EXTENSION = ".unchecked"
local module_creator = function()
---@class XLaunchFileModule 游戏启动文件类
local XLaunchFileModule = {}
local MESSAGE_PACK_MODULE_NAME = "XLaunchCommon/XMessagePack"
require(MESSAGE_PACK_MODULE_NAME)
---@type XLaunchDlcManager
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 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 DownloadedMap = {}
--
local HasLocalFiles = false
local IsDebugBuild = CS.XApplication.Debug
local IsPause = false
local CurrentDownloader
local TipsOnce = false
-- Local Function
local CheckIndexFile
local ResolveResIndex
local PrepareDownload
local DownloadFiles
local StopDownloading
local CompleteDownload
local OnCompleteResFilesInit
local LoadIndexTable
local LoadIndexTableWithDlcInfo
local InitDocumentIndex
local DownloadDlcIndexs
local DoPrepareDownload
local OnNotifyEvent
local DoRecord
local RemoveEvents
local IsFullDownloadSelectType
-- DLC分包相关
local DLC_BASE_INDEX = 0 -- 基础包
local DLC_COMMON_INDEX = -1 -- 通用资源
local IsDlcBuild = CsInfo.IsDlcBuild
local IsInGame = false
local NeedShowSelect = false
local DlcNeedFileMap = nil
local CheckFixDlcRecord
-- 本地测试
local NeedLaunchTest = CS.XResourceManager.NeedLaunchTest -- 调试用debug环境下测试下载流程 ("Tools/本地下载测试/开启")
local LaunchTestPath = UnityApplication.dataPath .. "/../../../Product/Temp/LocalCdn"
local LaunchTestDirApp = UnityApplication.dataPath .. "/../../../Product/Temp/LocalDirApp"
local LaunchTestDirDoc = UnityApplication.dataPath .. "/../../../Product/Temp/LocalDirDoc"
XLaunchFileModule.LaunchTestDirDoc = LaunchTestDirDoc
local InitDocumentIndexTest
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()
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()
if IsDlcBuild then
NeedShowSelect = XLaunchDlcManager.NeedShowSelect(CsInfo.Version) -- 每个大版本只会弹出一次选择更新,小更新沿用选择结果
end
end
if CS.XRemoteConfig.IsHideFunc then
--NeedUpdate = false
end
CsLog.Debug("[Download] 开始检查更新 NeedUpdate:"..tostring(NeedUpdate)..", type:"..ResFileType .. ", NeedShowSelect:" ..tostring(NeedShowSelect) .. ", IsDlcBuild:" .. tostring(IsDlcBuild))
if IsInGame or NeedLaunchTest then
NeedUpdate = true
ResolveResIndex()
return
end
CheckIndexFile()
end
function XLaunchFileModule.SetIsInGame(isInGame)
IsInGame = isInGame
end
-- function XLaunchFileModule.GetOffset()
-- return OFFSET
-- end
DownloadDlcIndexs = function(cb)
if not IsDlcBuild then
cb()
return
end
if not DocumentIndexTable then
DocumentIndexTable, DlcIndexTable = LoadIndexTableWithDlcInfo(DocumentIndexPath)
end
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)
CsApplication.SetMessage(CsApplication.GetText("CheckDlcIndex"))--"分析资源..."
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 url = string.format("%s/%s/%s/%s", DocumentUrl, NewVersion, ResFileType, name)
local path = DocumentFilePath .. "/" .. ResFileType .. "/" .. name
local downloader = CS.XUriPrefixDownloader(url, path, cache, sha1, TIMEOUT, RETRY, READ_TIMEOUT)
local size = 0
--CsLog.Debug("DocumentUrl:"..DocumentUrl)
--CsLog.Debug("url:"..url)
--CsLog.Debug("path:"..path)
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
DoRecord(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 then
local isCorrect = CS.XFileTool.CheckSha1(documentFilePath, sha1)
CsLog.Debug("[Download] HasUpdated:" .. tostring(HasUpdated) .. ", isCorrect:" .. tostring(isCorrect))
if isCorrect then
ResolveResIndex()
return
end
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
AppVersionModule.UpdateDocVersion()
ResolveResIndex()
end
end
end)
end
-- {[assetPath] = value{[1] = Name, [2] = Sha1, [3] = Size}, ... }
LoadIndexTable = function(indexPath)
if NeedLaunchTest then
if not CS.System.IO.File.Exists(indexPath) then
return {}
end
end
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 {}
assetBundle:Unload(true)
return indexTable, dlcIndexTable
end
return nil
end
local SetDlcTable
-- 解析doc目录下index
InitDocumentIndex = function()
if NeedLaunchTest then
InitDocumentIndexTest()
else
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 = LoadIndexTableWithDlcInfo(DocumentIndexPath)
else
DocumentIndexTable = LoadIndexTable(DocumentIndexPath) -- {[assetPath] = value{[1] = Name, [2] = Sha1, [3] = Size}, ... }
end
end
end
CurrentFileTable = {} -- 当前需下载资源
AllFileTableDlc = {} -- DLC完整资源
local countApp = 0
local countExist = 0
NeedFileSet = {} -- 需下载标记
DlcNeedFileMap = {} -- DLC id对应所需资源
local countAll = 0
-- 基础补丁
for asset, info in pairs(DocumentIndexTable) do
countAll = countAll + 1
NeedFileSet[info[1]] = true
CurrentFileTable[asset] = info
AllFileTableDlc[asset] = info
end
-- 统计资源
if IsDlcBuild then
if ResFileType == RES_FILE_TYPE.MATRIX_FILE and DlcIndexTable then
XLaunchDlcManager.Init(DlcIndexTable)
XLaunchDlcManager.SetDlcIndexInfo(DLC_BASE_INDEX, DocumentIndexTable)
-- 使用新分包构建方式后,暂时没有通用资源包了,设置为空
XLaunchDlcManager.SetDlcIndexInfo(DLC_COMMON_INDEX, {})
local dlcUseAppCount = 0
local dlcTableMap = {} -- 游戏内下载用
local needDownloadMap = {} -- 调试用
local checkFullDownload = IsFullDownloadSelectType()
local isSelectFull = true
if not IsInGame then --非游戏内
-- 1:基础资源 2:完整资源
local downloadMode = XLaunchDlcManager.IsFullDownload(CsInfo.Version) and 2 or 1
isSelectFull = downloadMode == 2
end
-- 分包补丁
for dlcId, dlcTable in pairs(DlcIndexTable) do
dlcTableMap[dlcId] = dlcTable
XLaunchDlcManager.SetDlcIndexInfo(dlcId, dlcTable)
local needDownloadDlc = (isSelectFull and XLaunchDlcManager.CheckNeedDownload(dlcId, NeedShowSelect)) or checkFullDownload
needDownloadMap[dlcId] = needDownloadDlc
local fileMap = {}
for asset, info in pairs(dlcTable) do
NeedFileSet[info[1]] = true
if ApplicationIndexTable[asset] and ApplicationIndexTable[asset][1] == info[1]then
dlcUseAppCount = dlcUseAppCount + 1
else
if needDownloadDlc then
CurrentFileTable[asset] = info
end
AllFileTableDlc[asset] = info
fileMap[info[1]] = info
end
end
DlcNeedFileMap[dlcId] = fileMap
end
SetDlcTable(dlcTableMap)
if IsDebugBuild then
local logTab = {}
for dlcId, need in pairs(needDownloadMap) do
table.insert(logTab, dlcId .. ":" .. tostring(need))
end
CsLog.Debug("[DLC] needDownloadMap: " .. tostring(table.concat(logTab, "\n")))
end
end
-- 剔除包内已有资源需asset与Name都对应
for asset, info in pairs(ApplicationIndexTable) do
local value = AllFileTableDlc[asset]
countApp = countApp + 1
if value and value[1] == info[1] then
countExist = countExist + 1
AllFileTableDlc[asset] = nil
CurrentFileTable[asset] = nil
end
end
else
CurrentFileTable = DocumentIndexTable
-- 剔除包内已有资源需asset与Name都对应
for asset, info in pairs(ApplicationIndexTable) do
countApp = countApp + 1
local value = CurrentFileTable[asset]
if value and value[1] == info[1] then
countExist = countExist + 1
CurrentFileTable[asset] = nil
end
end
end
CsLog.Debug("[Download] 基础资源总量:" .. countAll .. "app包内资源数量记录/存在):" .. countApp .. "/" .. countExist)
end
SetDlcTable = function(dlcTableMap)
local documentFilePath = DocumentFilePath .. "/" .. ResFileType .. "/"
if NeedLaunchTest then
documentFilePath = LaunchTestDirDoc .. "/" .. ResFileType .. "/"
end
local needLog = IsDebugBuild and CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.WindowsEditor
local DownloadedMark = {}
local logTab = {}
for dlcId, dlcTable in pairs(dlcTableMap) do
local count, clearCount, downloadedCount = 0, 0, 0
local size, clearSize, downloadedSize = 0, 0, 0
for asset, info in pairs(dlcTable) do
count = count + 1
size = size + info[3]
local name = info[1]
local value = ApplicationIndexTable[asset]
if value and value[1] == name then -- 包内
clearCount = clearCount + 1
clearSize = clearSize + info[3]
dlcTable[asset] = nil -- 不统计到总大小
elseif needLog then
if DownloadedMark[name] == nil then
DownloadedMark[name] = CS.System.IO.File.Exists(documentFilePath .. name) -- 已下载
end
if DownloadedMark[name] then
local downloaded = DownloadedMark[name]
downloadedCount = downloadedCount + 1
downloadedSize = downloadedSize + info[3]
end
end
end
if IsDebugBuild then
table.insert(logTab, "[DLC] DLC .." .. dlcId
.. ", appb包内 + doc已下载 = 总 - 余量,数量" .. clearCount .. " + " .. downloadedCount.. " = " .. count .. " - " .. (count-clearCount-downloadedCount)
.. ", 大小: " .. math.ceil(clearSize/1024/1024) .."mb"
.. " + " .. math.ceil(downloadedSize/1024/1024) .. "mb"
.. " = " .. math.ceil(size/1024/1024) .. "mb"
.. " - " .. math.ceil((size - clearSize - downloadedSize)/1024/1024) .. "mb)")
end
XLaunchDlcManager.SetDlcIndexInfo(dlcId, dlcTable) -- 记录总需下载资源
end
if IsDebugBuild and #logTab > 0 then
CsLog.Debug("DLC各分包下载情况\n" .. table.concat(logTab, "\n"))
end
DownloadedMark = nil
end
ResolveResIndex = function()
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Version_Checking_End)
local applicationIndexPath = ApplicationFilePath .. "/" .. ResFileType .. "/" .. INDEX
if NeedLaunchTest and IsDlcBuild then
applicationIndexPath = LaunchTestDirApp .. "/" .. ResFileType .. "/" .. INDEX
end
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]
DoRecord(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 IsDlcBuild then
for _, info in pairs(AllFileTableDlc) do
AllUpdateTable[info[1]] = info
AllUpdateTableCount = AllUpdateTableCount + 1
AllUpdateSize = AllUpdateSize + info[3]
end
end
CsLog.Debug(string.format("[Download] UpdateSize: %d(mb), UpdateTableCount: %d, AllUpdateSize: %d(mb), AllUpdateTableCount: %d", math.ceil(UpdateSize/1024/1024), UpdateTableCount, math.ceil(AllUpdateSize/1024/1024), AllUpdateTableCount))
local deleteKey = SPECIAL_DELETE_MATRIX_PREF_KEY .. tostring(AppVersionModule.GetAppVersion())
local isMatrix = ResFileType == RES_FILE_TYPE.MATRIX_FILE
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
if NeedLaunchTest then
files = CS.XFileTool.GetAllFiles(LaunchTestDirDoc .. "/" .. ResFileType)
else
files = CS.XFileTool.GetFiles(DocumentFilePath .. "/" .. ResFileType)
end
local lastVerCount = 0
local otherCount = 0
local totalCount = 0
--是否启用IOS后台下载
--在启用时由于IOS校验流程的统一需要因此文件下载完可能还未校验需要假设资源是完整的
--在以上条件下,需要合理估计仍然需要下载的文件大小,因此需要减去对仅未验证的文件的大小
local isUseIosDownloadService = (CS.XRemoteConfig.DownloadMethod == 0) and AppPathModule.IsIos()
DownloadedMap = {}
for i = 0, files.Count - 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 NeedFileSet[name] == nil then
CsLog.Debug("[Download] 清理上一版本资源" .. tostring(name) .. ", need:" .. tostring(NeedFileSet[name] ~= nil))
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 IsDlcBuild then
local infoDlc = AllUpdateTable[name]
if infoDlc then
AllUpdateTable[name] = nil
AllUpdateTableCount = AllUpdateTableCount - 1
AllUpdateSize = AllUpdateSize - infoDlc[3]
DownloadedMap[name] = true
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
CsLog.Debug("[Download] .. other Clean:" .. tostring(file))
CS.XFileTool.DeleteFile(file)
:: CONTINUE ::
end
CsLog.Debug(string.format("[Download] 资源清理 本地总数:%d, 清理上版本数:%d, 其他清理:%d", totalCount, lastVerCount, otherCount))
CsLog.Debug(string.format("[Download] 准备下载,本次需下载数: %d(%dmb) dlc未下载%d(%dmb)",
UpdateTableCount, math.ceil(UpdateSize/1024/1024), AllUpdateTableCount, math.ceil(AllUpdateSize/1024/1024)))
if checkClean then
CsLog.Debug("[Download] 清理上一版本资源完成。")
CS.UnityEngine.PlayerPrefs.SetInt(deleteKey, 1)
CS.UnityEngine.PlayerPrefs.Save()
end
if IsDlcBuild and isMatrix then
XLaunchDlcManager.SetDownloadedMap(DownloadedMap)
CheckFixDlcRecord()
end
PrepareDownload()
end
local GetDlcMapCountSize = function(map)
local num = 0
local size = 0
for _, info in pairs(map) do
num = num + 1
size = size + info[3]
end
return num, size
end
-- 检查dlc文件是否存在
CheckFixDlcRecord = function()
if IsInGame then
return
end
local nums = {}
local sizes = {}
if IsDebugBuild then
-- 总况
for dlcId, map in pairs(DlcNeedFileMap) do
local num, size = GetDlcMapCountSize(map)
nums[dlcId] = num
sizes[dlcId] = size
end
end
local logTab = {}
-- 剔除通用
DlcNeedFileMap[DLC_COMMON_INDEX] = nil
-- 剔除已下载
for dlcId, map in pairs(DlcNeedFileMap) do
local num, num2, num3, size = 0, 0, 0, 0
for name, info in pairs(map) do
num2 = num2 + 1
if DownloadedMap[name] then
map[name] = nil
num = num + 1
size = size + info[3]
else
num3 = num3 + 1
end
end
if IsDebugBuild then
table.insert(logTab, "dlc " .. dlcId .. ", 已下载数量:" .. num .. "(总" .. num2 .. " - 未下载" .. num3 .. "), 已下载大小:".. math.ceil(size/1024/1024).."mb")
end
end
if IsDebugBuild then
CsLog.Debug("[DLC] ==== dlc检测前剔除 " .. table.concat(logTab, "\n"))
end
-- 修正下载记录
for dlcId, map in pairs(DlcNeedFileMap) do
local downloaded = XLaunchDlcManager.HasDownloadedDlc(dlcId)
if downloaded then
if next(map) then
if IsDebugBuild then
local num, size = GetDlcMapCountSize(map)
CsLog.Error("[DLC]dlc_" .. tostring(dlcId) .. "检测异常:记录为已下载,但缺失本地文件,修正为未下载,需下载数量:" .. num .. "/" .. tostring(nums[dlcId])
..", ".. math.ceil(size/1024/1024) .. "/" .. math.ceil(sizes[dlcId]/1024/1024) .."mb" .. ',' .. size .. "/" .. sizes[dlcId])
else
CsLog.Error(dlcId .. "记录:[已下载],但仍需下载,修复为:[未下载]")
end
XLaunchDlcManager.FixDownloadedDlc(dlcId, false)
elseif IsDebugBuild then
CsLog.Debug("[DLC]dlc_" .. tostring(dlcId) .. "检测ok全部下载数量" .. tostring(nums[dlcId]))
end
else
if not next(map) then
if IsDebugBuild then
CsLog.Error("[DLC]dlc_" .. tostring(dlcId) .. "检测异常:记录为未下载,但已下载完成,修正记录。数量:" .. tostring(nums[dlcId]))
else
CsLog.Error(dlcId .. "记录[未下载],但无需下载,修复为[已下载]")
end
XLaunchDlcManager.FixDownloadedDlc(dlcId, true)
elseif IsDebugBuild then
local num, size = GetDlcMapCountSize(map)
CsLog.Debug("[DLC]dlc_" .. tostring(dlcId) .. "检测ok未下载数量:" .. num .. "/" .. tostring(nums[dlcId])
..", ".. math.ceil(size/1024/1024) .. "/" .. math.ceil(sizes[dlcId]/1024/1024) .."mb")
end
end
end
CsLog.Debug("[DLC] 检查DLC资源完成。")
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
local InitFullDownload = function()
XLaunchDlcManager.SetAllLaunchDownloadRecord()
UpdateTable = AllUpdateTable
UpdateSize = AllUpdateSize
end
local OnDoneSelect = function(isFullDownload)
XLaunchDlcManager.DoneSelect(CsInfo.Version)
XLaunchDlcManager.SetIsFullDownload(CsInfo.Version, isFullDownload)
if isFullDownload then
InitFullDownload()
else
if UpdateTableCount <= 0 then
OnCompleteResFilesInit()
return
end
end
DoPrepareDownload()
end
PrepareDownload = function()
CsLog.Debug("PrepareDownload, UpdateTableCount:" .. UpdateTableCount .. ", NeedShowSelect:" .. tostring(NeedShowSelect) .. ", AllUpdateTableCount:" .. AllUpdateTableCount .. ", IsInGame:"..tostring(IsInGame))
if UpdateTableCount <= 0 and (not NeedShowSelect or AllUpdateTableCount <=0) then
OnCompleteResFilesInit()
return
end
--todo 如果是dlc打包显示选择框选择完重新下载
if not IsInGame and NeedShowSelect then
OnNotifyEvent = function(evt, data)
OnDoneSelect(data[0])
end
CsGameEventManager:RegisterEvent(CS.XEventId.EVENT_LAUNCH_DONE_DOWNLOAD_SELECT, OnNotifyEvent)
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_SHOW_DOWNLOAD_SELECT,UpdateSize,AllUpdateSize)
else
DoPrepareDownload()
end
end
DoPrepareDownload = function()
-- 分包且禁用,则全部下载
if IsDlcBuild and IsFullDownloadSelectType() then
InitFullDownload()
end
-- 1:基础资源 2:完整资源
local downloadMode = XLaunchDlcManager.IsFullDownload(CsInfo.Version) and 2 or 1
local dict = {["type"] = ResFileType, ["version"] = NewVersion, ["size"] = UpdateSize, ["mode"] = downloadMode }
DoRecord(dict, "80011", "StartDownloadNewFiles")
local unit,num = GetSizeAndUnit(UpdateSize) -- todo updateSize算上launch+matrix只需launch弹出一次
if ResFileType == RES_FILE_TYPE.MATRIX_FILE and not IsInGame and not TipsOnce then
TipsOnce = true
local sizeTxt = string.format("%0.2f%s", num, unit)
local envTxt = ""
local totalTxt = CsApplication.GetText("UpdateTips")
if UnityApplication.internetReachability == CS.UnityEngine.NetworkReachability.ReachableViaCarrierDataNetwork then
envTxt = CsApplication.GetText("CarrierTxt")
else
envTxt = CsApplication.GetText("WifiTxt")
end
CS.XHeroBdcAgent.BdcUpdateGame("203", "1", "0")
local tmpStr = string.format(totalTxt, sizeTxt, envTxt)
local cancelCB = CsApplication.Exit
-- CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"), tmpStr, cancelCB, function()
-- DownloadFiles()
-- end))
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_DIALOG, tmpStr, cancelCB, function()
DownloadFiles()
end)
else
DownloadFiles()
end
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
local lastProgress = 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 lastProgress ~= updateProgress and OnProgressCallback then
lastProgress = updateProgress
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()
RemoveEvents()
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
local lastProgress = nil
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 and progress == progress then -- NAN用相等判断
CsApplication.SetProgress(progress)
end
if lastProgress ~= progress and OnProgressCallback then
lastProgress = progress
OnProgressCallback(progress)
end
elseif manager.StateInt == IosDownloadState.Verifying then
CS.XGameEventManager.Instance:Notify(CS.XEventId.EVENT_LAUNCH_START_LOADING)
CsApplication.SetMessage(string.format(CsApplication.GetText("Verifying"), verifier.CurrentCheckCount, verifier.TotalNeedCheckCount)) -- 正在校验中(%d/%d)
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()
if ResFileType == RES_FILE_TYPE.LAUNCH_MODULE then
for _, info in pairs(UpdateTable) do
local name = info[1]
local ext = CS.XFileTool.GetFileExtension(name)
if string.find(ext, "usm") then
CsApplication.SetMessage(CsApplication.GetText("PVDownloading")) -- "PV下载中..."
break
end
end
end
local count = 0
-- local updateFileText = CsApplication.GetText("UpdateFile")
local iter, t, key = pairs(UpdateTable)
local info
local iterKey = nil
local Loop
local useCache = true
local lastProgress = nil
local currentUpdateSize = 0
Loop = function()
key, info = iter(t, iterKey)
-- print((count + 1) .. "/" .. UpdateTableCount .. "、IsPause :" .. tostring(IsPause))
if IsPause then
return
end
if not key then
CompleteDownload()
return
end
count = count + 1
local name = info[1]
local sha1 = info[2] -- 补丁index中记录的sha1和下载后文件sha1对比
local url = string.format("%s/%s/%s/%s", DocumentUrl, NewVersion, ResFileType, name)
local path = DocumentFilePath .. "/" .. ResFileType .. "/" .. name
-- CsApplication.SetMessage(updateFileText .. ": " .. name)
if NeedLaunchTest then
url = ResFileType .. "/" .. name
path = LaunchTestDirDoc .. "/" .. ResFileType .. "/" .. name
end
local downloader = CS.XUriPrefixDownloader(url, path, useCache, sha1, TIMEOUT, RETRY, READ_TIMEOUT)
CurrentDownloader = downloader
local size = 0
CsTool.WaitCoroutinePerFrame(downloader:Send(), function(isComplete)
if not isComplete then
--
currentUpdateSize = currentUpdateSize + (downloader.CurrentSize - size)
size = downloader.CurrentSize
local updateProgress = UpdateSize == 0 and 0 or currentUpdateSize / UpdateSize
CsApplication.SetProgress(updateProgress)
if lastProgress ~= updateProgress and OnProgressCallback then
lastProgress = updateProgress
-- print("... process:" .. updateProgress .. ", currentUpdateSize/UpdateSize:" .. math.ceil(currentUpdateSize/1024/1024) .."mb/" .. math.ceil(UpdateSize/1024/1024) .."mb, ".. currentUpdateSize .. "/" .. UpdateSize)
OnProgressCallback(updateProgress)
end
else
if downloader.State ~= CS.XDownloaderState.Success then
if downloader.State == CS.XDownloaderState.Stop then
CsLog.Debug("Stop Downloading.")
return
end
local msg = "[Download] error, state error, state: " .. tostring(downloader.State)
CsLog.Error(msg)
local dict = {}
dict.file_name = name
dict.file_size = info[3]
DoRecord(dict, "80007", "XFileManagerDownloadError")
local exitCb = OnExitCallback or CsApplication.Exit
local errorCode = IsInGame and "FileManagerInitFileTableInGameDownloadError" or "FileManagerInitFileTableDownloadError"
ShowStartErrorDialog(errorCode, exitCb, function()
Loop()
end, CsApplication.GetText("Retry")) -- 重试
return
end
if IsDlcBuild then
XLaunchDlcManager.SetDownloadedFile(name, true)
end
currentUpdateSize = currentUpdateSize - size + downloader.Size
iterKey = key
Loop()
end
end)
end
Loop()
end
local ParallelDownload = function()
local lastProgress = nil
local downloadManager = CS.XNewDownloadManager
downloadManager.Init()
downloadManager.Prepare()
-- downloadManager.AddWatcher()
for _name, info in pairs(UpdateTable) do
local name = info[1]
local sha1 = info[2] -- 补丁index中记录的sha1和下载后文件sha1对比
local url = string.format("%s/%s/%s/%s", DocumentUrl, NewVersion, ResFileType, name)
local path = DocumentFilePath .. "/" .. ResFileType .. "/" .. name
downloadManager.AppendTask(url, path, info[3], sha1)
end
local DownloadState = CS.XDownloadManagerState
local progress = CS.XDownloadProgress
local exitCb = OnExitCallback or CsApplication.Exit
local updateFunc
updateFunc = function()
if downloadManager.State == DownloadState.Downloading then
local p = progress.CurrentDownloadSize / progress.TotalDownloadSize
CsApplication.SetProgress(p)
if lastProgress ~= p and OnProgressCallback then
lastProgress = p
OnProgressCallback(p)
end
elseif downloadManager.State == DownloadState.CompleteError then
CsTool.RemoveUpdateEvent(updateFunc)
ShowStartErrorDialog("FileManagerInitFileTableDownloadError", exitCb, function()
downloadManager.RePrepareFailedTask()
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, progress.TotalDownloadSize)
downloadManager.Start()
CsTool.AddUpdateEvent(updateFunc)
end, CsApplication.GetText("Retry")) -- 重试
elseif downloadManager.State == DownloadState.Complete then
CsTool.RemoveUpdateEvent(updateFunc)
downloadManager.Stop()
CompleteDownload()
else
return
end
end
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, progress.TotalDownloadSize)
downloadManager.SetTaskFinish()
downloadManager.Start()
CsTool.AddUpdateEvent(updateFunc)
end
-- 是否需要播放cg名字+大版本号)
local function CheckPlayCG()
if IsInGame then
return
end
local needCGBtn = (ResFileType == RES_FILE_TYPE.MATRIX_FILE)
local needPlayCG = false
local videoUrl = "null"
if needCGBtn then
videoUrl = CS.XAudioManager.LaunchVideoAsset
local hasVideo = (videoUrl ~= "" and videoUrl ~= "null")
if hasVideo then
local videoName = CS.XFileTool.GetFileNameWithoutExtension(videoUrl)
local newRecord = videoName .. "_" .. tostring(AppVersionModule.GetAppVersion())
local oldRecord = CS.UnityEngine.PlayerPrefs.GetString(LAUNCH_PLAYED_CG, "")
if newRecord ~= oldRecord then
CS.UnityEngine.PlayerPrefs.SetString(LAUNCH_PLAYED_CG, newRecord)
needPlayCG = true
end
local bundleName = CS.XResourceManager.GetBundleUrl(videoUrl);
videoUrl = CS.XBundleManager.GetFile(bundleName)
if not videoUrl then
needCGBtn = false
else
if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then
local path = videoUrl
local streamingAssetPath = CS.UnityEngine.Application.streamingAssetsPath
local len = string.len(streamingAssetPath)
local prefix = string.sub(videoUrl, 0, len)
-- 若pv在包内对路径修正为 resource/launch/xxx.usm
if prefix == streamingAssetPath then
videoUrl = string.sub(videoUrl, len + 2)
end
end
end
print("[Audio] Need Play CG, newRecord:" .. tostring(newRecord) .. ", oldRecord:" .. tostring(oldRecord) .. ", videoUrl:" .. tostring(videoUrl))
else
needCGBtn = false
end
print("[Audio] Need Play CG:" .. tostring(needPlayCG) .. ", hasVideo:" .. tostring(hasVideo) .. ", videoUrl:" .. tostring(videoUrl))
end
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_CG, needCGBtn, needPlayCG, videoUrl)
end
DownloadFiles = function()
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, UpdateSize)
CheckPlayCG()
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Resource_Download_Start)
-- -- 如果空间不足的话,直接弹出空间不足提示
-- if UpdateSize > 0 and not CS.XAppPlatBridge.DiskSizeEnough(math.ceil(UpdateSize/1024)) then
-- ShowStartErrorDialog("FileManagerDownloadDiskFull")
-- return
-- end
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()
local useParallel = (CS.XRemoteConfig.ParallelQueueSize ~= nil and CS.XRemoteConfig.ParallelDownload == 1)
if CS.XRemoteConfig.ParallelQueueSize ~= nil and useParallel and ResFileType == RES_FILE_TYPE.MATRIX_FILE and not IsInGame then
CsLog.Debug("多线程下载模式")
ParallelDownload()
return
end
if isUseAndroidDownloadService and ResFileType == RES_FILE_TYPE.MATRIX_FILE and not IsInGame then
CsLog.Debug("安卓后台下载模式")
AndroidBackgroundDownload()
elseif isUseIosDownloadService and ResFileType == RES_FILE_TYPE.MATRIX_FILE and not IsInGame then
CsLog.Debug("IOS后台下载模式")
IosBackgroundDownload()
else
CsLog.Debug("传统下载模式")
TraditionalDownload()
end
end
function XLaunchFileModule.PauseDownload()
if CurrentDownloader then
CurrentDownloader:Stop()
CurrentDownloader = nil
end
IsPause = true
CompleteDownload()
--需要在CompleteDownload之后
XLaunchDlcManager.ClearGameDownloadRecord()
end
function XLaunchFileModule.ResumeDownload()
IsPause = false
end
function XLaunchFileModule.CleanDlcFiles(dlcId)
if dlcId == DLC_BASE_INDEX or dlcId == DLC_COMMON_INDEX then
CsLog.Error("[DLC] 清理dlc资源失败 dlcId:" .. tostring(dlcId))
return
end
local dirPath = DocumentFilePath .. "/" .. ResFileType .. "/"
if NeedLaunchTest then
dirPath = LaunchTestDirDoc .. "/" .. ResFileType .. "/"
end
local fileMap = DlcNeedFileMap[dlcId]
if not fileMap then
CsLog.Error("[DLC] 清理dlc资源失败 fileMap is ni, dlcId:" .. tostring(dlcId))
return
end
local count, size = 0, 0
for name, info in pairs(fileMap) do
local file = dirPath .. name
CS.XFileTool.DeleteFile(file)
XLaunchDlcManager.SetDownloadedFile(name, false)
count = count + 1
size = size + info[3]
end
if IsDebugBuild then
CsLog.Debug("[DLC] 清理DLC .." .. dlcId .. "下载资源,数量:" .. count .. ",大小:" .. math.ceil(size/1024/1024) .. "mb")
end
end
-- 启动下载测试
InitDocumentIndexTest = function()
local indexPath = LaunchTestDirDoc .. "/" .. ResFileType .. "/" .. INDEX
print("[DownloadTest] InitDocumentIndexTest: ResFileType: " .. ResFileType .. ", indexPath:" .. indexPath)
if CS.System.IO.File.Exists(indexPath) then
-- 本地下载release测试真机逻辑解析index
print("[DownloadTest] 本地下载-release测试解析index, IsDlcBuild:" .. tostring(IsDlcBuild))
if IsDlcBuild then
DocumentIndexTable, DlcIndexTable = LoadIndexTableWithDlcInfo(indexPath)
else
print("[DownloadTest] InitDocumentIndexTest:222")
DocumentIndexTable = LoadIndexTable(DocumentIndexPath)
end
else
-- 本地下载(随意文件)测试
print("[DownloadTest] 本地下载-随意文件测试")
DocumentIndexTable = {}
local UnityApplication = CS.UnityEngine.Application
local cdnPath = LaunchTestPath .. "/" .. ResFileType
local files = CS.XFileTool.GetAllFiles(cdnPath)
local function GetFileSize(path)
local file, err = io.open(path, "rb")
if not file then
return 0
end
local size = file:seek("end")
file:close()
return size
end
local tab = {}
for i = 0, files.Count - 1 do
local file = files[i]
local name = CS.XFileTool.GetFileName(file)
if name ~= INDEX then
local asset = string.sub(file, #cdnPath + 2)
local size = GetFileSize(file)
table.insert(tab, "[LaunchTest] " .. tostring(i + 1) .. "、file:" .. tostring(file) .. ", name:" .. tostring(name) .. ", asset:" .. tostring(asset) .. ", size:" .. tostring(size))
DocumentIndexTable[asset] = {name, nil, size}
end
end
if #tab > 0 then
print(table.concat(tab, "\n"))
end
end
end
CompleteDownload = function()
print("CompleteDownload!")
CsApplication.SetProgress(1)
-- 1:基础资源 2:完整资源
local downloadMode = XLaunchDlcManager.IsFullDownload(CsInfo.Version) and 2 or 1
local dict = {["type"] = ResFileType, ["version"] = NewVersion, ["size"] = UpdateSize, ["mode"] = downloadMode}
DoRecord(dict, "80012", "DownloadNewFilesEnd")
CS.XAppEventManager.LogAppEvent(CS.XAppEventConfig.Resource_Download_End)
OnCompleteResFilesInit()
end
local function ClearData()
ApplicationIndexTable = nil
DocumentIndexTable = nil
CurrentFileTable = nil
DlcIndexTable = nil
AllFileTableDlc = nil
NeedFileSet = nil
DlcNeedFileMap = nil
DownloadedMap = nil
end
OnCompleteResFilesInit = function()
if IsInGame then
if not IsPause then
XLaunchDlcManager.DoneDownloadInGame()
end
ClearData()
if OnCompleteCallback then
OnCompleteCallback(IsPause)
end
return
end
local urlTable = {}
local hashTable = {}
if IsDlcBuild then
if AllFileTableDlc then
for asset, info in pairs(AllFileTableDlc) do -- 未剔除包体已有资源dlc补丁逻辑会访问路径出错
urlTable[asset] = DocumentFilePath .. "/" .. ResFileType .. "/" .. info[1]
hashTable[asset] = info[1]
end
XLaunchDlcManager.DoneDownloadInLaunch()
end
else
if DocumentIndexTable then
for asset, info in pairs(DocumentIndexTable) do
urlTable[asset] = DocumentFilePath .. "/" .. ResFileType .. "/" .. info[1]
hashTable[asset] = 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]
hashTable[asset] = info[1]
end
end
ClearData()
RemoveEvents()
-- 完成回调
if OnCompleteCallback then
OnCompleteCallback(urlTable, hashTable, NeedUpdate, HasLocalFiles)
end
end
RemoveEvents = function()
if NeedShowSelect then
CsGameEventManager:RemoveEvent(CS.XEventId.EVENT_LAUNCH_DONE_DOWNLOAD_SELECT, OnNotifyEvent)
end
NeedShowSelect = nil -- 网络下载失败重试时,不再弹选择弹窗
end
DoRecord = function(...)
if IsInGame then
return
end
CS.XRecord.Record(...)
end
IsFullDownloadSelectType = function()
local selectType = CS.XRemoteConfig.LaunchSelectType
return selectType == nil or selectType == 0
end
return XLaunchFileModule
end
return module_creator