Files
mtgodot-poc/docs/ANDROID-TESTING.md
T
shenleiandClaude Opus 5 fb4d2d222b docs: 文档审计——修正失效链接与过期结论
按 docs/ 目录逐篇核对,只改与事实/路径不符的部分,不动尚未验证的计划条目:

- `docs/steps/**` 在早前整理时已迁到 `docs/reference/steps/**`,全仓的旧路径
  引用(PLAN.md / README.md / M0-gr2-reader.md 及 libgr2 的头注释)一并改正。
- CLIENT-GAP.md / CLIENT-GAP-FIX.md / BACKLOG.md / MIDREVIEW.md:把已经落地的
  条目从「待办」改为已完成,删掉与代码现状矛盾的描述。
- ANDROID-TESTING.md / CLIENT-PORT.md / CLIENT-ROADMAP.md / GODOT-POC-PLAN.md /
  SHINSOO-WORLD-RENDERING.md / PARITY-GAP.md:同上,另补当前实际的构建/测试入口。
- THIRD-PARTY.md:补齐实际在用的第三方来源与许可说明。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SJugvEJwz3FK4hw9ti3SRb
2026-09-08 17:15:17 +09:00

394 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- generated-by: gsd-doc-writer -->
# Android 真机测试指南
本文说明如何在 Android 真机上安装本客户端(APK 产物名仍是 `mtgodot-poc.apk`,包名 `org.internal.mtgodotpoc`)、生成并导入资源包、验证资源挂载,以及进行 40250 客户端测试。
## 1. 当前测试范围与已知前置条件
当前 Android 导出目标是 `arm64-v8a`APK 包名为 `org.internal.mtgodotpoc`,最低 Android SDK 为 24。APK 只包含代码和 Godot 工程资源;Metin2 的 `assets/``bgm/` 不打进 APK,测试时必须单独导入 `assets.zip`
当前仓库的资源部署存在一个需要特别注意的限制:
- `export-android.sh --install` 会把资源推到 `/sdcard/Android/data/org.internal.mtgodotpoc/files/assets.zip`
- `project/asset_pack.gd` 的候选顺序是 `MT_ASSETS_ZIP` 环境变量 → `user://assets.zip``OS.get_user_data_dir()/assets.zip` → 可执行文件目录 → `res://../assets.zip`(见 `_find_local_zip()`);上述外部目录不在候选路径里。
- 因此,Debug 真机测试应把外部目录中的压缩包再复制到应用私有 `files/` 目录,确保客户端的 `user://assets.zip` 能命中。
另外,40250 classic 网络栈当前由进程环境变量 `MT_PROTOCOL=classic` 选择。Android 通过 Activity 启动 APK 时不能直接继承 Mac 终端的环境变量;如果 APK 尚未增加 Android 侧的协议配置入口或将 classic 设为移动端默认值,则只能完成 APK、资源和 UI 验证,不能据此宣称已经完成真实 40250 登录验收。
公会功能按当前项目范围暂缓;龙魂玩法不属于目标 40250 服务器功能,不纳入 Android 验收。
## 2. 主机环境
以下版本来自当前 Android Gradle 配置和构建脚本:
| 项目 | 要求 |
|---|---|
| 主机 | macOSApple Silicon 构建脚本已按当前机器验证 |
| Godot | `4.7.1.stable`,并安装对应 Android 导出模板 |
| Android SDK | compile/target SDK `36`Build Tools `36.1.0` |
| Android NDK | `29.0.14206865` |
| Java | Gradle 配置最低 Java 17;当前脚本默认使用 OpenJDK 21 |
| Android 手机 | `arm64-v8a`,建议使用 Vulkan 设备 |
| 磁盘 | 至少预留 APK、资源包和临时构建空间;当前 `assets.zip` 约 2.12.2 GB |
进入仓库并设置环境变量。路径按本机安装位置调整:
```bash
cd /Users/shenlei/Work/mt/metin2-client
export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk"
export ANDROID_HOME="$ANDROID_SDK_ROOT"
export ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/ndk/29.0.14206865"
export JAVA_HOME="/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home"
export GODOT="/opt/homebrew/bin/godot"
export ADB="$ANDROID_SDK_ROOT/platform-tools/adb"
```
先确认工具存在:
```bash
"$GODOT" --version
java -version
"$ADB" version
test -f "$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake"
```
如果 Android SDK/NDK 尚未安装,可在 Android Studio 的 SDK Manager 中安装,或使用 `sdkmanager` 安装与上表一致的版本。不要只安装一个较旧 NDK 后直接构建;Gradle 模板要求的 NDK 版本以 `project/android/build/config.gradle` 为准。
Godot 还需要安装与 `4.7.1` 完全匹配的 Android 导出模板。可在 Godot 的“编辑器设置 → 导出 → 导出模板”中安装。
首次导出前生成 Debug keystore
```bash
./gen-debug-keystore.sh
```
## 3. 连接 Android 真机
在手机上完成以下设置:
1. 设置 → 关于手机 → 连续点击版本号,开启开发者选项。
2. 开发者选项中开启“USB 调试”。
3. USB 连接模式选择“文件传输/MTP”。
4. 首次连接时,在手机上确认“允许 USB 调试”。
在 Mac 上检查设备:
```bash
"$ADB" kill-server
"$ADB" start-server
"$ADB" devices -l
```
期望看到:
```text
<设备序列号> device
```
状态为 `unauthorized` 时,解锁手机并接受 RSA 授权;没有设备时,优先检查 USB 线、USB 模式、开发者选项和手机是否允许该电脑调试。
## 4. 生成资源包
资源包必须从与 APK 同一份工作树生成。执行:
```bash
./pack-assets.sh
```
该脚本会:
1. 执行 `bake_asset_index.gd`,生成 `assets/asset_index.txt`
2.`assets/``bgm/` 打成 `build/export/assets.zip`
3. 使用 `zip -0` 原样存储,不压缩 `.dds``.gr2` 等大型资源。
4. 排除 `.git``.DS_Store``assets/.gdignore`
检查资源包:
```bash
ls -lh build/export/assets.zip
unzip -l build/export/assets.zip | rg 'assets/asset_index\.txt|assets/|bgm/' | head -n 20
```
不要手工解压到 APK,也不要把完整 `assets/` 强行放进 `res://`。客户端启动时通过 `ProjectSettings.load_resource_pack()` 挂载 zip,挂载成功后资源以 `res://assets/...``res://bgm/...` 访问。
资源发生变化后必须重新执行 `./pack-assets.sh`。只重新导出 APK 不会更新已经生成的 `assets.zip`
## 5. 构建 APK
建议先单独构建,不要在第一次测试时直接使用 `--install`
```bash
./export-android.sh Debug
```
构建成功后应得到:
```text
build/export/mtgodot-poc.apk
```
检查 APK 和 native library
```bash
ls -lh build/export/mtgodot-poc.apk
unzip -l build/export/mtgodot-poc.apk | rg 'lib/arm64-v8a/.*\.so'
```
应至少包含 `lib/arm64-v8a/` 下的 Godot Android 库和 `libmtgodot` 扩展库。
## 6. 安装 APK 并导入资源
### 6.1 安装 APK
```bash
"$ADB" install -r build/export/mtgodot-poc.apk
```
`-r` 会保留应用数据。若要完全清理测试数据,可选执行:
```bash
"$ADB" shell pm clear org.internal.mtgodotpoc
```
清理后必须重新导入资源包。
### 6.2 先推送到 Android 外部目录
```bash
PKG=org.internal.mtgodotpoc
EXT_DIR="/sdcard/Android/data/$PKG/files"
"$ADB" shell mkdir -p "$EXT_DIR"
"$ADB" push build/export/assets.zip "$EXT_DIR/assets.zip"
"$ADB" shell ls -lh "$EXT_DIR/assets.zip"
```
### 6.3 Debug 测试复制到 Godot `user://`
当前 `Debug` APK 可使用 `run-as` 把外部文件复制到应用私有 `files/` 目录:
```bash
"$ADB" shell run-as "$PKG" sh -c \
"cp '$EXT_DIR/assets.zip' files/assets.zip"
"$ADB" shell run-as "$PKG" ls -lh files/assets.zip
```
最后一条命令能看到约 2.1–2.2 GB 的文件,才继续启动客户端。这个步骤是当前代码路径下的关键步骤;只执行 `adb push``/sdcard/Android/data/.../files/`,不能替代它。
如果 `run-as` 报告应用不可调试,确认安装的是 `Debug` APK,而不是 Release APK。Release 流程需要先修改资源查找/部署实现,使客户端明确支持外部目录,不能假设 `run-as` 可用。
### 6.4 资源更新
客户端退出后,只更新资源包时执行:
```bash
./pack-assets.sh
"$ADB" push build/export/assets.zip "$EXT_DIR/assets.zip"
"$ADB" shell run-as "$PKG" sh -c \
"cp '$EXT_DIR/assets.zip' files/assets.zip"
```
资源挂载只在 `client_main.gd::_ready()` 中执行,因此更新后必须重启客户端,不能只切回前台:
```bash
"$ADB" shell am force-stop "$PKG"
```
## 7. 启动客户端并确认资源挂载
清空旧日志后启动:
```bash
"$ADB" logcat -c
"$ADB" shell am start -n \
org.internal.mtgodotpoc/com.godot.game.GodotApp
```
实时查看日志:
```bash
"$ADB" logcat -v time -s godot GodotError AndroidRuntime
```
资源挂载成功的关键日志是:
```text
[AssetPack] mounted .../assets.zip
```
以下日志表示资源没有被找到或挂载失败:
```text
[AssetPack] 找不到 assets.zip
[AssetPack] load_resource_pack 失败
[client] 资源目录不存在
```
启动验收至少包含:
- 登录界面正常出现,而不是黑屏或立即退出。
- 登录背景、控件和字体资源正常显示。
- 选人页能加载职业模型、背景和界面资源。
- 进入游戏后能看到地图、地形、建筑、树木或角色模型。
- 日志中没有持续出现资源文件缺失、`FileAccess` 打开失败或 native library 加载失败。
可保存截图作为测试证据:
```bash
mkdir -p build/export/android-evidence
"$ADB" exec-out screencap -p > build/export/android-evidence/launch.png
```
## 8. 40250 服务器连接配置
### 8.1 手机网络要求
手机必须能直接访问认证服/游戏服的 IP 和端口:
- 手机与局域网测试服连接到同一网络,或服务器开放公网访问。
- 客户端不能使用 `127.0.0.1``localhost` 指向 Mac;在手机上它们指向手机自身。
- 防火墙和 FreeBSD jail 的端口映射必须允许手机来源地址访问。
- 服务器端口以实际 `CONFIG` 为准,不要照抄示例端口。
### 8.2 `serverlist.txt`
客户端启动时会优先读取 `res://serverlist.txt`;没有该文件时使用 `project/net/serverinfo.gd` 中的内置默认值。真实 40250 测试应在导出前准备 `project/serverlist.txt`,格式为 TSV
```text
# 名称\t认证地址\t认证端口\t游戏地址\t游戏端口\t频道列表\t端口步长\t会徽端口
龙魂40250\t<服务器IP>\t<auth-port>\t<服务器IP>\t<channel1-port>\t1,2,3,4\t1\t0
```
例如 40250 仓库脚本中的默认 channel1 端口与当前客户端内置默认值并不相同,必须以目标 FreeBSD 服务器的 `CONFIG` 和实际监听结果为准。
<!-- VERIFY: 真实 40250 服务器 IP、auth/game 端口、频道数量和防火墙策略必须由当前 FreeBSD 部署确认。 -->
### 8.3 classic 协议选择限制
当前 native 代码仅在进程环境变量满足以下条件时切换 40250 classic 后端:
```text
MT_PROTOCOL=classic
```
在 Mac 上运行 Godot 时可以通过环境变量设置;但 Android APK 是由 Activity 启动的,普通的 `adb shell am start` 不会把 Mac 的环境变量传入 APK。因此,真实 Android 40250 登录测试前必须确认以下任一项已经完成:
1. Android 版本把 classic 设置为默认网络后端;
2. 客户端增加可持久化的协议配置并在 Android 导出中设为 `classic`;或
3. Android 测试包提供协议选择入口。
不要把下面的命令当作可靠解决方案:
```bash
adb shell MT_PROTOCOL=classic am start ...
```
它设置的是 `am` 命令进程的环境,不等于给已启动的 Android Activity 设置环境变量。
## 9. 真机功能验收清单
以下项目按实际 40250 测试账号、角色和 NPC 条件逐项记录:
### 启动与网络
- [ ] APK 安装成功,包名为 `org.internal.mtgodotpoc`
- [ ] `assets.zip` 已复制到应用私有 `files/`,大小与主机一致。
- [ ] 日志出现 `[AssetPack] mounted`
- [ ] 登录界面资源完整显示。
- [ ] 服务器/频道检测能得到预期结果。
- [ ] 认证成功后进入选人页。
- [ ] 选择角色后进入游戏场景。
### 世界与基础操作
- [ ] 地图、地形、建筑、树木、角色和纹理正常加载。
- [ ] 点击地面移动,角色位置与服务器同步。
- [ ] 普通攻击、目标选择、技能和动作没有异常断线。
- [ ] 聊天发送与接收正常。
- [ ] 切换前后台后连接和场景状态符合预期;断线时能看到重连提示。
### 已接入的常用功能
- [ ] 背包打开、物品使用、丢弃、移动和快捷栏操作。
- [ ] NPC 对话、脚本选项、输入框和确认框。
- [ ] 普通商店查看、切换货架和购买。
- [ ] 私人商店物品选择、定价、开设和撤收。
- [ ] 交易发起、物品/金币添加、确认和取消。
- [ ] 仓库密码、存入、取出和物品移动。
- [ ] 商城物品列表和取出。
- [ ] 组队邀请、接受、离队、成员状态和治疗入口。
- [ ] ESC 系统菜单、音量、镜头、雾效和显示设置持久化。
### 明确不纳入本轮
- 公会相关功能:按当前范围暂缓。
- 龙魂:目标 40250 服务器没有该功能,不进行功能验收。
- 真实 FreeBSD + MySQL 全流程验收:需要服务器环境和测试账号,不能用本机离线测试结果替代。
## 10. 测试证据保存
建议每次测试保留 APK、资源包校验值、设备信息和日志:
```bash
mkdir -p build/export/android-evidence
shasum -a 256 build/export/mtgodot-poc.apk \
build/export/assets.zip \
> build/export/android-evidence/artifacts.sha256
"$ADB" shell getprop ro.product.model \
> build/export/android-evidence/device-model.txt
"$ADB" shell getprop ro.build.version.release \
> build/export/android-evidence/android-version.txt
"$ADB" logcat -d -v time -s godot GodotError AndroidRuntime \
> build/export/android-evidence/logcat.txt
```
测试记录至少填写:构建时间、Git commit、APK SHA-256、`assets.zip` SHA-256、手机型号、Android 版本、服务器地址/端口、账号、测试结果和失败日志。
## 11. 常见问题
| 现象 | 处理 |
|---|---|
| `adb devices` 没有设备 | 开启 USB 调试、接受 RSA、切换 MTP、检查数据线;必要时重新执行 `adb kill-server` / `adb start-server` |
| 状态是 `unauthorized` | 解锁手机并接受“允许 USB 调试”,然后重新执行 `adb devices` |
| APK 安装失败 | 检查设备是否为 arm64;卸载旧包后再安装;查看 `adb install` 的具体错误 |
| `run-as` 报不可调试 | 安装 `Debug` APKRelease APK 不能依赖 `run-as` 导入资源 |
| 日志找不到 `assets.zip` | 确认外部 push 成功,再执行 `run-as ... cp ... files/assets.zip`,然后重启应用 |
| `load_resource_pack 失败` | 检查压缩包完整性、磁盘空间、是否由 `./pack-assets.sh` 生成,以及 zip 内是否存在 `assets/asset_index.txt` |
| 登录连接超时 | 手机不能使用 `localhost`;检查服务器 IP、端口、Wi-Fi/VPN、防火墙和 FreeBSD jail 映射 |
| 登录协议不对或立即断线 | 确认 Android 包实际选择了 `classic`,仅在 Mac 终端设置 `MT_PROTOCOL` 不会自动传入 APK |
| 黑屏或 Vulkan 崩溃 | 保存完整 `logcat`;当前 Android 移动 Vulkan 的 shader/GPU-skin 真机验证仍需在目标设备上进行 |
| 更新资源后画面不变 | 资源包挂载发生在启动阶段,执行 `am force-stop` 后重新启动;必要时清理应用数据并重新导入 |
## 12. 推荐的最短测试流程
首次测试按以下顺序执行:
```bash
cd /Users/shenlei/Work/mt/metin2-client
./pack-assets.sh
./export-android.sh Debug
export ADB="${ANDROID_SDK_ROOT:-$HOME/Library/Android/sdk}/platform-tools/adb"
PKG=org.internal.mtgodotpoc
EXT_DIR="/sdcard/Android/data/$PKG/files"
"$ADB" install -r build/export/mtgodot-poc.apk
"$ADB" shell mkdir -p "$EXT_DIR"
"$ADB" push build/export/assets.zip "$EXT_DIR/assets.zip"
"$ADB" shell run-as "$PKG" sh -c \
"cp '$EXT_DIR/assets.zip' files/assets.zip"
"$ADB" shell run-as "$PKG" ls -lh files/assets.zip
"$ADB" logcat -c
"$ADB" shell am start -n "$PKG/com.godot.game.GodotApp"
"$ADB" logcat -v time -s godot GodotError AndroidRuntime
```
只有在看到 `[AssetPack] mounted`、登录界面资源正常、并确认 Android 包使用正确的 40250 classic 后端后,才进入真实服务器功能验收。