Commit Graph
44 Commits
Author SHA1 Message Date
lanterngamescn 9abd571f43 M5: 显式化导航拓扑约束(无子游戏→子游戏,须经大厅)
确认当前实现已符合用户拓扑:大厅常驻不销毁、子游戏临时销毁、仅 大厅↔子游戏、
子游戏换子游戏须 backgameData 回大厅再 SwitchOverGameData 进新子游戏。

- switchGame 守卫拆分:已在子游戏中(subgameUrl!='')时忽略 SwitchOverGameData 并告警日志
  (此前静默忽略);注释说明拓扑约束与正确流程。无功能变更,仅可观测性。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:49:47 +08:00
lanterngamescn cf2eebdad9 计划进度:M5 T-M5-01/02 双 Web 架构完成(真机验证)
01_WBS:T-M5-01/02 标记完成(双 Web 槽 + WebSlot 激活协议 + Provider 前后台,真机验证大厅常驻/接口隔离/只一个激活);
M5 进入进行中,余 T-M5-03 节流/04 崩溃兜底/05 安全加固/06 可观测/07 冷启动/08 包体
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:37:35 +08:00
lanterngamescn 0eabcac7e9 M5: Provider 前后台生命周期(非激活槽真正停 native 活动)
forEachForeground/forEachBackground 此前扇出但多数 Provider 未实现 → 非激活槽 native 监听仍跑。补齐:
- ShakeProvider:onBackground 停传感器、onForeground 按 H5 意图(wantShake)恢复;区分 H5 请求态与实际监听态
- LocationProvider:onBackground 停连续定位、onForeground 按 wantContinuous 恢复(单次定位无需恢复)
- NetworkProvider:onBackground 注销网络订阅、onForeground 重订阅(抽 unsubscribe)
- AudioProvider:onBackground 停语音/音效播放(非激活端不出声)
至此"同时只有一个激活"在 native 侧也落实:去激活槽停传感器/定位/网络/音频;H5 侧由 appservice('2') 自停。

WeChat resp 路由保持现状(微信整体延期;双 Web 下发起槽持续存活,边缘情形见 m3-deferred 记录)。
devecocli build + scripts/test.sh 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:35:25 +08:00
lanterngamescn d7148a72e6 M5(T-M5-01/02): 双 Web 大厅/子游戏架构 + WebSlot 激活协议(真机验证通过)
- 新增 entry/web/WebSlot:封装单 Web 的桥+能力+激活生命周期(setup/onLoadIntercept/onPageEnd/
  onFirstProgress/activate/resumeLoaded/deactivate/onAppForeground/onAppBackground/dispose)
- BridgeGameContainer 重写为 Stack 双 Web:大厅常驻(始终在 Stack,subgame 时 Hidden+onInactive)、
  子游戏临时(subgameUrl 非空时渲染,onControllerAttached 各自 setup);替换 M2/M4 单 WebView loadUrl
- 激活协议:进子游戏 deactivate(大厅 appservice'2'+forEachBackground+setActive(false)+onInactive)→
  注入子游戏 app_data(LT'1')→建子游戏 slot→onFirstProgress(appservice'1'+setPostUrl);
  返回 dispose 子游戏→大厅 resumeLoaded(appservice'1'+getWebdata)
- 每槽独立 BridgeController+buildCapabilities(结构隔离,接口不串);nav/前后台事件路由到 activeSlot
- 内置测试包升级:gamehall+subA 自动驱动页(大厅→SwitchOverGameData→子游戏→backgameData→大厅)

真机验证(Pura 90 全新装):LOBBY LT=0 appservice1→SwitchOverGameData→LOBBY appservice2→
SUB LT=1 appservice1+独立 getTime→backgameData→LOBBY appservice1+getWebdata=fromSub。
大厅无二次 ready=未重载=常驻保活 ✓;接口不串 ✓;只一个激活 ✓。无 registration failed/RenderExited。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:32:18 +08:00
lanterngamescn a865ac766b M5: BridgeController 激活闸门 setActive(双 Web 基础件)
- BridgeController 加 active 状态 + setActive/isActive:
  - 非激活:onLoadIntercept 拦截 yy:// 但不分发(入站忽略)、dispatch 直接返回(出站抑制)
  - 保证双 Web 下"同时只有一个 Web 执行桥接口",且去激活端不会收到 native 推送
- 去激活顺序约定:先 callHandler(appservice,'2')(彼时仍激活),再 setActive(false)
- 单测新增 inactive_gate_suppresses_outbound_and_inbound;scripts/test.sh 通过
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:25:49 +08:00
lanterngamescn f190fe69e3 M5 设计验证:file:// 存储共享真机验证通过 + 文档定稿
验证(临时 VerifyStoragePage 真机跑后已回退):
- localStorage:两个不同 file:// 路径(lsA/lsB)+setPathAllowingUniversalAccess 跨页共享 ✓(lsB 读到 lsA 写的值)
- cookie:file:// 不支持 WebView cookie;原 Android cookie 全在 native HTTP 层(Volley),WebView 未开 file-scheme cookie,
  H5 不用 WebView cookie → 非缺口;http(s) cookie 由 WebCookieManager 应用级全局共享
- 结论:采用 file:// + setPathAllowingUniversalAccess + WebCookieManager(全局),无需自定义协议

文档:
- 框架新增 §7.5 双 Web 大厅/子游戏架构定稿(结构隔离/激活协议四联动/onInactive 不停JS的平台限制与 appservice 正解/存储验证结论/状态机/改造清单)
- 01_WBS:M5 标记"设计就绪",记存储验证通过
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 23:23:10 +08:00
lanterngamescn d196b13e39 设计:确认 M5 大厅/子游戏双 Web 激活模型(用户约束)
用户明确:大厅 Web 常驻、子游戏 Web 进入创建/返回销毁(不保活);同时只一个激活(联网+收发包+界面更新),
非激活端 onInactive 彻底停网络+渲染;仅 大厅↔子游戏、无子游戏→子游戏;两 Web 各自独立桥+能力。

- 框架 §7.1:子游戏切换加"双 Web 激活模型"铁律块;M2/M4 单 WebView loadUrl 标为过渡实现
- 框架 §9:Web 保活/预热行改为双 Web 槽 + onActive/onInactive 模型
- 01_WBS:T-M5-01/02 重写为双 Web 槽(大厅常驻保活 + 子游戏临时 + 仅一个激活 + 各自独立桥),估时上调
- 记入项目记忆 m5-dual-web-activation-model
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 21:49:45 +08:00
lanterngamescn 6bec98d584 review: M3+M4 成果审查后的质量加固
八角度审查 15 Provider+微信/七牛+双容器+导航。桥核心/契约骨架基本无误;修确凿问题:

正确性/健壮性
- ShakeProvider:stop()/onDestroy 取消未决 shakeEnd 计时并复位 pending(修停止后仍触发出站、重启后首摇被吞、计时器泄漏)
- VibrateProvider:startRepeat 先 stopRepeat(修重复 repeatvibrator('1') 叠加出无法取消的孤儿计时链)
- PhotoProvider:JSON.parse 后 Array.isArray 守卫(修 H5 传非数组致 .map 抛错、出站永不下发使 H5 挂死);去不可达 .catch
- GenericWebContainer:getWebdata 直调改用 JSON.stringify 生成 JS 字符串实参(修 data 含换行/行分隔符断行致注入语法错误)
- LocationProvider:单次请求前先停连续监听(修连续后切单次仍持续推送);去 push() 中 !continuousOn→stopContinuous 死代码

加固/清理
- BridgeGameContainer:抽 firstReadyPush() 幂等助手(appservice/setPostUrl/pendingWebdata);保持 100% 触发时序
  (注明为何用 100% 而非更早 onPageEnd:确保 H5 已注册 handler);aboutToDisappear 置空 hostCtx/config/resource

研判驳回(与原 Android 一致/契约默认/自愈):getphonestate CallState 值映射、通用容器 orientation 默认横屏、setMuted prepared 自愈、exitDialog backgameData() 无参通知。
延期(随微信集成):WeChatApi 单例陈旧回调/instanceof(容器重建后回调打旧 bridge;微信运行期本就待开放平台注册)。
记录待重构:AbstractProvider 基类 + parseJson 助手(去 15 Provider 重复 bridge/ctx/解析样板)、AVPlayer 复用、openBrowser/orientation 抽公共。

devecocli build 通过;单测通过;模拟器复测桥往返/appservice/setPostUrl 无回归。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 21:30:06 +08:00
lanterngamescn 6bd0cf7488 计划进度:M4 完成、NavProvider(T-M3-06)完成
- 01_任务分解WBS:M4 标记完成;T-M3-06 随 M4 完成;M3 进度 16/17(余 T-M3-17 真机回归、录音待服务端)
- 真机冒烟:16 能力含 nav 全注册、桥 appservice/getTime/nativeEcho 往返无回归(无 registration failed/RenderExited)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 21:00:56 +08:00
lanterngamescn 98854f7312 M4: 通用网页容器 + SettingsProxy + NavProvider + 子游戏切换
T-M4-01/02/03 GenericWebContainer(§11.3 第二套机制,不挂桥):
  - javaScriptProxy 注入 settings 对象 6 方法(SettingsProxy,函数回调避开 ArkTS 对象字面量限制)
  - 首次 100% runJavaScript 直调 getWebdata('<data>');返回键 isbackfinishweb→gamebackkeydown /
    isexitdialogeshow→退出确认→backgameData();关闭 pop({data}) 101 语义回上层
  - orientation "1"竖/其他横(window.setPreferredOrientation);browser 隐式 want
T-M3-06 NavProvider:OpenurlTitleData(开通用容器,onPop→callHandler getWebdata)、
  SwitchOverGameData(同容器 loadUrl 切子游戏+重注入 app_data(launchtype'1')+方向+复位首屏标志)、
  getGameinstall(同步 1/0 查 <解压根>/<dir>/index.html)、backgameData(重载大厅+待加载后 getWebdata)
导航解耦:common NavEvents(名+具名 payload interface);NavProvider 发 EventBus → BridgeGameContainer 执行
  (容器持 pathStack/controller)。EventBus payload 放宽为 Object(ArkTS 禁 Record 字面量),用 GenericEventData
domain AppDataInjector.buildValues 复用(StartupOrchestrator + 子游戏切换共用,去重)
组装根装配 NavProvider

devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:58:10 +08:00
lanterngamescn ef04f4e9e1 计划进度:M3 批5(音频播放+七牛上传器,15/17)
01_任务分解WBS:T-M3-10 音频播放完成、录音分档(QiniuUploader 就绪);M3 进度 15/17;
余 T-M3-06 NavProvider(并入 M4)、T-M3-17 真机回归
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:14:29 +08:00
lanterngamescn 4a8524bcbe M3(批5): AudioProvider 播放 + 七牛上传器(@qiniu/upload)
依赖:ohpm i @qiniu/upload@1.0.2(platform)

platform QiniuUploader:UploadFile.fromPath + key + createMultipartUploadV2Task(context,file,{tokenProvider})。
  🔴 token 走 tokenProvider(服务端用 AK/SK 生成 uploadToken(bucket)),AK/SK 不入端——纠正原 Android 硬编码 AK/SK

T-M3-10 AudioProvider(@kit.MediaKit AVPlayer):
  - mediaTypeAudio:播放语音 url → gameui_play_voice/gameui_stop_voice(user 透传)
  - srcIsloop:播放本地 wav(<gameDir>/assets/wav/<src>,isloop 0一次/>0循环/<0停止)
  - voicePlaying:静音总开关 setVolume
  - prepareaudio:录音分档(QiniuUploader 链路就绪;按住说话手势+麦克风+七牛服务端 token 三依赖未就绪前安全空实现)

bucket/域名/key 规则对齐原工程(bucket gameauio、回放 http://gameaudio.daoqi88.cn/<key>,由服务端 token 与 AudioProvider 接入时落地)
devecocli build 通过(CompileArkTS 编译七牛/音频无误)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:14:02 +08:00
lanterngamescn 829f267966 计划进度:M3 批4 完成(14/17,图片/摇/扫码/相机/定位)+ 真机回归冒烟
- 01_任务分解WBS:T-M3-07/08/09/11/12 标记完成;M3 进度 14/17;
  余 T-M3-10 AudioProvider(录音上传需服务端,待单独推进)、T-M3-06 NavProvider(并入 M4)、T-M3-17 真机回归
- 真机冒烟:15 个能力全部注册成功、桥 appservice/setPostUrl/getTime/nativeEcho 往返无回归(无崩溃/RenderExited)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:02:54 +08:00
lanterngamescn 9dc3e2ddf7 M3(批4): 图片/摇一摇/扫码/相机/定位 Provider
T-M3-07 PhotoProvider:getphoto 批量下载到资源根 photos/(file:// 白名单内) → 出站 getphoto[{pid,photourl}],复用 Downloader 并行
T-M3-08 ShakeProvider:startshake/SwitchShake/stopshake,@ohos.sensor 加速度合力阈值检测+节流,~1s 后出站 shakeEnd(空串),反馈震动
T-M3-11 ScanProvider:opensaoma → @kit.ScanKit 默认界面扫码(免权限) → 出站 getsaomaData(originalValue)
T-M3-12 CameraProvider:opencamera → @kit.CameraKit cameraPicker.pick(免权限) → 出站 getcameraaAddress(resultUri)
T-M3-09 LocationProvider:startlocation(连续/单次,用时申请权限)/getlocationinfo(同步) → geoLocationManager 定位+逆地理编码 →
        出站 getlocationinfo(MaplocationInfo;错误码 0/-1未就绪/-2权限拒绝)
module.json5 增 ACCELEROMETER/LOCATION/APPROXIMATELY_LOCATION;组装根装配 5 者

devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:59:04 +08:00
lanterngamescn 841a964693 计划进度:M3 批3 完成(10/17,微信分享+登录)
01_任务分解WBS:T-M3-13/14 标记完成;M3 进度更新为 10/17
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:43:40 +08:00
lanterngamescn b1e3ce7433 M3(批3): 微信分享 + 登录(@tencent/wechat_open_sdk)
依赖:ohpm i @tencent/wechat_open_sdk@1.0.19(feature_capabilities)

T-M3-13 ShareProvider:friendsSharetypeUrlToptitleDescript → SendMessageToWXReq(scene 会话/朋友圈)
        + WXWebpageObject → 回传 sharesuccess{success(2成功/3取消),type(1好友/2朋友圈)}。
        type 2截图/3图片/4视频暂回退网页分享(TODO);微信未安装回 cancel 不卡死
T-M3-14 LoginProvider:accreditlogin("1"=QQ空实现/其他=微信) → SendAuthReq(scope snsapi_userinfo) → 取 code。
        🔴 AppSecret 不入端:code 换 profile 必须服务端,无端点时记录 code+TODO,不推不完整 sharelogin(红线)
WeChatApi 单例:createWXAPI(AppID wxd2bd650e06bdfe58 公开标识) + sendReq + handleWant 路由 onResp
EntryAbility.onCreate/onNewWant → WeChatApi.handleWant(接收微信回调)
module.json5:querySchemes ["weixin"](isWXAppInstalled)

运行期成功前提(已注释说明):微信开放平台注册本 HarmonyOS 应用(bundleName+指纹绑 AppID)、登录 profile 需服务端 code 换取端点。
devecocli build 通过(CompileArkTS 编译微信代码无误)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:43:11 +08:00
lanterngamescn 89af002e95 计划进度:M3 进行中(批1+批2 完成,8/17)
01_任务分解WBS:M3 标记进行中,新增 M3 任务明细块(已完成 6 Provider+2 桩,余 摇/定位/音频/扫码/相机/图片/分享/登录/导航/回归)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:20:46 +08:00
lanterngamescn 7af1d7e834 M3(批2): DeviceProvider + NetworkProvider
T-M3-02 DeviceProvider:getTime/getphonestate(call.getCallState)/getmarketname/getothername(按名查本地配置)/
        getOther/getcompareCode(暂返 '0' 待接版本决策) 同步返回;getbattery→getBattery(batteryInfo.batterySOC/100)、
        getwifiLevel→getwifiLevel(wifiManager 信号 0~4)、getphoneInfo→getphoneinfo(deviceInfo;IMEI/IMSI/MAC 鸿蒙受限留空) 出站推送。
        裸串 vs JSON、出站命名陷阱(getphoneinfo 小写/getBattery 大写)逐字对齐
T-M3-03 NetworkProvider:getnetwork 同步返回 1无网/2WiFi/3移动(connection.getDefaultNet+bearerTypes);
        connection 订阅 netAvailable/netLost/netCapabilitiesChange 变化时出站广播 getnetwork;onDestroy 注销
module.json5 增 GET_NETWORK_INFO/GET_WIFI_INFO;组装根装配二者

devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:19:54 +08:00
lanterngamescn 59b000ce7a M3(批1): 占位桩 + 震动 + 剪贴板 + 系统能力 Provider
T-M3-15 RoomStubProvider/PayStubProvider:createRoom/exitRoom/getVideoinfo/DragViewvideoIsshow、
        paybrowser/getGameplay 全 void 空实现+日志,绝不触发出站(§6.5 安全网)
T-M3-04 VibrateProvider:vibrator/repeatvibrator/canclevibrator(@ohos.vibrator,重复用递归 setTimeout)
T-M3-05 ClipboardProvider:gameCopytext/gamepastetext(@ohos.pasteboard,读取经 responseCallback 回执)
T-M3-01 AppSystemProvider:orientation(window.setPreferredOrientation 横/竖)、browser(隐式 want)、
        finsh(terminateSelf)、openApplyDownloadpath(按包名启动失败回退浏览器)、notification(空)
组装根 buildCapabilities 装配上述 + 桩;module.json5 增 VIBRATE 权限

devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:15:21 +08:00
lanterngamescn 4590d5bf70 review: M2 成果审查后的质量加固
三路+对照审查 M2 全部成果。桥核心(M1,本期未改)与契约骨架零问题;发现集中在新的资源/启动/容器代码,已修:

高危
- ResourceManager.updateGame 原子化:下载→解压暂存→校验 <gamestart>/index.html→才删旧并 rename 换入。
  修复"先删旧 gamehall 再解压,失败即把可用资源砖掉"且 catch『keep local』失效的数据丢失风险
- BridgeGameContainer.setupBridge:先建桥并赋值 this.bridge,能力注册/配置加载整体兜底 try/catch。
  修复"config/registration 抛错→bridge 永远 undefined→H5 所有 callHandler 静默"违反 H5 零改动铁律

中危
- VersionResolver:空 gameid 守卫(大厅不参与 game 树匹配,避免误命中 gamelist 空 id 节点);
  两树 version 平手时取"有下载地址"的一棵(避免选中只有版本号无下载地址的层)。新增 2 单测,覆盖率 83.7%
- Downloader:dataReceive 写盘失败标记并于请求结束后抛出(避免磁盘满致截断文件被当作下载成功)
- FileSystem:rmrf 的 statSync 纳入 try(兑现"不存在/竞态则忽略"承诺);copyRawFileTo 按
  byteOffset/byteLength 切片写入(避免 Uint8Array 为大池子视图时写入多余字节致 zip 损坏);新增 rename
- ConfigManager.fetchSecondary:二级节点本层版本字段也并入(此前只换 channellist/agentlist 会丢节点自身版本/下载地址)

清理/抗回归
- 跨域白名单路径改用 ResourceManager.resourceRoot()(单一来源,避免与领域层路径定义漂移致 V2 回归)
- 前后台订阅移到 setupBridge(桥就位后),避免冷启动 FOREGROUND 早于桥到达被丢
- prepareBuiltin 单次读取内置包(去掉"先整包读探测、再整包读拷贝"双读)
- LocalUploadServer 删死码 isRunning/running
- 文档化延期项:weburl 分支不注入 app_data(同 Android,远程大厅自带)、app_gamename 待 M3 扩展 VersionXml、
  子游戏切换 firstProgressDone 复位 TODO(M3 T-M3-06)

devecocli build 通过;单测全通过;模拟器复测 app_data/V2 fetch/桥双向/特殊字符往返均无回归。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:05:46 +08:00
lanterngamescn 40b8c2e91c 计划进度:M2 完成、R-02(V2 file:// 跨域)关闭
- 01_任务分解WBS:M2 标记完成(13 任务),新增 M2 任务明细块与决策/偏差记录
- 03_风险登记册:R-02 关闭(setPathAllowingUniversalAccess 方案 + 真机复测 OK)
- 框架 §7.3:file:// 跨域改为已验证的具体方案(setPathAllowingUniversalAccess),保留 onInterceptRequest 回退
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:43:18 +08:00
lanterngamescnandClaude Opus 4.8 2100faaef7 M2(V2 阻塞性验证通过): setPathAllowingUniversalAccess 解决 file:// 跨域
T-M2-08 V2:真机验证 file:// 加载下 H5 fetch/XHR 取本地资源——首测被 CORS 拦截
(origin 'null',file 协议不在允许跨域 scheme 列表,正是框架 §7.3 预判风险)。
启用官方方案 WebviewController.setPathAllowingUniversalAccess([filesDir/tsgames]),
对 H5 完全透明(仍 file:// 加载)。复测:V2 fetch/XHR OK。

真机端到端链路全通(Pura 90 模拟器):启动编排→远程失败降级本地→解压内置包→
注入 app_data.js→file:// 加载大厅→跨域 fetch OK→桥握手→getTime 回执→nativeEcho
特殊字符往返一致。app_data 全局变量、Launchtype=0、appservice/setPostUrl 下发均正确。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:41:42 +08:00
lanterngamescn 2b0bd1f392 M2(容器+能力骨架+启动接线): CapabilityProvider/Registrar/AppModule + BridgeGameContainer 完整化 + Splash 接编排
T-M2-13 能力插件框架骨架:CapabilityProvider/CapabilityContext 接口、CapabilityRegistrar(批量注册+生命周期转发)、
        组装根 AppModule.buildCapabilities()(唯一知道全部能力处)、EchoSampleProvider 样板
T-M2-10 BridgeGameContainer 完整化:经 Registrar 注册能力(替换内联 handler)、首次进度 100% 推 appservice/setPostUrl、
        加载 params.entryUrl(回退 test_echo)、前后台 EventBus 联动、aboutToDisappear 全量清理;getContext→getHostContext 去弃用
SplashPage:进入即跑 StartupOrchestrator,完成 replace 进大厅、showmessage 阻断弹公告、进度条
内置测试大厅 rawfile/gamehall_builtin.zip(gamehall/index.html+data/test.json+version.xml,正斜杠标准 zip),
  作 M2 端到端 + V2(file:// XHR) 离线验证页;真实大厅由远程 zip 在生产下发

devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:36:59 +08:00
lanterngamescn d2da223c8d M2(领域层): ConfigManager/VersionResolver/ResourceManager/AppDataInjector/StartupOrchestrator
T-M2-05 ConfigManager:本地 rawfile/app_config.json(§4.2 实测值)、远程 URL 拼装('-'→'/'+.txt+?a=ts 禁缓存)、
        长度<30 走 showmessage 阻断、二级 url 二次请求(语义待真机校验)、产出版本决策
T-M2-06 VersionResolver:纯函数,agentlist/gamelist 两棵树 + agent→channel→market→game 后层覆盖 +
        两树取更高 version(§4.4)。单测 8 用例全通过,覆盖率 81.8%(≥80%)
T-M2-07 ResourceManager:沙箱路径规范、内置包拷贝解压、version.xml 解析(@ohos.xml)、远程 zip 下载/删旧/解压、版本比较
T-M2-09 AppDataInjector:加载前写 <gameDir>/app_data.js(§6 全局变量同名同义,JSON.stringify 安全字面量)
T-M2-11 StartupOrchestrator:INIT→…→ENTER_HALL 状态机,远程失败降级本地、showmessage 阻断、weburl 空/非空入口规则
配套:module.json5 声明 ohos.permission.INTERNET + reason_internet 字符串

devecocli build 通过;scripts/test.sh 单测全通过(修复 PermissionRequestResult 顶层导入)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:29:45 +08:00
lanterngamescn ecb0e4642a M2(平台层): KvStore/FileSystem/HttpClient/Downloader/Unzipper/PermissionGuard/LocalUploadServer
T-M2-01 存储/文件:KvStore(preferences 持久化 urlpath/upurlpath)、FileSystem(fileIo 建删读写/列目录/拷贝内置 rawfile)
T-M2-02 网络/下载:HttpClient(GET 禁缓存,契约 §4.3)、Downloader(http 流式写盘+进度,原生异步不阻塞 UI)
T-M2-03 解压:Unzipper(zlib.decompressFile,原生异步)。偏差:下载/解压用原生异步 API 即满足"UI 不阻塞",
        独立 TaskScheduler(TaskPool) 推迟到 M5 真有 CPU 密集任务(MD5)时再加,避免投机性死代码。
T-M2-04 权限/上传:PermissionGuard(用时申请,沙箱文件免存储权限)、LocalUploadServer(骨架,本机端口服务 M3 落地)

devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:14:41 +08:00
lanterngamescnandClaude Opus 4.8 bdb920f61e review: M0/M1 成果审查后的质量加固
三路独立审查:桥引擎(对照 lzyzsd 逐字)与契约 SSOT(对照原 Android 44 handler)
两个命门维度【零问题】;以下为架构/质量改进项的修复:

- [安全红线] BridgeGameContainer setWebDebuggingAccess 加 AppEnv.isDebug() 守卫
  (common 新增 AppEnv,用 bundleManager.appInfo.debug 运行时判断,release 自动关闭,
  消除 CLAUDE.md 附录B 红线违反)
- [生命周期] BridgeController 加 dispose() 清回执表/注册表/启动队列;HandlerRegistry 加
  clear();容器 aboutToDisappear 先 dispose 桥再 dispose adapter 并置空,防残留命中/泄漏
- [事件总线] EventBus.on/once 返回取消函数支持 per-subscriber 精确退订;off→offAll 并
  标注谨慎(避免 M3 多容器订阅 appservice 时误注销他人回调)
- [单测] 加强 escape 断言覆盖内层 " 加倍(命门);新增 dispose 用例;16 用例全通过,
  桥核心覆盖率 89.0%
- [记录] Index.pageMap param as 运行期不校验,M4 外部 scheme 唤起时需补校验(已注释)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:16:37 +08:00
lanterngamescnandClaude Opus 4.8 74b302e131 计划进度:M1 完成、R-18 关闭
- 01_WBS:M1 ☑ 完成(8 任务全 ☑,V1 通过、桥核心覆盖 87.3%)
- 03_风险登记册:R-18 关闭(探明 hvigorw 本地单测命令,封装 scripts/test.sh)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:27:18 +08:00
lanterngamescnandClaude Opus 4.8 159dcf2687 M1: 桥引擎单测跑通,桥核心覆盖率 87.3%(T-M1-08 完成,R-18 处置)
- 修复 2 个测试用例(漏先触发 flushMessageQueue 注册 _fetchQueue 回调)
- 补 set_default/remove、FakeWebController、send 用例,共 15 用例全通过
- 桥核心覆盖率 87.3%(MessageCodec/Message 100%、BridgeController 83%、
  HandlerRegistry 88%)≥80% 达标;Adapter/BridgeJsLoader 系统耦合由 V1 真机覆盖
- scripts/test.sh:本地单测 + 覆盖率运行脚本(devecocli 无 test,用 DevEco hvigorw
  + 强制 DEVECO_SDK_HOME 指向自带 sdk);ci.sh 集成单测(SKIP_TESTS=1 可跳过)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:26:23 +08:00
lanterngamescnandClaude Opus 4.8 38307e8d71 计划进度:M1 核心+V1 通过、单测受阻登记 R-18
- 01_WBS 进度总览:M1 近完成,T-M1-01~07 全 ☑、V1 真机通过;T-M1-08 单测代码就位待运行
- 03_风险登记册:新增 R-18(单测运行工具链缺口)+ 受阻任务记录 T-M1-08

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:07:49 +08:00
lanterngamescnandClaude Opus 4.8 5587df0562 M1: 桥引擎单测代码(T-M1-08,运行待工具链)
- entry/src/test/Bridge.test.ets:13 用例覆盖
  MessageCodec(toJson省略/response/escape转义/toArray)、
  HandlerRegistry(put/get/默认兜底不抛错)、
  BridgeController(入站分发+回执/出站callHandler/启动队列补发/
  responseId回执路由/未注册名默认兜底) —— 用 FakeWebController 纯逻辑、不依赖设备
- 接入本地单测入口 List.test.ets
- ⚠ 运行受阻:devecocli 无 test 子命令,本地单测 hvigor task 未常规暴露,
  待定运行方式(DevEco IDE / CI / 其他)后跑覆盖率(目标 ≥80%)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:06:55 +08:00
lanterngamescnandClaude Opus 4.8 3e2b1282ba M1: 容器接桥 + V1 阻塞性验证通过(T-M1-05/06/07)
- BridgeGameContainer 挂 Web + 接桥:onControllerAttached 建桥/注册 handler、
  onLoadIntercept 接桥、onPageEnd 注桥 JS + 补发启动队列、aboutToDisappear 释放
- test_echo.html 最小回显 H5(getTime 往返 + nativeEcho 特殊字符转义往返)
- 修复:dispatch 出站补转义单引号——lzyzsd 原版遗漏,_handleMessageFromNative('...')
  单引号包裹下 data 含 ' 会破坏字符串;补转义对 H5 透明(JSON.parse 仍得原始 data)
- ⚠ V1 真机通过:yy:// 被 onLoadIntercept 捕获、_fetchQueue 经 yy://return 回传、
  双向回执、含 "\/'中文 特殊字符转义往返一致。技术路线成立,无需回退

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:01:35 +08:00
lanterngamescnandClaude Opus 4.8 206db9730a M1: 桥引擎核心(T-M1-01~04)
100% 复刻 lzyzsd/JsBridge(对照原 Android com.tagmae.jsbridge 逐字):
- IWebController + WebviewControllerAdapter(emitter UI 线程守卫,§5.5) + FakeWebController(单测用)
- Message(5字段,undefined省略) + MessageCodec(toJson/toArray + dispatchMessage 两次正则转义逐字复刻)
- HandlerRegistry + 空实现 DefaultHandler 兜底(H5 调用永不报错最后防线)
- BridgeController:onLoadIntercept(decode→yy://return/yy://)/callHandler/send/onPageEnd/
  flushMessageQueue(_fetchQueue 经 yy://return 回传,非 runJavaScript 返回值)/handleReturnData/
  启动队列补发;对能力零感知、纯逻辑可测
- build 编译通过(ArkTS 严格)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:51:11 +08:00
lanterngamescnandClaude Opus 4.8 9280c00809 计划进度更新机制 + 标记 M0 完成
- CLAUDE.md 工作约定新增「及时更新计划进度」:按 Plan 实施时主动更新
  01_任务分解WBS 任务状态,与代码提交同节奏
- 01_任务分解WBS 新增「进度总览」:M0 全部 7 任务标记完成 ☑,M1~M6 未开始;
  记录 M0 期间确立的项目决策(包名/横屏/验证策略/devecocli 无 test)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:40:24 +08:00
lanterngamescnandClaude Opus 4.8 82459c708c 横屏改为 auto_rotation_landscape:横屏两朝向跟随传感器旋转,不进竖屏
- module.json5:landscape → auto_rotation_landscape(横屏正/反向 180° 跟随重力
  感应自动旋转,但不进入竖屏),build 校验取值合法、安装启动通过
- 同步契约 §7 与框架 §7.4:'不跟随传感器' 修正为 '横屏两朝向内跟随旋转'
- H5 显式方向控制(含竖屏)仍由 setPreferredOrientation 保留,零改动不变

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:38:05 +08:00
lanterngamescnandClaude Opus 4.8 dbc416a940 entry: EntryAbility 配 orientation:landscape,脚手架默认横屏
落地横屏项目约束(契约 §7 / 框架 §7.4):module.json5 配默认横屏、
不随传感器自动旋转;H5 显式方向控制留待 M3 用 setPreferredOrientation 动态实现。
模拟器验证:启动即横屏(2856x1320),SplashPage 布局正常。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:34:34 +08:00
lanterngamescnandClaude Opus 4.8 3a333bfe32 docs: 补充横屏项目约束(默认横屏、不支持竖屏自动旋转)
- 契约规范 §7:新增屏幕方向约束——默认横屏、不跟随传感器自动旋转;
  但遵守 H5 零改动铁律,保留 orientation/SwitchOverGameData webtype/通用网页
  orientation 三处 H5 显式方向控制(含竖屏),与原 Android 一致
- 框架指南 §7.4:实现落地——module.json5 orientation:landscape 默认横屏 +
  运行时 window.setPreferredOrientation 按 H5 请求动态切换
- 经核对原 Android:上述三处确为真实竖屏切换(非死代码),故定调为
  '默认横屏 + 不破坏 H5 方向控制'

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:26:40 +08:00
lanterngamescnandClaude Opus 4.8 300f6d9b80 更改应用包名 com.example.gamelobby → com.lobby.daoqi
- AppScope/app.json5 bundleName 更新
- build 通过,产物 pack.info bundleName 已生效
- 注:代码无硬编码包名;原 DevEco 默认签名材料(default_gamelobby_*)按旧包名生成,
  日后配真机/自动签名需重新生成

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:15:04 +08:00
lanterngamescnandClaude Opus 4.8 dca926df5b M0: 构建/签名/CI(T-M0-03)
- 构建:build-profile 已有 debug/release buildMode,多模块 build 通过
- 签名:本期暂不配(模拟器调试已验证可装可跑);真机/release 时由 DevEco
  自动签名写入 build-profile.signingConfigs
- CI:scripts/ci.sh 平台无关校验脚本(devecocli build debug/release),任何 CI 可调;
  单测运行待 M1 桥引擎单测落地后启用(devecocli 当前无 test 子命令)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:05:18 +08:00
lanterngamescnandClaude Opus 4.8 7fb0c194f7 M0: App 入口与路由壳(T-M0-07)
框架 §4 路由骨架,Navigation + NavPathStack:
- AppRoutes:路由名(Splash/BridgeGame/GenericWeb)、容器参数类型、前后台事件名
- Index:@Entry 导航宿主,初始进 Splash,navDestination 按名分发
- SplashPage:启动引导壳(weclomeactivity1),replacePathByName 进大厅
- BridgeGameContainer:大厅容器壳(webviewActivity),pushPathByName+onPop 演示
  打开通用网页并接收 101 回传
- GenericWebContainer:通用网页容器壳(openwebActivity1),pop(result) 模拟
  backgameData 带数据返回(§11.2 结果码 101 语义)
- EntryAbility:onForeground/onBackground 经 EventBus 广播应用前后台事件
  (M3 容器订阅后 callHandler('appservice','1'/'2'))
- build 编译通过

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 07:44:57 +08:00
lanterngamescnandClaude Opus 4.8 f89275ea4b M0: 引入桥 JS(T-M0-06)
- WebViewJavascriptBridge.js 原样复刻到 feature_bridge/src/main/resources/rawfile
  (与原 Android assets 去尾随空白后逐字一致,lzyzsd 协议 100% 复刻)
- BridgeJsLoader:从 rawfile 读取桥 JS(getRawFileContentSync + TextDecoder)并缓存,
  供 M1 BridgeController 在 onPageEnd 注入;HarmonyOS 走 runJavaScript 无需去注释
- 经 build smoke 验证 rawfile 读取 API 签名与编译通过

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 07:41:11 +08:00
lanterngamescnandClaude Opus 4.8 f7f208e6c8 M0: common 公共设施(T-M0-05)
框架 §10 横切层:
- Logger:基于 HiLog 的分级日志(d/i/w/e/f),业务域 0x9527,tag 截断 31B
- BridgeTracer:桥消息 traceId 自增 + 阶段打点,可还原全链路
- EventBus:封装 @ohos.events.emitter(on/once/emit/off,string eventId)
- DIContainer:轻量 DI,支持单例/懒单例工厂注册与泛型解析
- ErrorCenter:异常收敛 + 处置策略(Notify/Silent/Report/Block),UI 处置经 sink 注入
- 经 entry 临时 smoke 验证编译通过(含 common→contracts 跨 HAR 引用)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 07:12:44 +08:00
lanterngamescnandClaude Opus 4.8 26299c06ce M0: contracts 契约类型 SSOT(T-M0-04)
落地《契约规范》§8/§9/§12,全工程唯一来源:
- InboundHandlers 枚举:45 入站 handler 名,原样拼写(finsh/canclevibrator/opensaoma 等)
- OutboundHandlers 枚举:21 出站 handler 名,含命名陷阱(getphoneinfo≠getphoneInfo、
  getBattery≠getbattery、backgameData-末尾连字符)
- PayloadType:入站/出站 raw|json 标注表 + 入站同步返回类型 + 查询函数
- DTO interface ×17(§12 字段同名同义):Sharetype/Maplocation/PhoneInfo/savephoto/
  videoinfo/Othervideoinfo/GamePay/PayState/ShareLogin/ShareSuccess 等
- Result<T> + Errors(ErrorKind/LocationErrorCode/AppError)
- 经 entry 临时 smoke 全量引用,CompileArkTS 编译通过

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 07:09:17 +08:00
lanterngamescnandClaude Opus 4.8 424c5f4d94 M0: 忽略 hvigor 生成物 BuildProfile.ets(保持仓库干净)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 06:59:12 +08:00
lanterngamescnandClaude Opus 4.8 6de9038a54 M0: 搭建多模块工程骨架(T-M0-01/T-M0-02)
- 在 entry 基础上新增 6 个 HAR:contracts/common/platform/domain_resource/feature_bridge/feature_capabilities(框架§4 工程结构)
- 依赖单向向下、无环、无传递依赖(T-M0-02):
  contracts←common←platform←domain_resource;feature_bridge←(contracts,common);
  feature_capabilities←(全部下层);entry←(全部下层)
- 各 HAR 含 build-profile/hvigorfile(harTasks)/module.json5(type:har)/Index.ets 导出入口
- devecocli build(debug) 全模块编译通过,entry 打包 HAP 成功

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 06:58:29 +08:00