Bukkit -> 伪造网络消息

问题描述 投票:0回答:1

我通过 Bukkit 插件发送数据包。包裹发送代码:

        try {
            String full_msg = "Text(" + message + ")";
            byte[] data = full_msg.getBytes(StandardCharsets.UTF_8);

            MinecraftKey channel = new MinecraftKey("chilove", "main");

            PacketContainer packet = new PacketContainer(PacketType.Play.Server.CUSTOM_PAYLOAD);
            packet.getMinecraftKeys().write(0, channel);

            ByteBuf byteBuf = Unpooled.wrappedBuffer(data);
            Object serializer = MinecraftReflection.getPacketDataSerializer(byteBuf);

            packet.getModifier().withType(ByteBuf.class).write(0, serializer);

            ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
            return true;
        } catch (Exception exception) {
            Bukkit.getLogger().info(ConsoleColor.ANSI_RED + "Error on TextPacket: " + ConsoleColor.ANSI_CYAN + " (" + exception.getMessage() + ")" + ConsoleColor.ANSI_RESET);
            exception.printStackTrace();
        }
        return false;
    }

数据包本身是无条件发送的...但是 mod 上的处理程序根本不起作用。尝试创建处理程序的代码是:

private static final String PROTOCOL_VERSION = "1";
    public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(
            new ResourceLocation("chilove", "main"),
            () -> PROTOCOL_VERSION,
            PROTOCOL_VERSION::equals,
            PROTOCOL_VERSION::equals
    );

    public static void register() {
//        INSTANCE.registerMessage(0, TextPacket.class, TextPacket::encode, TextPacket::decode, TextPacket::handle);

        int id = 0;
        INSTANCE.messageBuilder(TextPacket.class, id++, NetworkDirection.PLAY_TO_SERVER)
                .decoder(TextPacket::decode)
                .consumerMainThread(TextPacket::handle)
                .add();
        INSTANCE.registerMessage(id++, TextPacket.class, TextPacket::encode, TextPacket::decode, TextPacket::handle);
        INSTANCE.messageBuilder(TextPacket.class, id++, NetworkDirection.PLAY_TO_CLIENT)
                .decoder(TextPacket::decode)
                .consumerMainThread(TextPacket::handle)
                .add();
    }

TextPacket.class:

public class TextPacket {
    private String text;

    public TextPacket() { }

    public TextPacket(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }

    public static TextPacket decode(FriendlyByteBuf buffer) {
        byte[] bytes = buffer.readByteArray();
        String text = new String(bytes, StandardCharsets.UTF_8);
        ChiloveMod.LOGGER.info("Decoded text: {}", text);
        return new TextPacket(text);
    }

    public void encode(FriendlyByteBuf buffer) {
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        buffer.writeByteArray(bytes);
    }

    public void handle(Supplier<NetworkEvent.Context> ctx) {
        ctx.get().enqueueWork(() -> {
            ChiloveMod.LOGGER.info("Received message: {}", text);
        });
        ctx.get().setPacketHandled(true);
    }
}

我尝试了很多选项,并在互联网上搜索了有关 SimpleImpl 的所有信息。通常,当发送数据包时,我会在控制台中收到 2 个错误:

  • [15:15:32] [Netty 客户端 IO #1/错误] [ne.mi.ne.si.IndexedMessageCodec/SIMPLENET]:在通道 chilove:main 上收到无效的鉴别器字节 84
  • [15:15:32] [渲染线程/警告] [minecraft/ClientPacketListener]:未知的自定义数据包标识符:chilove:main
我不知道该怎么办了,我真的已经翻遍了我能翻遍的一切。我正在寻求帮助... 我的世界版本:1.19.3

尝试通过 ClientboundCustomPayloadEvent 等事件。

java networking minecraft bukkit forge
1个回答
0
投票
要简单地将 CustomPayload 数据包从 bukkit 发送到客户端,您可以使用

sendPluginMessage(plugin, channel, data)

 方法,如下所示:

Player p = ...; String full_msg = "Text(" + message + ")"; byte[] data = full_msg.getBytes(StandardCharsets.UTF_8); p.sendPluginMessage(MyPlugin.getInstance(), "chilove:main", data);
论据是:

    您用来发送消息的插件
  1. 频道名称,格式如下:
  2. project:name
    。如果您使用 
    new MinecraftKey("a", "b")
     创建密钥,那么通道将为 
    a:b
    
    
  3. 要发送的数据
© www.soinside.com 2019 - 2024. All rights reserved.