
ProxLib
使附近的玩家能够自主相互通信。本质上是一个通过mc服务器发送的CustomPayloadC2CPacket,无需任何集成。
查看大图ProxLib
ProxLib 是一个库,用于在 Minecraft 中实现玩家之间基于距离的通信。它允许附近的玩家通过服务器直接相互交换数据,而服务器无需安装任何模组或插件来中继这些数据。
概述
ProxLib 为 ProxChat 提供支持,也可被其他模组用于实现基于距离的通信功能。它提供了一个简单的 API,用于在大约 26 格范围内的玩家之间发送和接收数据包。
该库的工作原理是巧妙地将数据编码到 Minecraft 现有的数据包系统中,通过方块破坏操作数据包(仅中止操作)实现,这些数据包会被中继给附近所有玩家,且无需服务器验证(没错,即使在空气中也能工作!)。
工作原理
- 通信方式:使用
PlayerActionC2SPacket配合ABORT_DESTROY_BLOCK操作 - 数据编码:数据被编码到玩家周围的相对方块位置中
- 范围:大约 26 格(技术上受 Minecraft 32 格操作数据包中继限制)
- 数据容量:每个 Minecraft 数据包 9 比特
- 发送的数据前会附加 2 个 Minecraft 数据包作为魔数(用于识别为 Prox 数据包),2 字节的 Vendor 和 Packet Id,以及 3 字节的数据包长度。
- 因此,如果你发送一个包含 4 字节数据的数据包,这将会变成
2 + (2 + 2 + 3 + 4) * (8 / 9) » 11.77 » 12个 Minecraft 数据包
- 因此,如果你发送一个包含 4 字节数据的数据包,这将会变成
- 发送的数据前会附加 2 个 Minecraft 数据包作为魔数(用于识别为 Prox 数据包),2 字节的 Vendor 和 Packet Id,以及 3 字节的数据包长度。
- 可靠性:几乎在所有服务器上都能工作,包括那些装有反作弊系统的服务器
- 请注意,反作弊系统可能会将其视为数据包刷屏或某种奇怪的 nuker 尝试。这可能导致玩家被标记为作弊。
- 我的测试主要是在 2b2t 上进行的。反作弊系统没有阻止任何数据包,没有将我踢出,但最近的一次更新导致发送数据并移动时会出现回弹(数据仍然正常发送)。
- 当你距离垂直建筑高度上限和下限小于约 6 格时会停止工作(可能在世界边界附近也会)
- 即使发送玩家处于创造模式也能工作!
- 请注意,反作弊系统可能会将其视为数据包刷屏或某种奇怪的 nuker 尝试。这可能导致玩家被标记为作弊。
免责声明: 由于此模组会发送大量上述的 ABORT_DESTROY_BLOCK 数据包,反作弊系统可能会将玩家标记为数据包刷屏甚至 nuking(尽管任何 nuker 都不会发送中止操作)。
因此,请确保在玩家启用相应的发送功能之前,让他们知晓可能会发生这种情况。
安装
对于模组用户
ProxLib 是一个库模组,应与其依赖的模组一起安装。
模组可能会自带此库,因此除非你在游戏内模组菜单的 Libraries 中查看,否则你可能永远不会意识到它被包含了。
对于模组开发者
在你的 build.gradle 中将 ProxLib 添加为依赖项:
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
dependencies {
// 例如 MC 版本 1.21.4(请确保检查最新的版本)。
// 如果你不希望将此模组直接打包到你的模组中(目前 <30 KiB),请移除 "include"。
include modApi("maven.modrinth:proxlib:0.2.4+1.21")
}
在你的 fabric.mod.json 中添加:
"depends": {
"proxlib": ">=0.2.0"
}
构建
如果你希望构建此模组,你应该注意:
- 此项目使用 Stonecutter 来同时生成多个版本
- 你不应运行
build任务,而应运行chiseledBuild(在project分类中) - 查看他们的文档以获取更多信息
版本管理
总的来说,我尝试将版本视为 SemVer(主版本号.次版本号.修订号)。
这个库仍处于 1.0.0 之前。所以稳定性可能并不完美。然而,这个库可能最终永远不会达到 1.0.0,而当前版本仍然相当稳定。
特别是对于 ProxLib 类,我会尽力不破坏现有公共方法的兼容性。如果确实破坏了,我会提升次版本号。然而,如果添加了大量新功能,我也可能会提升次版本号。所以这并不一定意味着破坏性变更。
关于更新日志,请查看 GitHub 上的 releases 或 Modrinth 上的 changelog。
协议兼容性
我在 2024 年 1 月 ProxChat 首次发布时就确定了协议,此后未做修改。
我的目标是永远不需要破坏兼容性。我也尝试对我的数据包做到同样的事情。
到目前为止唯一的变更:
- ID(u16)已被拆分为 10 位的 Vendor ID 和 6 位的 Packet ID。这不是破坏性变更,但改变了 ID 的解释方式。
开发者用法
数据包 ID
数据包由 2 字节的 id 标识,该 id 被拆分为:
- 10 位:Vendor ID(0 到 1023)
- 6 位:Packet ID(0 到 63)
因此,如果你想创建自己的数据包,你应该:
- 选择你自己的 Vendor ID。最好使用随机数生成器生成一个供你的模组使用的 ID。
- 然后开始为任何数据包编号
示例:
final int VENDOR_ID = 932; // 使用随机数生成器生成
final ProxPacketIdentifier AWESOME_PACKET_ID = ProxPacketIdentifier.of(VENDOR_ID, 0);
final ProxPacketIdentifier ANOTHER_PACKET_ID = ProxPacketIdentifier.of(VENDOR_ID, 1);
发送和接收数据包
你可能需要的所有方法都可以从 ProxLib 类轻松调用。
发送示例
public void sendAwesomePacket(String message) throws IOException {
// 为你的数据包创建数据(byte[])
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(bytesOut);
dataOut.writeByte(1); // 类型
dataOut.writeUTF(message);
// 发送数据包
int packets = ProxLib.sendPacket(MinecraftClient.getInstance(), AWESOME_PACKET_ID, bytesOut.toByteArray());
LOGGER.info("Sent my awesome packet using {} packets!", packets);
}
接收示例
public class MyAwesomeMod implements ClientModInitializer {
@Override
public void onInitializeClient() {
ProxLib.addHandlerFor(AWESOME_PACKET_ID, (sender, identifier, data) -> {
try {
DataInputStream dataIn = new DataInputStream(new ByteArrayInputStream(data));
int type = dataIn.readUnsignedByte(1);
if(type == 1) {
String message = dataIn.readUTF();
// 对 message 做一些处理...
}else {
LOGGER.warn("Received unsupported type in my awesome packet: {}", type);
}
} catch (IOException ex) {
LOGGER.error("Failed to proccess my awesome packet!", ex);
}
});
ProxLib.addHandlerFor(ANOTHER_PACKET_ID, (sender, identifier, data) -> {
// ...
});
}
}
已知的数据包 ID:
| 模组 | Vendor ID | Packet ID | 名称 | 描述 | 链接 |
|---|---|---|---|---|---|
| ProxChat | 0 | 1 | Chat | 聊天中的简单聊天消息(使用模组输入 % <msg>)。 |
PC-Chat |
| ProxChat | 0 | 2 | PatPat-PatEntity | 抚摸某人(旧版) | PC-Pat |
| ProxChat | 0 | 3 | EmoteCraft | 播放 / 重复 / 停止自己的表情 | PC-Emote |
| ProxChat | 0 | 4 | TextDisplay | 向他人显示一个或多个可自定义的文本显示(使用模组输入 %% <msg>)。 |
PC-TextDisplay |
| PatPat | 2 | 0 | Pat | 抚摸某人 | PP-Pat |
注意:ProxChat 的 Vendor ID 为 0,因为当时 ID 尚未拆分为 Vendor/Packet ID(而且此库曾是 ProxChat 的一部分)。因此使用了从 1 开始的编号,这实际上就是 Vendor ID 0,并且保留它是为了向后兼容旧版本的 ProxChat。
与其他语言的集成
ItzN00bPvP 开发了一个与此兼容的基础 Rust 库(crates.io:proxchat,仓库:proxchat-rs)。因此,如果你想让你例如 azalea 机器人发送 ProxChat 消息,这会很方便。
致谢
由 EnderKill98 开发,基础是在与 ItzN00bPvP 一起检查他自己的 N00bBots 日志时偶然发现的。没有他,这一切都不会存在!
正在加载版本记录…


正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。