目录
此文件含有人类无法区分的不可见的Unicode字符,但可以由计算机进行不同的处理。如果您是想特意这样的,可以安全地忽略该警告。使用Escape按钮显示他们。
简洁联机标记约定 (Pure Connect Labeling, 简称 PCL 约定 ) 是一个旨在以 最简单的代码实现 实现基础的互通联机功能的约定。
仅需遵照此约定,即可使用 EasyTier 与所有实现了 PCL 约定的软件互相联机!
建议订阅 更新通知帖,以在本文内容更新时得到通知!
生成邀请码
◇ 端口: 将需要开放的端口转为 16 进制,然后在左侧补零直至四位。
例如,端口号 2747 在处理后应为 0abb 。
△ 随机字符: 生成 10 个由任意数字与字母混合的随机字符。
例如,oi7lksidz1。
◎ 邀请码版本: 数字,当前固定为 02。今后可能会增加,建议订阅 更新通知帖 以得到通知!
例如,02。纯废话。
☆ 初始节点: 选择 EasyTier 节点列表 中的任意一个节点,将其 id 在左侧补零直至三位。
例如,北京-腾讯云 节点的 id 是 94,在处理后应为 05e。
特别地,如果你需要指定不在该列表中的节点(例如使用了 PCL 启动器的 “自定义节点” 设置),则为 000。
将上述四个部分按照 P◇◇◇◇-△△△△△-△△△△△-◎◎☆☆☆ 的格式组合在一起。
例如,P0abb-oi7lk-sidz1-0205e。
最后,将它转为大写,再将 O 替换为 0、将 I 替换为 1。大功告成!
因此,示例邀请码即为 P0ABB-017LK-S1DZ1-0205E。
// 伪代码示例
Const INVITE_CODE_VERSION = 2
邀请码 = String.Format("P{0}-{1}-{2}-{3}{4}",
进制转换(端口, 10, 16).PadLeft(4, '0'), // 替换 {0}
获取随机字符(5), // 替换 {1}
获取随机字符(5), // 替换 {2}
INVITE_CODE_VERSION.ToString().PadLeft(2, '0'), // 替换 {3}
是否设置了自定义的节点列表() ? "000" : 进制转换(选择的节点["id"], 10, 16).PadLeft(3, '0') // 替换 {4}
)
邀请码 = 邀请码.ToUpper().Replace('O', '0').Replace('I', '1')
[可扩展] 若有额外需求,你还可以在邀请码末尾附加任意自定义信息。
例如,P0ABB-017LK-S1DZ1-0205E-EXTRAINFO。
解析邀请码
Tip
以下内容仅适用于
02版本 PCL 约定的邀请码。更新通知帖 中有老版本兼容指南。
要判断邀请码是否属于 PCL 约定,验证第 1 位是否为 P,第 6、11、18 位是否为 - 即可。
将邀请码按照 P◇◇◇◇-△△△△△-▽▽▽▽▽-◎◎☆☆☆[自定义信息] 的格式阅读:
继续以上述的示例邀请码 P0ABB-017LK-S1DZ1-0205E-EXTRAINFO 为例。
◇ 端口: 将 ◇ 部分转换为十进制。
例如,将 0ABB 转为端口号 2747。
网络名: 取邀请码的前 11 个字符,也就是 P◇◇◇◇-△△△△△ 这一部分。
例如,网络名为 P0ABB-017LK。
▽ 网络密码: 对应 ▽ 的五个字符。
例如,网络密码为 S1DZ1。
☆ 初始节点: 将 ☆ 部分转换为十进制。需要从 EasyTier 节点列表 寻找 id 与其匹配的节点,获取其 address 字段。
例如,05E 对应节点列表中 id = 94 的节点,其 address 为 tcp://mc1.easytier.cn:55558。
特别地,如果为 000,则必须以某种方式手动指定与房主相同的节点(例如使用 PCL 启动器的 “自定义节点” 设置)。
至此,即可从邀请码解析到:端口号 2747,网络名 P0ABB-017LK,密码 S1DZ1,初始节点 tcp://mc1.easytier.cn:55558。
可选的,你还可以通过检测 ◎ 部分的邀请码版本判断是否需要更新。
// 伪代码示例
邀请码 = "P0ABB-017LK-S1DZ1-02094-EXTRAINFO"
端口 = 进制转换(邀请码.Substring(1, 4), 16, 10) // 2747
网络名 = 邀请码.Substring(0, 11) // P0ABB-017LK
网络密码 = 邀请码.Substring(12, 5) // S1DZ1
初始节点ID = 进制转换(邀请码.Substring(20, 3), 16, 10) // 94
if (初始节点ID == 0) {
初始节点 = 获取自定义的节点列表()
} else {
初始节点 = 获取节点列表JSON()["data"]["items"].First(节点 -> 节点["id"] == 初始节点ID)["address"] // tcp://mc1.easytier.cn:55558
}
[可扩展] 若有额外需求,你可以以你需要的方式读取第 24 位及以后的内容,基础的 PCL 约定会忽略它。
EasyTier 参数
在启动 EasyTier 时,PCL 约定要求指定以下参数:
-
--encryption-algorithm- 固定为
chacha20
- 固定为
-
-p(初始节点)- 从邀请码中获取的初始节点(你可以追加其他节点以改善体验,但不建议追加一大堆)
-
--network-name与--network-secret- 从邀请码中获取的网络名和网络密码,例如
--network-name=P0ABB-017LK --network-secret=S1DZ1
- 从邀请码中获取的网络名和网络密码,例如
-
-i(IP 地址)- 仅当是房主时,该参数必须为
-i 10.114.114.114(这会固定房主的 IP,也确保了房间中仅有一个房主)
- 仅当是房主时,该参数必须为
-
--hostname- 仅当是加入者时,该参数必须以
Client开头,例如--hostname=Client-LTCat [可扩展]房主的此参数,以及加入者在Client之后的内容不作限制,若有额外需求,你可以借此传递自定义信息
- 仅当是加入者时,该参数必须以
-
--tcp-whitelist和--udp-whitelist- 若是房主,建议设为房主指定的端口;若是加入者,建议设为 0(阻止所有)
- 这不是强制的要求,但可以增强安全性
// 伪代码示例
进程参数 = " --encryption-algorithm=chacha20"
进程参数 += " -p " + 初始节点
进程参数 += " --network-name=" + 网络名
进程参数 += " --network-secret=" + 网络密码
if (当前是房主) {
进程参数 += " -i 10.114.114.114"
进程参数 += " --tcp-whitelist=" + 端口 + " --udp-whitelist=" + 端口
} else {
进程参数 += " --hostname=Client" + 任意内容
进程参数 += " --tcp-whitelist=0 --udp-whitelist=0"
}
此外,你还需要根据 EasyTier 配置选项文档 设置其他参数,不过 PCL 约定对这些就没有硬性要求了。
后续
加入网络后,你可以选择使用 EasyTier CLI 查询信息,并以如下规则判断节点身份:
-
若
ipv4为10.114.114.114,则为服主 -
若
hostname以Client开头,则为加入者
你还需要自行实现端口映射,例如使用 --port-forward 参数将 房主指定的端口 映射到 localhost 的空闲端口上。
如果你想实现更复杂的功能,可以在邀请码末尾和 hostname 传递自定义信息,例如用于额外通信的端口号。不过……这些就在 PCL 约定的范围之外啦。
联机快乐!
F&Q
为何没有使用 HMCL 的 Scaffolding-MC 协议?
如果有其他疑问或建议,可以在 Discussions 中提出,并且 @LTCatt !