子游戏跳转链路修复 + H5 音频统一可用
修复后子游戏 SwitchOverGameData 跳转完全可用,行为对齐 daoqi msext:
【zip URL 解析】H5 字段 gamedownloadurl 实为 gameid(msext gameController.m:544
注释"游戏ID")。RemoteConfigClient 新增 lastParsed 缓存 + current() getter;
SubGameViewController.resolveBoot 做两次 VersionResolver.resolve:
- lobby 视角(gameId=bc.gameId)→ ResolvedVersion 传 AppDataWriter 算
app_appversion 审核标志(msext result_state 等价)
- sub-game 视角(gameId=H5 传的 gameid)→ 真实 game_zip 下载 URL
之前 SubGameDownloader 直接把 token 当 URL 用,URLSession 报 -1002
unsupported URL;AppDataWriter resolvedVersion 始终 nil 导致子游戏 app_appversion
永远 0、丢失审核切换能力。
【push 前停大厅背景音】AppCoordinator.showSubGame 节流通过后、push 前调
AudioPlayer.stopAllBackground(msext NewRootVC.m:549-552 等价)。
【H5 音频】
- AVAudioSession.setCategory(.playback) 在 AppDelegate 启动期设置,让原生
+ WKWebView 内 <audio> 都不受静音键影响(msext RootVC.m:1302 等多处等价)
- WKWebViewConfiguration.mediaTypesRequiringUserActionForPlayback = [],子游戏
push 后立即 loadFileURL 自播背景音不再被 WebKit 静默拦截
- LocalAudioHandler.register 增 assetsRoot 参数,srcIsloop 按容器各自的 H5
根目录拼 assets/wav/{src}(msext gameController.m:364 等价,大厅 / 子游戏
音频文件在各自 zip 内不重叠)。修前所有路径都指向大厅根,子游戏读不到自己的
音频文件,AVAudioPlayer 报 OSStatus 2003334207 (wht?
kAudioFileUnsupportedFileTypeError)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
053232ed26
commit
e50dfb75af
@@ -4,10 +4,14 @@
|
||||
//
|
||||
// H5 → Native handler:srcIsloop — 本地音频播放(背景循环 / 按钮单次)
|
||||
// 契约:docs/H5-Native-Contract.md §3.1 [3]
|
||||
// 原项目:daoqi/msext NewRootVC.m initJSdata 关联 buttunPlayer / backgroundPlayer
|
||||
// 原项目:
|
||||
// - 大厅 daoqi/msext NewRootVC.m 用 lobby gamedir/gamestart
|
||||
// - 子游戏 daoqi/msext gameController.m:359-419 用 self.gamefilepath/self.game_name
|
||||
// 两边各自注册,路径根不同。新外壳保留同一 enum 注册器,但调用方注入 assetsRoot。
|
||||
//
|
||||
// 本地音频文件路径:`{Caches}/{gamedir}/{gamestart}/assets/wav/{src}`
|
||||
// 与 SandboxPaths.lobbyIndex 同一根目录下 assets/wav 子目录
|
||||
// 音频文件实际路径:`{assetsRoot}/assets/wav/{src}`
|
||||
// - lobby:assetsRoot = SandboxPaths.lobbyIndex.deletingLastPathComponent()
|
||||
// - subGame:assetsRoot = SandboxPaths.subGameIndex(dir,name).deletingLastPathComponent()
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@@ -15,9 +19,14 @@ import Foundation
|
||||
@MainActor
|
||||
public enum LocalAudioHandler {
|
||||
|
||||
public static func register(on bridge: any BridgeProtocol) {
|
||||
/// 注册 srcIsloop handler。
|
||||
/// - Parameters:
|
||||
/// - bridge: 桥接器
|
||||
/// - assetsRoot: 该容器(lobby / subGame)的 H5 资源根目录;
|
||||
/// 音频文件实际路径会拼接 `assets/wav/{src}` 在该根下查找。
|
||||
public static func register(on bridge: any BridgeProtocol, assetsRoot: URL) {
|
||||
// 【3】srcIsloop — 本地音频播放
|
||||
// 入参 src : string 音频文件名(位于 lobbyAssets/assets/wav/{src})
|
||||
// 入参 src : string 音频文件名(位于 {assetsRoot}/assets/wav/{src})
|
||||
// 入参 isloop : int 0 单次 / 1 循环背景 / -1 停同名循环
|
||||
// cb: "Response from srcIsloop"
|
||||
bridge.register("srcIsloop") { data, callback in
|
||||
@@ -30,7 +39,10 @@ public enum LocalAudioHandler {
|
||||
return
|
||||
}
|
||||
|
||||
let url = audioFileURL(src: src)
|
||||
let url = assetsRoot
|
||||
.appendingPathComponent("assets")
|
||||
.appendingPathComponent("wav")
|
||||
.appendingPathComponent(src)
|
||||
|
||||
switch isloop {
|
||||
case 0:
|
||||
@@ -44,14 +56,4 @@ public enum LocalAudioHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `{lobbyAssets}/assets/wav/{src}` —— 与 msext NewRootVC 路径约定一致。
|
||||
/// H5 业务调用前会先用 zip 升级(gamehall.zip 内含 assets/wav/*.wav 音频文件)。
|
||||
nonisolated private static func audioFileURL(src: String) -> URL {
|
||||
SandboxPaths.lobbyIndex
|
||||
.deletingLastPathComponent() // {Caches}/{gamedir}/{gamestart}/
|
||||
.appendingPathComponent("assets")
|
||||
.appendingPathComponent("wav")
|
||||
.appendingPathComponent(src)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user