PGRData/Script/launch/XLaunchModule.lua

457 lines
17 KiB
Lua
Raw Normal View History

local CsApplication = CS.XApplication
local CsLog = CS.XLog
local CsInfo = CS.XInfo
local CsTool = CS.XTool
local CsStringEx = CS.XStringEx
local CsGameEventManager = CS.XGameEventManager.Instance
local IO = CS.System.IO
local CsRemoteConfig = CS.XRemoteConfig
--Test 设置模式
--CsApplication.Mode = CS.XMode.Debug
print("Launch Version Code 1." )
RES_FILE_TYPE = {
LAUNCH_MODULE = "launch",
MATRIX_FILE = "matrix",
CG_FILE = "cg",
}
local APP_PATH_MODULE_NAME = "XLaunchAppPathModule"
local APP_VERSION_MODULE_NAME = "XLaunchAppVersionModule"
local FILE_MODULE_NAME = "XLaunchFileModule"
local UI_MODULE_NAME = "XLaunchUiModule"
local PathModule = require(APP_PATH_MODULE_NAME)
local FileModuleCreator = require(FILE_MODULE_NAME)
local XLaunchUiModule = require(UI_MODULE_NAME)
local VersionModule
local LaunchFileModule
local DocFileModule
local IsReloaded = false
local ResFileUrlTable = {}
-- 游戏内强更
local DOWNLOAD_APK_VERSION = "download_apk_ver"
local OPPO_CHANNEL_ID = 1
local ApkListUrl = "client/patch/config.js"
local ApkFileName = "Punishing.apk"
local ApkSavePath = string.format("%s/%s", CS.UnityEngine.Application.persistentDataPath, ApkFileName)
local ApkFileSize = 0
local APK_TIMEOUT = 5000
-- local IsApkTesting = true -- 调试用
2024-09-01 20:49:41 +00:00
--======= 私有方法 * 声明 =======
local CheckLaunchModuleUpdate
local CheckDocUpdate
local DownloadDlc
local OnCheckLaunchModuleComplete
local InitGame
local CheckDownloadChannel
local TryDownloadApk
local BeforeDownloadApk
local StartDownloadApk
local CheckLocalZipFile
2024-09-01 20:49:41 +00:00
local NeedLaunchTest = CS.XResourceManager.NeedLaunchTest
---======= 私有方法 * 声明 =======
GetResFileUrl = GetResFileUrl or nil
-- 注意:重载模块需要释放的对象
ShowStartErrorDialog = function(errorCode, confirmCB, cancelCB, cancelStr)
CS.XHeroBdcAgent.BdcStartUpError(errorCode)
confirmCB = confirmCB or CsApplication.Exit
2024-09-01 20:49:41 +00:00
cancelStr = cancelStr or "Cancel"
CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"), CsApplication.GetText(errorCode), cancelCB, confirmCB, cancelStr, "Confirm"))
end
2024-09-01 20:49:41 +00:00
--======= 私有方法 * 定义 =======
CheckLaunchModuleUpdate = function()
2024-09-01 20:49:41 +00:00
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release or NeedLaunchTest then
LaunchFileModule = FileModuleCreator()
LaunchFileModule.Check(RES_FILE_TYPE.LAUNCH_MODULE, PathModule, VersionModule, OnCheckLaunchModuleComplete)
else
CheckDocUpdate()
end
end
CheckDocUpdate = function()
2024-09-01 20:49:41 +00:00
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release or NeedLaunchTest then
CsLog.Debug("Release 模式运行")
DocFileModule = FileModuleCreator()
DocFileModule.Check(RES_FILE_TYPE.MATRIX_FILE, PathModule, VersionModule, InitGame)
elseif PathModule.IsEditorOrStandalone() and CsApplication.Mode == CS.XMode.Debug then
CsLog.Debug("Debug 模式运行")
InitGame()
elseif PathModule.IsEditorOrStandalone() and CsApplication.Mode == CS.XMode.Editor then
CsLog.Debug("Editor 模式运行")
CS.XResourceManager.InitEditor()
InitGame()
end
end
2024-09-01 20:49:41 +00:00
OnCheckLaunchModuleComplete = function(urlTable, hashTable, needUpdate, hasLocalFiles)
if not needUpdate or IsReloaded then
2024-09-01 20:49:41 +00:00
if hasLocalFiles then
CS.XLaunchManager.SetUrlTable(urlTable)
end
2024-09-01 20:49:41 +00:00
CheckDocUpdate()
return
end
CS.XUiManager.Instance:Clear()
2024-09-01 20:49:41 +00:00
if NeedLaunchTest then
print("[LaunchTest] OnCheckLaunchModuleComplete ")
else
CS.XResourceManager.Clear()
CS.XResourceManager.ClearFileDelegate()
CS.XLaunchManager.SetUrlTable(urlTable)
CS.XResourceManager.ResolveBundleManifest("launchmanifest")
end
ShowStartErrorDialog = nil
CheckUpdate = nil
CS.XLaunchManager.GetLaunchUi = nil
CS.XGame.ReloadLaunchModule()
end
2024-09-01 20:49:41 +00:00
InitGame = function(urlTable, hashTable)
-- -- for testing
-- CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, 100)
-- local videoUrl = CS.XResourceManager.GetBundleUrl(CS.XAudioManager.LaunchVideoAsset)
-- CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_CG, true, false, videoUrl)
-- print("for test launch download.")
-- do return end
urlTable = urlTable or {}
for k, v in pairs(urlTable) do
local url = ResFileUrlTable[k]
if url then
CS.XLog.Error("资源文件key重复key:" .. tostring(k))
return
end
ResFileUrlTable[k] = v
end
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_LOADING)
local import = CS.XLuaEngine.Import
import("XLaunchCommon")
import("XLaunchUi")
--TODO
GetResFileUrl = function(path)
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release then
return ResFileUrlTable[path]
elseif PathModule.IsEditorOrStandalone() and CsApplication.Mode == CS.XMode.Debug then
return PathModule.GetDebugFilePath() .. "/" .. path
else
return path
end
end
CS.XLaunchManager.GetPrimaryFileUrl = GetResFileUrl
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release then
--
--CS.XResourceManager.ClearFileDelegate()
CS.XResourceManager.AddFileDelegate(GetResFileUrl)
CS.XResourceManager.ResolveBundleManifest("matrixmanifest")
end
2024-09-01 20:49:41 +00:00
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release then
CS.XLaunchManager.SetHashTable(hashTable)
end
CS.XGame.InitGame()
end
--- <<<<<<<<<<<<<<<<<<<<<<<<<< 私有方法 * 定义 <<<<<<<<<<<<<<<<<<<<<<<<<<
CheckUpdate = function(isReloaded)
IsReloaded = isReloaded or false
CS.XLaunchManager.GetLaunchUi = XLaunchUiModule.NewLaunchUi
if not IsReloaded then
XLaunchUiModule.RegisterLaunchUi()
end
--测试模式,初始化资源管理器
if PathModule.IsEditorOrStandalone() and CsApplication.Mode == CS.XMode.Debug then
CS.XResourceManager.InitBundleDebug(PathModule.GetDebugFilePath())
elseif PathModule.IsEditorOrStandalone() and CsApplication.Mode == CS.XMode.Editor then
CS.XResourceManager.InitEditor()
end
-- 开启Launch模块Ui
CS.XUiManager.Instance:Open("UiLaunch")
CS.XRecord.Record("50000", "UiLaunchand")
2024-09-01 20:49:41 +00:00
VersionModule = require(APP_VERSION_MODULE_NAME)
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release then
CS.XHeroBdcAgent.BdcUpdateGame("201", "1", "0")
end
if VersionModule.CheckAppUpdate() then
-- if IsApkTesting or VersionModule.CheckAppUpdate() then
2024-09-01 20:49:41 +00:00
if CS.XUiPc.XUiPcManager.IsPcMode() then
CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"),
CsStringEx.Format(CsApplication.GetText("PCUpdateApplication"), CsInfo.Version), nil, CsApplication.Exit, "Cancel", "Confirm"))
else
CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"), CS.XStringEx.Format(CS.XApplication.GetText("UpdateApplication"), CS.XInfo.Version),
nil, function()
local jumpCB = function()
print("[Apk] - Failed to Download Apk.")
CsTool.WaitCoroutine(CsApplication.GoToUpdateURL(PathModule.GetAppUpgradeUrl()), nil)
end
local downloadCB = function(url)
BeforeDownloadApk(url)
end
TryDownloadApk(downloadCB, jumpCB)
2024-09-01 20:49:41 +00:00
end, "Cancel", "Confirm"))
end
else
-- 无需更新并删除本地下载的Apk
if CheckDownloadChannel() and IO.File.Exists(ApkSavePath) then
print("[Apk] - Clean Apk path:" .. ApkSavePath)
CS.XFileTool.DeleteFile(ApkSavePath)
end
local LaunchUpdateFunc = function()
if not PathModule.IsEditorOrStandalone() or CsApplication.Mode == CS.XMode.Release then
CS.XHeroBdcAgent.BdcUpdateGame("202", "1", "0")
end
CheckLaunchModuleUpdate()
end
if CsRemoteConfig.Debug then
CheckLocalZipFile(LaunchUpdateFunc)
else
LaunchUpdateFunc()
end
end
end
GetAppUpgradeUrl = function ()
return PathModule.GetAppUpgradeUrl()
end
--============检查本地压缩包=========
function CheckLocalZipFile(cb)
local documentPath = CS.UnityEngine.Application.persistentDataPath .. "/document"
if not CS.System.IO.Directory.Exists(documentPath) then
cb()
return
end
local files = CS.System.IO.Directory.GetFiles(documentPath, "*.zip", CS.System.IO.SearchOption.TopDirectoryOnly)
print("[Unzip] DocumentPath:" .. tostring(documentPath) .. ", files.length:" .. tostring(files.Length))
local length = files.Length
local function UnzipFile(index)
if index >= length then
if index > 0 then
CsApplication.SetProgress(1)
print("[Unzip] Finished.")
end
cb()
return
end
local file = files[index]
local nextIndex = index + 1
if string.find(file, "source") then
local overwrite = true
local password = nil
local totalCount = CS.ZipUtility.GetZipEntityCount(file, password)
print("[Unzip] Start File: " .. tostring(file))
if (totalCount > 0) then
local cancelCB = function()
UnzipFile(nextIndex)
end
local confirmCB = function()
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, totalCount, false, CsApplication.GetText("Unzip") .. "(%d/%d)") -- 解压资源
CsApplication.SetProgress(0)
local progressCB = function(counter, name)
local progress = counter / totalCount
CsApplication.SetProgress(progress)
print("[Unzip] progress:" .. tostring(counter) .. "/" .. tostring(totalCount) .. ", name:" .. tostring(name) .. ", zipFile: " .. tostring(file) .. ", outputPath:" .. tostring(documentPath))
end
local finishCB = function(counter)
if counter >= totalCount then
print("[Unzip] Completed file:" .. tostring(file))
CS.XFileTool.DeleteFile(file)
UnzipFile(nextIndex)
end
end
CS.ZipUtility.UnzipFile(file, documentPath, progressCB, finishCB, overwrite, password)
end
local text = "检查到本地压缩文件" .. CS.XFileTool.GetFileNameWithoutExtension(file) .. ", 是否进行解压?"
2024-09-01 20:49:41 +00:00
CsTool.WaitCoroutine(CsApplication.CoDialog(CsApplication.GetText("Tip"), text, cancelCB, confirmCB, "Cancel", "Confirm"))
else
print("[Unzip] count <= 0, zipFile: " .. tostring(file))
UnzipFile(nextIndex)
end
else
print("[Unzip] name not Contains 'source', zipFile: " .. tostring(file))
UnzipFile(nextIndex)
end
end
local index = 0
UnzipFile(index)
end
--============包内下载apk逻辑=========
function CheckDownloadChannel()
local channelId = CS.XHgSdkAgent.GetChannelId()
return (channelId == OPPO_CHANNEL_ID)
end
-- 可在包内强更 调用downloadCB 否则调用jumpCB跳转外链下载
function TryDownloadApk(downloadCB, jumpCB)
if not CheckDownloadChannel() then
-- if not IsApkTesting and not CheckDownloadChannel() then
jumpCB()
return
end
-- 清理过期的下载临时文件
local curVersion = CsRemoteConfig.ApplicationVersion
local tempFile = ApkSavePath .. ".download"
if IO.File.Exists(tempFile) then
local lastDownloadVersion = CS.UnityEngine.PlayerPrefs.GetString(DOWNLOAD_APK_VERSION, "")
print("[APK] - Last down load versin:" .. lastDownloadVersion .. ", current:" .. curVersion)
if lastDownloadVersion ~= curVersion then
CS.XFileTool.DeleteFile(tempFile)
end
end
CS.UnityEngine.PlayerPrefs.SetString(DOWNLOAD_APK_VERSION, curVersion)
CS.UnityEngine.PlayerPrefs.Save()
local channelId = CS.XHgSdkAgent.GetChannelId()
-- local channelId = IsApkTesting and OPPO_CHANNEL_ID or CS.XHeroSdkAgent.GetChannelId()
local request = CS.XUriPrefixRequest.Get(ApkListUrl, nil, APK_TIMEOUT)
CS.XTool.WaitCoroutine(request:SendWebRequest(), function()
if request.isNetworkError or request.isHttpError or not request.downloadHandler then
CsLog.Error("[Apk] - Request apkList error:" .. tostring(request.error))
jumpCB()
return
end
local content = request.downloadHandler.text
local url = nil
for k, v in string.gmatch(content, "\"(%d+)\" : \"(.-)\"") do
local cid = tonumber(k)
if cid == channelId then
url = v
break
end
end
if url then
downloadCB(url)
else
jumpCB()
end
end)
end
-- 获取apk大小并开始下载
function BeforeDownloadApk(apkUrl)
print("[Apk] - Start Downloading Apk:" .. apkUrl)
local request = CS.UnityEngine.Networking.UnityWebRequest.Head(apkUrl)
request.timeout = APK_TIMEOUT
CS.XTool.WaitNativeCoroutine(request:SendWebRequest(), function()
if request.isNetworkError or request.isHttpError then
CsLog.Error("[Apk] - Request ApkUrl error:" .. tostring(request.error))
ShowStartErrorDialog("DownloadAPKError", function()
BeforeDownloadApk(apkUrl)
end)
return
end
ApkFileSize = request:GetResponseHeader("Content-Length")
print("[Apk] - Request ApkFileSize is " .. tostring(ApkFileSize))
ApkFileSize = tonumber(ApkFileSize)
StartDownloadApk(apkUrl)
end)
end
function StartDownloadApk(apkUrl)
print("[Apk] - Start to download.")
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, ApkFileSize)
local cache = true
local sha1 = nil
local downloader = CS.XDownloader(apkUrl, ApkSavePath, cache, sha1, APK_TIMEOUT)
local isDownloading = false
CS.XTool.WaitCoroutinePerFrame(downloader:Send(), function(isComplete)
if not isComplete then
if not isDownloading then
isDownloading = true
print("[Apk] - Init Download Apk Info:", downloader.CurrentSize, ApkFileSize)
CsGameEventManager:Notify(CS.XEventId.EVENT_LAUNCH_START_DOWNLOAD, ApkFileSize)
end
local downloadedSize = downloader.CurrentSize
local progress = downloadedSize / ApkFileSize
CsApplication.SetProgress(progress)
else
local localFileSize = 0
if isDownloading then
localFileSize = downloader.CurrentSize
elseif IO.File.Exists(ApkSavePath) then
local fs = IO.File.Open(ApkSavePath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
localFileSize = tonumber(fs.Length)
fs:Close()
end
local isFinish = (localFileSize == ApkFileSize)
print("[Apk] - Finish Download:" .. tostring(downloader.State) .. ", localFileSize:" .. localFileSize.. ", Size:" .. ApkFileSize .. ", isFinish:" .. tostring(isFinish))
if not isFinish then
local function CleanAndDownload()
if IO.File.Exists(ApkSavePath) then
print("[Apk] - Clean downloaded Error File:" .. ApkSavePath)
CS.XFileTool.DeleteFile(ApkSavePath)
end
StartDownloadApk(apkUrl)
end
if isDownloading then -- 下载过程失败才询问
ShowStartErrorDialog("DownloadAPKError", CleanAndDownload, CsApplication.Exit)
else
CleanAndDownload()
end
return
end
if downloader.State ~= CS.XDownloaderState.Success then
CsLog.Error("[Apk] - Download Error state:" .. tostring(downloader.State) .. ", Exception:" .. tostring(downloader.Exception and downloader.Exception.Message))
ShowStartErrorDialog("DownloadAPKError", function()
StartDownloadApk(apkUrl)
end)
return
end
CsApplication.SetProgress(1)
CS.XTool.OpenFile(ApkSavePath, function(result)
print("[Apk] - Open File result:" .. tostring(result))
CsApplication.Exit()
end)
end
end)
end
--============包内下载apk逻辑 end=========