真实抓包里的关键帧是 zlib 压缩的(space-100045260/s2c_0000.bin 整帧 915B → 解压后帧体 1799B;space-100073070/s2c_0004.bin 整帧 41590B → 解压后 255844B),M2 只在 Node 侧用 zlib 解、浏览器目标直接抛错。改为两端同一份纯 JS 实现 fflate 0.8.3,DecodeFrame 保持同步签名。关键修正:fflate 的 inflateSync 是「无包装 DEFLATE」,喂 zlib 流会报 unexpected EOF,zlib 包装要用 unzlibSync —— 官方客户端也正是用它(3DTank/src/module_24635.js:20 g = n.unzlibSync,来自 module_29518.js:1172),与我们同路。验收:Node 侧两个压缩帧的解压结果与 link.js 的 zlib.inflateSync SHA256 完全相同,且解压后完整解出记录(1 条 zt / 1 条 pt + 28 条 fields),M2 对照脚本仍 5 帧、一致叶子 26950 / 不一致 0;浏览器侧页面加载即自动跑自检、console 全项通过(已实际用浏览器打开确认);三个构建任务全绿;production 产物 524579 → 564689 字节(+40110,fflate 的 CJS 入口无法 tree-shake,后续可换 ESM 瘦身)。
53 lines
2.4 KiB
Kotlin
53 lines
2.4 KiB
Kotlin
// TankIcClient 客户端脚手架 —— Kotlin/JS (IR) + React 构建脚本
|
||
|
||
plugins {
|
||
// Kotlin 多平台插件,本脚手架只启用 js(IR) 目标
|
||
kotlin("multiplatform") version "2.1.21"
|
||
// 序列化插件,供后续协议层做 JSON / 二进制编解码
|
||
kotlin("plugin.serialization") version "2.1.21"
|
||
}
|
||
|
||
group = "com.tankic"
|
||
version = "0.1.0"
|
||
|
||
kotlin {
|
||
js(IR) {
|
||
browser {
|
||
commonWebpackConfig {
|
||
// webpack 产物文件名,index.html 按此名引用
|
||
outputFileName = "TankIcClient.js"
|
||
}
|
||
}
|
||
// 追加 nodejs 目标(保留 browser):让协议层 M1 自检能无头运行。
|
||
// Node 24+ 提供全局 WebSocket,与浏览器同接口,Connection.kt 两端通用。
|
||
nodejs {
|
||
binaries.executable()
|
||
}
|
||
// 生成可执行的 JS 产物
|
||
binaries.executable()
|
||
}
|
||
|
||
sourceSets {
|
||
val jsMain by getting {
|
||
dependencies {
|
||
// React 绑定(版本后缀 19.1.0 对应 React 19.1.0)
|
||
implementation("org.jetbrains.kotlin-wrappers:kotlin-react:2025.5.11-19.1.0")
|
||
implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom:2025.5.11-19.1.0")
|
||
// 序列化运行时
|
||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
|
||
// 协程运行时
|
||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
|
||
// HTML 构建库,游戏侧同样使用
|
||
implementation("org.jetbrains.kotlinx:kotlinx-html-js:0.12.0")
|
||
// fflate:纯 JS 的同步 zlib 解压(browser 与 node 共用一份实现,见 Protocol/Zlib.kt)。
|
||
// 版本依据:0.8.3 是 npm 上的 latest(0.8.2 之后唯一的修复版),且其 unzlibSync 对
|
||
// 真实抓包帧的解压结果与 3DTank/tools/server/link.js 的 zlib.inflateSync 逐字节一致。
|
||
// 用 unzlibSync 而不是 inflateSync:后者只吃「raw DEFLATE(无包装)」;官方客户端
|
||
// 网络层取的就是 unzlibSync(3DTank/src/module_24635.js:20)。
|
||
// 注意:gradle.properties 里 kotlin.js.yarn=false,走系统 npm 安装。
|
||
implementation(npm("fflate", "0.8.3"))
|
||
}
|
||
}
|
||
}
|
||
}
|