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>
55 lines
4.1 KiB
Markdown
55 lines
4.1 KiB
Markdown
# 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 真机测试未做。
|