joywayer and Claude Opus 5
065ebb1f58
refactor(framework): native-bridge 内部命名现代化(外部契约保留)
...
外部契约逐字不变(与原生 app 零改动对接):
- handler 名白名单 14 个字符串(getVideoinfo/sharelogin/...)
- window.WVJBCallbacks / WebViewJavascriptBridgeReady 事件名
- window.settings.getothername API
- 回调签名 (data, responseCallback) 与数据结构
内部命名走现代专业风格:
- WVJB → NativeBridgeChannel(双向通信通道语义清晰)
- WVJBHandler → NativeHandler
- WVJBCallback → NativeResponseCallback
- WVJB_HANDLER_NAMES → NATIVE_HANDLER_NAMES
- WVJBHandlerName → NativeHandlerName
- createNativeBridge → createBridge
- getSetting → getNativeSetting(明确是原生注入)
- NativeBridge interface → Bridge(隐含 Native)
- isKnownHandler → isNativeHandlerName
- __nbBridge → __activeChannel
- __nbHandlers → __registeredHandlers
144/144 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 20:49:51 +08:00
joywayer and Claude Opus 5
9b69bb8611
feat(framework): 原生桥 WVJB + window.settings(NativeBridge facade)
...
严格对齐原 gameabc 项目 05_Func.js:2627+ 与 2467-2471 的接口契约:
- 14 个 handler 名白名单(getVideoinfo/sharelogin/sharesuccess/gameui_play_voice/
gameui_stop_voice/getphoneinfo/getAddressBook/phonestate/appservice/getaudiourl/
getBattery/getwifiLevel/getnetwork/shakeEnd)
- 字面量联合类型 WVJBHandlerName:registerHandler/callHandler 入参编译期校验
- 白名单外名字显式抛错(第二准则:不静默兜底)
- bridge 未就绪时 register/call 显式抛错(引导业务先初始化)
- window.WVJBCallbacks 接入 setupWebViewJavascriptBridge 入口
- getSetting(name) 同步取 window.settings.getothername(name)
Node 单测用 mock bridge + triggerReady() 模拟 WebView bridge 就绪。
Cocos 侧走相同 facade,原生侧 WVJB handler 零改动对接。
143/143 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 20:38:53 +08:00
joywayer and Claude Opus 5
4142f590ee
feat(framework): StoreBinder 响应式视图绑定 mixin
...
替代 1773 处 set_self 调用的视图端契约:
- bind(store, slot, cb): 首次同步 + 订阅变化
- unbindAll(): 退订全部(幂等,可重复调用)
- callback 抛错隔离:首次同步与后续订阅均不污染 binder 状态
设计为 mixin 而非 cc.Component 子类:
- 单测不依赖 cc(纯逻辑)
- 业务侧自由组合 cc.Component + binder
- 单一职责:StoreBinder 只管订阅,Component 管生命周期
135/135 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 20:03:22 +08:00
joywayer and Claude Opus 5
045d9ec8c9
feat(framework): 收包路由分界(ActiveGame + Router)
...
C 规范 §4.1 的红线落地:
- platform/agent/room 三个 route → 平台 handlers(未注册显式抛错)
- 其他 route → activeGame.onReceive(rpc, data)(未激活或不匹配显式抛错)
ActiveGame: 当前子游戏槽(set/clear/get),进房时 setGame、离房 clear。
Router: 纯分发,不持状态。错误一律抛(第二准则:不静默吞包)。
128/128 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 19:55:05 +08:00
joywayer and Claude Opus 5
d10c43e6ea
feat(framework): sdk 子游戏对接边界(IGameModule + GameContext)
...
GameContext(子游戏调用框架的唯一入口):
- 受限 net.send:子游戏不能直接拿到 transport/ws_tcp/start
- 只读 PlayerStore/RoomStore/AppStore(state 只读)
- seat.toView/fromView:替代旧 ChangeToStatus
- events: 子游戏自定义事件总线
IGameModule(子游戏实现,被框架调用):
- route: 本游戏的 game route(框架 Router 据此分发对局包)
- onEnter/onExit: 进入/离开牌桌
- onReceive(rpc, data): 接收对局包(框架已按 route 过滤)
- onReconnect(deskinfo): login 含 deskinfo 时触发(平台层不解析)
- serialize?(): 对局快照(断线重连用)
- 平台钩子 onPlayerJoin/onPlayerLeave/onReady/onDissolve/onOffline 默认空实现
架构零耦合规则 §3 保证:子游戏只能 import sdk + core 类型,
无法触碰 platform/net 内部实现。
118/118 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 19:50:49 +08:00
joywayer and Claude Opus 5
77be6c0d19
feat(framework): AppStore + PlatformSession(登录接入)
...
AppStore(=旧 GameData 子集): setIdentity/setServers/setPhase/applyLogin
- applyLogin 区分两类字段语义:
* 身份字段(agentid/channelid/agentmode/gameversion)缺省保留旧值
* 显示字段(agentname)缺省重置为空字符串
- phase 仅由 session 驱动,applyLogin 不写 phase
PlatformSession: 订阅 NetClient 事件总线 → 扇出到三 Store
- 'open' → phase=connected
- 'login'(state==0) → 三 Store 填充 + phase=loggedIn
- 'login'(state!=0) → phase=loginFailed, 不污染 playerid/roomcode
- 'reconnecting' → phase=reconnecting
- 'slow' → phase=slow
- 'kicked' → phase=kicked
110/110 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 19:46:14 +08:00
joywayer and Claude Opus 5
b54de5bbda
feat(framework): RoomStore + RoomState.players 类型精确化
...
RoomState.players: unknown[] → Array<PlayerState | null>
- 座位未占用显式为 null(不是 undefined、不是空对象)
- 长度由 maxPlayerCount 决定,RoomStore.applyRecovery 校验填充
deskinfo 字段注释强调"C 规范 §5 边界判据 2:平台层不持有、不解析",
新测试覆盖引用相等透传(不深拷贝)。
新增 RoomStore: applyRecovery/clear,响应式 + 类型化入参 RoomRecoveryData。
97/97 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 18:17:29 +08:00
joywayer and Claude Opus 5
7404719c24
refactor(framework): 删除 FrameSet 垫片,全面采用 Cocos 原生组件
...
Gameabc 多帧图切帧的迁移垫片(FrameSet)与 Cocos 现代化方向冲突:
- 散图命名 + prefix 加载 vs Auto Atlas 合图 + SpriteFrame 引用
- 自研异步组件 vs Cocos 内置 Button.Transition / Animation
- 制造"何时用 FrameSet vs Button"的概念困惑
新方案:多状态用 Button.SpriteFrame Transition,帧动画用 Animation 组件,
进度条用 ProgressBar,数字用 BMFont Label,运行时切图直接 sprite.spriteFrame = frame
(O(1) 赋值,无需 async)。
保留 ui/theme 与 atlas-* 资源(主流资产)。
90/90 tests pass, typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 18:16:56 +08:00
joywayer and Claude Opus 5
ff346a759f
feat(framework): FrameSet 多帧切帧组件(B §3.4)
...
承载 set_self(spid, 43, n) 的 C 移植调用:
- 1 基帧号, FrameIndex=0 按 1 处理(旧引擎 2 个对象如此)
- 越界显式抛错(第二准则:不兜底)
- 并发去重:多次 setFrame 在加载未完成时只触发一次 loadByPrefix
- 命名与 scripts/ui-migration/frames.mjs:frameFileName 公式逐字对齐
分层:
- core/frame-file-name.ts 纯公式,无 Cocos 依赖,直接单测
- ui/frame-set.ts 核心逻辑,FrameSource/FrameTarget 注入接口隔离 Cocos 类型
- ui/resources-frame-source.ts 生产实现,Resources.loadDir + Auto Atlas 合图过滤
tsconfig.framework.json 排除 resources-frame-source.ts(其含 cc 模块,走 Cocos 编辑器编译)。
103/103 framework tests pass,typecheck exit 0。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-31 17:50:22 +08:00
joywayer and Claude Opus 5
5a1afedfd3
feat(ui): theme 契约(类型+默认值+合并+Provider)
...
子游戏只写要改的字段, 缺省集中在 DEFAULT_THEME 一处(spec §4.3,
第二准则的唯一例外)。ThemeProvider 未 init 即读抛错, 不兜底。
皮肤构建期定死, 故静态读取不做响应式。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com >
2026-08-27 22:38:26 +08:00
joywayer and Claude Opus 4.8
4b4e2261b4
feat(framework): platform PlayerStore(=C_Player) applyLogin
...
Implement PlayerStore wrapping signal<PlayerState> for player account data.
Adds applyLogin(raw) to fill state from login response A group, with:
- Mandatory fields get default 0/'' if missing (never undefined)
- Optional fields (openid/unionid/province/city) only set if present
- Immutable updates via spread operator
- Notifies subscribers on state change
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 22:06:06 +08:00
joywayer and Claude Opus 4.8
854d72a420
feat(framework): core 响应式 signal 基元(自研薄封装)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 21:32:03 +08:00
joywayer and Claude Opus 4.8
883335f656
fix(framework): kick_server 终止不重连(对齐真实客户端)
...
收到 kick_server 时 emit kicked 并 stop(),不再 onClose→重连→重踢空转。
kick 处理移出登录门控,登录态内外一致。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 20:37:16 +08:00
joywayer and Claude Opus 4.8
ad661707ec
fix(framework): player_login.version 改为数字 versionCode(联调登录成功)
...
真机联调发现:协议 version 字段=数字 versionCode(源码 8 处 data.version=GameData.versionCode),
框架原发字符串 '1.1' 被服务器版本校验拒绝(kick_server 检查到新版本)。改为数字后登录成功
(state:0 playerid:430511)。
- ChannelIdentity/LoginRequestData.version: string→number,去掉冗余 versionCode 与未发送的 '1.1' 串
- query-string version 解析为数字;测试 fixture 同步
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 20:33:53 +08:00
joywayer and Claude Opus 4.8
96c6c7c914
fix(framework): decodeFrame 改单层(服务器协议非双层)
...
真机联调发现:服务器实发单层 {app,route,rpc,data};旧客户端的'外层 data'是浏览器
MessageEvent(00_minhttp.js:266 ws.onmessage=config.onmessage),非协议层。框架传输层
已取 ev.data,decodeFrame 不应再剥一层。修正后 kick_server 等业务包能正确解析。
- decodeFrame 单层化 + 测试改单层帧
- 更正 docs/protocol/01 §3.2(双层→单层,附 MessageEvent 依据)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 20:25:36 +08:00
joywayer and Claude Opus 4.8
5132fddc4e
feat(framework): config 调试 serverOverride(全链路+游戏服连本地)
...
- DebugProfile 加 serverOverride:debug 抓远程配置走全链路后把连接地址覆盖为此
- staging profile 加 serverOverride=ws://127.0.0.1:3088(联调本地测试服)
- release 一律忽略 serverOverride,用远程解析结果
- 同步指南
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 20:08:59 +08:00
joywayer and Claude Opus 4.8
d461578d6e
feat(framework): config 调试登录账号进 profile(DebugAccount)
...
- DebugProfile 加 account?: DebugAccount(openid 等登录字段,仅 debug 模式生效)
- resolveBootstrap 结果加 account:debug 取 profile.account,release 恒 undefined
- staging profile 留占位 account 待填真值;接入处 setIdentity 合并 identity+account
- 同步指南
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 19:57:41 +08:00
joywayer and Claude Opus 4.8
51a4ee57ac
refactor(framework): 移除 resolveBootstrap 下游兜底,立第二准则
...
- CLAUDE.md 新增「第二准则:数据源权威、唯一,下游不兜底」
- bootstrap 删除 fallbackServers 选项与 ?? DEFAULT_GAMESERVER 猜默认
- 无 server/gameserver、远程失败、解析不出地址 → 一律抛 ConfigFetchError 显式暴露
- 同步 guide + 两篇 spec(删 fallback/降级措辞)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 18:59:15 +08:00
joywayer and Claude Opus 4.8
5ab4a0a4b6
feat(framework): net NetClient 可选 debug 收发包日志
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 18:16:36 +08:00
joywayer and Claude Opus 4.8
2c2e487d8f
feat(framework): config resolveBootstrap 接入 mode + release 锁死 URL 覆盖
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 18:13:15 +08:00
joywayer and Claude Opus 4.8
8cbc488e0c
feat(framework): config 运行模式解析 resolveRuntimeMode(自动+手动覆盖)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 18:10:42 +08:00
joywayer and Claude Opus 4.8
c87d204f28
feat(framework): config 启动编排 resolveBootstrap(身份合并+服务器决策+降级)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 16:44:43 +08:00
joywayer and Claude Opus 4.8
6333ddc8e4
feat(framework): config 远程配置分层取参 getParam + 服务器解析 resolveServers
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 16:41:28 +08:00
joywayer and Claude Opus 4.8
231e9ee31c
feat(framework): config 调试 profiles + ?profile= 切换
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 16:38:44 +08:00
joywayer and Claude Opus 4.8
119a457c59
feat(framework): config 原生同步身份来源(window.settings/app_* 逐字对齐)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 16:36:13 +08:00
joywayer and Claude Opus 4.8
510c074627
feat(framework): config H5 URL query 身份来源
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 16:33:58 +08:00
joywayer and Claude Opus 4.8
2f97150a6f
feat(framework): config 身份类型 + 纯合并 resolveIdentity + 构建期默认
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 16:30:49 +08:00
joywayer and Claude Opus 4.8
dbc5d19e61
test(framework): login 全流程集成测试(over FakeTransport)
...
集成测试在断言处调用 parseLoginResponse(any login 数据),规避 TS6 对闭包内赋值变量经 assert.ok 收窄为 never 的 CFA 行为;断言与覆盖范围不变。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:27:56 +08:00
joywayer and Claude Opus 4.8
0ada512464
feat(framework): protocol routes 常量 + login 请求构造/响应解析
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:25:29 +08:00
joywayer and Claude Opus 4.8
540cf286a5
feat(framework): net-client 编排(login流程/门控/TcpID/超时重连/服务器切换/事件)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:24:57 +08:00
joywayer and Claude Opus 4.8
79d0071645
feat(framework): net 候选服务器轮询策略
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:23:41 +08:00
joywayer and Claude Opus 4.8
08d41cdec1
feat(framework): net 收包超时看门狗(注入 Clock 可测)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:23:13 +08:00
joywayer and Claude Opus 4.8
90843374f9
feat(framework): net Transport 接口 + 测试用 FakeTransport
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:22:47 +08:00
joywayer and Claude Opus 4.8
7dcdeb6615
feat(framework): net 信封编解码 + 握手/心跳/错误包识别
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:22:18 +08:00
joywayer and Claude Opus 4.8
c1be4dcb1e
feat(framework): core 座位↔视图转换
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:21:46 +08:00
joywayer and Claude Opus 4.8
bfd9339f64
feat(framework): core EventBus(类型化+故障隔离)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:21:26 +08:00
joywayer and Claude Opus 4.8
56dbfeb5e2
feat(framework): core 最小集协议类型(envelope/login)
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:20:54 +08:00
joywayer and Claude Opus 4.8
f693f45895
chore(framework): TS 测试基建(tsx+node:test) + core 常量
...
- 补 @types/node(tsconfig types:[node] 所需,原计划遗漏)
- tsconfig 加 allowImportingTsExtensions(import 带 .ts 后缀所需)
- test:framework 改用 run-framework-tests.mjs 递归枚举(node 20.13 <20.14 不支持 --test glob)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-28 14:20:25 +08:00