Phase 1.13:LobbyZipUpgrader 完成 H5 zip 升级端到端链路
Phase 1 远程配置链路(1.10-1.13)最后一环:把 VersionResolver 解出的
gameZip URL 下载 + 解压 + 原子 rename 到 lobbyRoot,触发条件是远端
gameVersion > 本地 version.xml /game/version@value。
- 新增 ylgamehall/Source/Resource/LobbyZipUpgrader.swift
- public actor,单例 LobbyZipUpgrader.shared
- upgradeIfNeeded(resolved:) async throws -> Outcome
- .noop:远端版本 ≤ 本地,或 gameZip nil / 非法 URL,直接返回
- .upgraded(from:to:):完成升级,附前后版本号
- URLSession.download(from:) 异步下载(60s 请求 / 300s 资源超时),
HTTP 状态码非 2xx 抛 .httpStatus
- 解压到 caches/lobby-staging-{UUID}/ 隔离目录(不直接覆盖 lobbyRoot,
msext "removeItem + ZipArchive overWrite:YES" 半途崩溃会留半残;
我们 staging 完整解压成功后才 rename)
- 原子 rename:fm.removeItem(lobbyRoot) → fm.moveItem(staging,
to: lobbyRoot);任一步失败抛 .stagingMoveFailed,调用方决定回退
- 类型化 UpgradeError 5 种:badGameZipURL / downloadFailed /
httpStatus / unzipFailed / stagingMoveFailed
- 实现照搬 msext NewRootVC.m:1789-1869 downFileFromServer + unzip
+ unzipDone 的语义,但用现代 async + 原子 rename 替代 ASIHTTPRequest
+ detachNewThreadSelector + ZipArchive overWrite:YES
- RootViewController 烟雾测试串接 LobbyZipUpgrader:
调 upgradeIfNeeded → switch outcome → 升级后重新读 version.xml 验证
- 真机实测端到端链路:
第一次:本地 260 vs 远端 261 → 升级完成 261,耗时 2.007s
(下载 11.5 MB HTTP zip + ZIPFoundation 解压 + 原子 rename)
重新读 version.xml = 261 ✓ lobbyIndex 仍存在 ✓
第二次:本地 261 vs 远端 261 → .noop,耗时 0.001s(幂等验证)
Phase 1 远程配置链路(1.10-1.13)完整闭环。下一步 Phase 1.14
WebContainer 把这条链路插到 viewDidLoad 之前 + 16:9 letterbox 加载
lobbyIndex,第一次让真实大厅 H5 渲染出来。
This commit is contained in:
@@ -128,6 +128,28 @@ final class RootViewController: UIViewController {
|
||||
远端 gameVersion = \(resolved.gameVersion)
|
||||
→ H5 zip 升级 = \(needZipUpgrade ? "需要" : "不需要")
|
||||
""")
|
||||
|
||||
// Phase 1.13 烟雾测试:触发 LobbyZipUpgrader(如果需要升级)
|
||||
let upgradeStart = Date()
|
||||
do {
|
||||
let outcome = try await LobbyZipUpgrader.shared.upgradeIfNeeded(resolved: resolved)
|
||||
let elapsed = Date().timeIntervalSince(upgradeStart)
|
||||
switch outcome {
|
||||
case .noop:
|
||||
print("""
|
||||
[LobbyZipUpgrader] 无需升级,跳过(耗时 \(String(format: "%.3f", elapsed))s)
|
||||
""")
|
||||
case .upgraded(let from, let to):
|
||||
let newLocalGame = LocalVersionReader.localGameVersion
|
||||
print("""
|
||||
[LobbyZipUpgrader] 升级完成 \(from) → \(to)(耗时 \(String(format: "%.3f", elapsed))s)
|
||||
重新读 version.xml: localGameVersion = \(newLocalGame)
|
||||
lobbyIndex 存在: \(FileManager.default.fileExists(atPath: SandboxPaths.lobbyIndex.path))
|
||||
""")
|
||||
}
|
||||
} catch {
|
||||
print("[LobbyZipUpgrader] ERROR: \(error)")
|
||||
}
|
||||
case .shortText(let msg):
|
||||
print("""
|
||||
[RemoteConfigClient] 拉到短文本响应(耗时 \(String(format: "%.3f", elapsed))s)
|
||||
|
||||
Reference in New Issue
Block a user