Files
metin2-client/docs/AVA2-CHANNEL.md
T
shenleiandClaude Opus 5.5 13a462b6fc Add client-only channel switch (AVA2 ENABLE_CHANNEL_CHANGE)
mt_channel lists the serverInfo channels of the current server and switches by
running the original paths: /logout, then the login window connects to the
chosen channel with the account kept by MainStream, and the original
stream.isAutoSelect starts the same character. No server change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 21:37:02 +09:00

55 lines
4.1 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.
# AVA2 换线适配进度(v1)
2026-10-15。只改了 metin2-client,服务端不需要改动。参考了 AVA2 的 `ENABLE_CHANNEL_CHANGE`(`Locale_inc.h`)。AVA2 客户端只接收 `HEADER_GC_CHANNEL`(121)来显示当前频道,真正的换线由服务端完成;AVA2 服务端源码不在本机,所以这里没有照搬它的做法。
## 与 AVA2 的差异
| 项目 | AVA2 | 本实现 |
| --- | --- | --- |
| 换线方式 | 服务端把角色传送到目标频道的核心 | 客户端依次走原有流程:`/logout` → 登录界面 → 用保存的账号登录目标频道 → 自动选择同一角色进入游戏 |
| 服务端改动 | 需要(频道到端口的对应关系,或 DB/P2P 协议) | 不需要;本服务端的核心之间不知道其他频道的监听端口 |
| 频道列表 | 服务端提供 | 客户端 `serverInfo.REGION_DICT`,与登录界面的频道列表相同 |
| 等待时间 | 传送 | 原 `/logout` 倒计时(3 秒,战斗中 10 秒)加一次登录和读图 |
## 流程
1. 游戏内点“换线”,窗口列出当前服务器的频道。当前频道用 `【】` 标出且不能点。当前频道按 `MainStream` 的连接地址在 `serverInfo` 中查找;找不到时(例如测试端口 13040)显示“未知”,服务器取 `channel.inf` 中上次选择的服务器。
2. 选择频道后发送原 `/logout`。服务端倒计时,结束后关闭连接;`OnRemoteDisconnect` 调用 `SetLoginPhase`。
3. `introLogin.LoginWindow.Open` 之后,脚本把连接信息设为目标频道(认证服务器取 `REGION_AUTH_SERVER_DICT`),写入 `channel.inf` 和 `net.SetServerInfo`,打开 `stream.isAutoSelect` 并恢复原来的角色槽位,然后调用原 `LoginWindow.Connect`,账号密码取自 `MainStream.id/pwd`。
4. `introSelect.SelectCharacterWindow.Open` 中原有的 `isAutoSelect` 分支选择同一槽位并 `StartGame`。
5. 进入游戏后关闭 `isAutoSelect`,聊天框提示“已换到 CHx”。
换线进行中所有频道按钮都不能点:再次发送 `/logout` 会取消服务端倒计时。
## 失败处理
- 20 秒内服务端没有断开连接(例如刚战斗过,`IsHack` 拒绝退出),取消换线并提示。
- 登录失败或连接失败时,取消换线、关闭 `isAutoSelect`,并显示原登录失败提示,之后可以手动登录。
- 没有保存的账号密码时(例如自动登录信息不完整)不发送 `/logout`。
## 客户端
- 模块 `mt_channel`(`src/platform/ScriptLib/ChannelScript.inc`),在 `PythonBoot.cpp` 中安装:
- 入口是小地图旁“显示”下方的“换线”按钮。
- 挂接 `game.GameWindow.Open/Close/OnUpdate` 和 `introLogin.LoginWindow.Open/OnUpdate/OnLoginFailure/OnConnectFailure`。
## 证据
- `tests/wiki/test_channel.py`(CTest:`port.channel`)共 6 项通过,覆盖:
- 当前频道定位(`serverInfo` 匹配、`channel.inf` 回退);
- 完整换线:只发一次 `/logout`,登录窗口连接到目标频道和认证服务器,`isAutoSelect`、槽位、`channel.inf`、`SetServerInfo`,进入游戏后复位;
- 退出超时、登录失败、同频道和无账号时拒绝;
- 服务端 `do_cmd` 的 10 秒倒计时小于超时,且重复 `/logout` 会取消。
- 2026-10-15 联机测试(203 正式频道,macOS 原生客户端,账号 admin,角色 `[SA]Admin`):
- CH1(13000)→ CH2(13010)→ CH1,每次约 20 秒(倒计时 3 秒、登录约 2 秒、读图约 6 秒)。
- 换线后角色在同一位置(64600, 79800),连接端口分别为 13010 和 13000,选人界面由原 `isAutoSelect` 自动进入。
- 截图确认窗口布局、当前频道标记和换线中状态正常。
## 限制和未完成
- 换线经过登录界面,比服务端传送慢,期间会看到登录和读图画面。
- 只支持 `serverInfo` 里有的频道;测试核心 channel5(13040)不在列表中,从它出发时当前频道显示“未知”。
- 副本等地图没有做客户端限制:退出后重新登录由服务端按原规则决定角色位置。
- macOS 桌面客户端没有中文字体,窗口文字显示为 `?`。
- Android 真机测试未做。