Files
redapricot/IDEA.md
T
2026-07-15 14:28:58 +08:00

41 lines
3.4 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.
redapricot (红杏) 针对 Minecraft 协议实现 central-hub 模式的 P2P 连接工具。
角色有三:
1. 服务器, 即红杏服务端,负责处理各种用户请求接入
2. 客户端, 负责跟服务器注册信息并且接受经过服务器转发的玩家连接到其他目的地上。
3. 玩家,使用 Minecraft 协议连接服务器的用户及软件,是服务器识别且匹配转发的首要对象。
# 协议工作流程
本协议是在 @CURRENT_MC_PROTO.txt(注意此文件巨大,采自 https://minecraft.wiki/w/Java_Edition_protocol/Packets 语境下对 Minecraft 协议的扩展。本协议有最基本的安全检查,但比起安全性更关注连接性问题本身,因此不安全的协议设计并不是待解决的问题。
- 客户端向服务器发送 Intent 为 17 的 Handshake 包进入红杏专属协议,且 Server Address 设置为 PSK 的 SHA3-224 哈希。在此封包后,所有的数据包均使用 PSK 进行加密,加密算法你可以自己选,也可以参考 MC Protocol Encryption 的流程
- 启用加密后,客户端发送魔数 0x01 、一串随机数、当前时间作为新的PSK。服务端检查时间后,使用该 PSK 作为新的密钥直到连接断开。
- 在服务器确定了客户端的身份后,此连接将作为控制会话。控制会话不直接传递游戏数据。
- 客户端可以在任意时刻向服务器发送注册请求。注册请求中包含一个大小写不敏感的 Server Address,记作 PATTERN。
- 玩家通过 Minecraft 连接服务器,服务器会匹配 Handshake 包中的 Intent 以及 Server Address. 对于 Intent != 17 且 Intent != 18 的 Handshake, 匹配 ServerAddress 有无命中的 PATTERN. 如果有,将此连接编号为 CID(CID 的生成必须是随机的),向客户端发送控制请求(PATTERN, 玩家IP, CID)。
- 收到控制请求的客户端需要匹配一个在线的 Worker Conn,然后使用 Worker Conn 跟服务端申请接管该连接(发送 CID)。Worker Conn 是实现多路复用的数据转发链路,具体见下文。
- 服务端将 Handshake 原样转发给 WorkerConn, Worker Conn 通过可选的 HAPROXY v2 协议将报文转发给目的地,并且开启双向转发。
- 当玩家断开连接时,服务器会给 Worker Conn 发送一条 disconnect 来关闭多路复用中对应的流。
# Worker Conn
Worker Conn 是实现了多路复用协议的 TCP 连接。建立过程如下:
- 按照上文所述的验证方法验证。只不过第二步魔数使用 0x02 而不是 0x01 来表示这是一个 worker conn
- Worker Conn 采用某种多路复用协议,该协议的最小操作单位是流。
多路复用协议的开销应该尽可能的少以在效率上达成最大收益。用户会通过配置文件设置 1 <= max_conn <= 8, stream 分配算法会总是在已有的 conn 簇里寻找活跃 stream 最少的 conn 进行分配。如果所有 conn 均饱和了,则在不超过 max_conn 的情况下创建一个新的 conn 并且在上分配。饱和指 stream 的数量 > 8。
worker conn 可以考虑使用类似 chacha20 的流密码算法以最小化 padding 带来的大小开销。
# Technical details
服务端必须使用 Java 编写,并且偏好于使用 Vert.x。客户端使用 Golang 编写。
注意:由于你现在在一个特殊的沙盒里,环境变量可能会出一些问题。如果有那样的问题,记住 Java 在 ~/.sdkman/candidates/current/ (JAVA_HOME).