子游戏 zip 升级链路完整对齐 msext(持久化目录 + advance + 版本比对)
之前新外壳的 SubGameDownloader 只看 index.html 是否存在,缺这两个关键行为:
- gamefilepath 持久化(msext NSUserDefaults["game_name"] → gamefilepath)
- 远端 game_version > 本地 version.xml 时升级 + 目录末尾追加 "1"
(msext gameController.m:1414 等价 [NSString stringWithFormat:@"%@1", gamefilepath])
本次完整补齐:
1. 新增 SubGameDirectoryStore:UserDefaults 持久化 directory → actualDir 映射
- current(forKey:) / advance(forKey:) / saveInitialIfNeeded(forKey:)
- nonisolated 让 actor / MainActor 都能直接调
2. SubGameDownloader 三分支决策(msext gameController.m:1239-1255 + uplevel: 等价):
- 目录不存在(首装)→ 下载到 currentDir,不 advance
- 目录存在 + 远端 > 本地 → advance + 下载到新目录
- 远端 ≤ 本地 → 复用 currentDir
API 改为按入参(directoryKey / gameStart / remoteVersion / remoteZipURL)调用,
返回 Outcome.actualDirectory 暴露实际生效目录名。
3. LocalAudioHandler.register 的 assetsRoot 改 @MainActor closure
srcIsloop 每次调用时取最新值,让子游戏升级(effectiveGameDir 末尾追加 "1")
后下一次 srcIsloop 自动用新目录路径。
4. SubGameViewController 引入 effectiveGameDir:
- init 时同步从 SubGameDirectoryStore 读初始值(首次=request.gameDir)
- boot pipeline 内调 ensureReady,从 outcome 同步升级后的新目录名
- loadFileURL / AppDataWriter / srcIsloop closure 全部走 effectiveGameDir
- resolveBoot 返回 (lobbyResolved, subGameResolved) 完整 ResolvedVersion,
给 ensureReady 用 gameVersion 做版本比对
5. WebContainerViewController 大厅侧 LocalAudioHandler 改 closure 形式(路径不变)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
18fd782156
commit
7be7a2abbc
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// SubGameDirectoryStore.swift
|
||||
// ylgamehall
|
||||
//
|
||||
// 子游戏目录名持久化映射:H5 传的 Gamedirectory(也是 gameStart 同名)→ 实际沙盒
|
||||
// 目录名。与 daoqi msext gameController.m:1414 / 2183-2188 等价:
|
||||
// - 首次安装:actualDir = directory,写入 NSUserDefaults
|
||||
// - 每次 zip 升级(远端 game_version > 本地 version.xml):actualDir 末尾追加 "1",
|
||||
// 新版本解压到新目录,旧目录残留在沙盒(msext 同款"追加而非原子替换"策略)
|
||||
//
|
||||
// 存储约定:UserDefaults key = "ylgh.subGameDir.<directory>",value = 实际目录名
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// UserDefaults 线程安全,所有方法 nonisolated 让 actor / MainActor / 后台线程都能直接调用。
|
||||
public enum SubGameDirectoryStore {
|
||||
|
||||
private static let keyPrefix = "ylgh.subGameDir."
|
||||
|
||||
/// 当前实际目录名。已持久化 → 返回持久化值;未持久化 → 返回 directory 本身
|
||||
/// (对应 msext NSUserDefaults 缺 key 时 gamefilepath = gamename 的默认)。
|
||||
nonisolated public static func current(forKey directory: String) -> String {
|
||||
UserDefaults.standard.string(forKey: keyPrefix + directory) ?? directory
|
||||
}
|
||||
|
||||
/// 触发升级:末尾追加 "1",写回 UserDefaults,返回新值。
|
||||
/// msext gameController.m:1414 等价 `gamefilepath = [NSString stringWithFormat:@"%@1", gamefilepath]`。
|
||||
@discardableResult
|
||||
nonisolated public static func advance(forKey directory: String) -> String {
|
||||
let next = current(forKey: directory) + "1"
|
||||
UserDefaults.standard.set(next, forKey: keyPrefix + directory)
|
||||
return next
|
||||
}
|
||||
|
||||
/// 首次访问时把 directory 自身写入(与 msext gameController.m:2187
|
||||
/// SaveDefaultInfo 等价)。后续 advance 会基于此值追加。
|
||||
nonisolated public static func saveInitialIfNeeded(forKey directory: String) {
|
||||
let k = keyPrefix + directory
|
||||
if UserDefaults.standard.string(forKey: k) == nil {
|
||||
UserDefaults.standard.set(directory, forKey: k)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user