原始编织者

原始编织者

一个用于创建在内部netty服务器上运行的自定义协议的网络库。

Maintenance PRs Welcome

ko-fi

ProtoWeaver

一个 Minecraft 网络库,用于创建在内部 netty 服务器上运行的自定义协议。

这是什么意思?

厌倦了通过劫持客户端连接来与代理之间收发数据?我可太厌倦了。ProtoWeaver 允许你创建一个自定义协议,它运行在 Minecraft 服务器使用的同一端口上。 这意味着像 velocity 这样的代理能够与服务器通信,无论玩家是否在线,而无需在不同端口上运行额外的套接字服务器。Protoweaver 也不仅仅 局限于代理。使用 client 模块,任何第三方 Java 应用程序都可以直接与 ProtoWeaver 通信!

Protoweaver 快速、安全且易于使用。所有协议都运行在 Minecraft 使用的同一个 netty 实例下,使用 ssl 加密,并封装在一个非常直观的 api 中。让我们来看看:

特性

  • 无需用户配置
  • SSL 加密
  • 协议认证
  • 数据包作为 POJO
  • 压缩(Gzip、Snappy、LZ)
  • 所有主流模组加载器(neoforge 即将到来 tm)
  • 用于注册原始协议(http、ssh 等)的 API
  • 自定义序列化
  • 自定义 SSL 提供者/证书
  • 多协议连接
  • 告诉我你想看到什么!

项目设置

在你的 build.gradle 中包含

*** 注意:** 不要对 protoweaver 进行 shade!它不会正常工作。ProtoWeaver 是与你的模组/插件一起安装的一个模组/插件!**

repositories {
    maven { url "https://maven.mrnavastar.me/releases" }
}

dependencies {
    // 'common' 可以替换为以下任意一项:`client`、`fabric`、`forge`、`paper` 或 `proxy`。
    implementation "me.mrnavastar.protoweaver:common:1.3.11"
}

创建协议

协议非常可定制,具有大量内置功能。以下是一个示例协议:

Protocol protocol = Protocol.create("my_mod_id", "cool_protocol")
    .setCompression(CompressionType.GZIP)
    .setServerHandler(MyCustomServerHandler.class)
    .setClientHandler(MyCustomClientHandler.class)
    .setMaxConnections(15)
    .addPacket(String.class)
    .build();

// Load the protocol before it can be used
ProtoWeaver.load(protocol);

发送数据包

发送数据包非常简单。任何已添加到协议中的 POJO(参见创建协议)都是可以发送的有效数据包。请注意,所有 POJO 序列化都通过 kyro 处理,这是一个快速且高效的序列化库。

// If you have a reference to a 'ProtoConnection', you can simply:
connection.send(myObject);
// If you have a reference to a 'ProtoClient', you can also:
client.send(myObject);

处理数据包

所有协议都需要处理器来实现功能。客户端和服务器可以使用相同的处理器,也可以各自使用不同的处理器。

public class MyCustomServerHandler implements ProtoConnectionHandler {
    // Note that all functions are optional to implement

    @Override
    public void void onReady(ProtoConnection connection) {
        System.out.println("awesome! looks like a new client has connected from: " + connection.getRemoteAddress());
    }

    @Override
    public void onDisconnect(ProtoConnection connection) {
        System.out.println("goodbye: " + connection.getRemoteAddress());
    }

    @Override
    public void handlePacket(ProtoConnection connection, Object packet) {
        System.out.println("wow! got: " + packet.toString() + " from: " + connection.getRemoteAddress());
    }
}
public class MyCustomClientHandler implements ProtoConnectionHandler {
    // Note that all functions are optional to implement

    @Override
    public void void onReady(ProtoConnection connection) {
        System.out.println("awesome! connected to: " + connection.getRemoteAddress());
    }

    @Override
    public void onDisconnect(ProtoConnection connection) {
        System.out.println("goodbye: " + connection.getRemoteAddress());
    }

    @Override
    public void handlePacket(ProtoConnection connection, Object packet) {
        System.out.println("saying hi!");
        connection.send("Hey server!");
    }
}

自定义序列化

有时在协议中发送 Minecraft 对象或其他预制 POJO 会很有用。为此,你可以注册一个自定义序列化器。

例如,以下是一个用于 NBT 标签的序列化器:

public class NbtSerializer extends ProtoSerializer<CompoundTag> {

    public NbtSerializer(Class<CompoundTag> type) {
        super(type);
    }

    @Override
    public void write(ByteArrayOutputStream buffer, CompoundTag value) {
        try {
            NbtIo.writeCompressed(value, buffer);
        } catch (IOException e) {
            Platform.throwException(e);
        }
    }

    @Override
    public CompoundTag read(ByteArrayInputStream buffer) {
        try {
            return NbtIo.readCompressed(buffer, NbtAccounter.unlimitedHeap());
        } catch (IOException e) {
            Platform.throwException(e);
            throw new RuntimeException(e);
        }
    }
}

然后要注册该序列化器,只需执行:

Protocol protocol = Protocol.create("my_mod_id", "cool_protocol")
    .setCompression(CompressionType.GZIP)
    .setServerHandler(MyCustomServerHandler.class)
    .setClientHandler(MyCustomClientHandler.class)
    .setMaxConnections(15)
    .addPacket(CompoundTag.class, NbtSerializer.class)
    .build();

更多文档即将推出!也许会有个真正的网站??