1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите общение пакетами клиент->сервер->клиент

Тема в разделе "Разработка плагинов для новичков", создана пользователем sweettie, 22 авг 2025.

  1. Автор темы
    sweettie

    sweettie Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    _Sweettie_
    Вопрос к гуру, пару дней смотрю в монитор и ничего не понимаю, по поводу общения пакетами клиент->сервер->клиент.
    Клиент - мод fabric
    Сервер - paper
    Версия 1.21.1

    Извиняюсь что приходится показывать двумя сообщениями, дс ограничивает

    В моде, как указано в официальной документации fabric https://docs.fabricmc.net/develop/networking#receiving-a-packet-on-the-client, создан класс от CustomPayload, зарегестрирован как S2C, C2S
    Код:
    Код:
    public static void register() {
           PayloadTypeRegistry.playC2S().register(TestDataPayload.ID,TestDataPayload.CODEC );
           PayloadTypeRegistry.playS2C().register(TestDataPayload.ID, TestDataPayload.CODEC );
           ClientPlayNetworking.registerGlobalReceiver(TestDataPayload.ID, (payload, context) -> {
               System.out.println("Handle server answer: "+payload.data());
           });
           ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
               MinecraftClient mc = MinecraftClient.getInstance();
               if (mc.player == null) return;
    
               ClientPlayNetworking.send(new TestDataPayload("REG"));
               System.out.println("Send null token to REG");
           });
       }
    TestDataPayload.java
    Код:

    Код:
    public record TestDataPayload(String data) implements CustomPayload {
    
       public static final Identifier PAYLOAD_ID = Identifier.of("modid", "test");
       public static final Id<TestDataPayload> ID = new Id<>(PAYLOAD_ID);
    
       public static final PacketCodec<PacketByteBuf, TestDataPayload> CODEC =
               CustomPayload.codecOf(TestDataPayload::write, TestDataPayload::read);
    
       private void write(PacketByteBuf buf) {
           buf.writeString(data);
       }
    
       private static TestDataPayload read(PacketByteBuf buf) {
    
           String data = buf.readString();
           System.out.println("READ PACKET "+data);
           return new TestDataPayload(data);
       }
    
       @Override
       public Id<? extends CustomPayload> getId() {
           return ID;
       }
    }
    На сервере же в плагине при инициализации регистрирую этот канал на получение и отправку
    Код:
    Код:
    public static final String CHANNEL_AUTH = "modid:test";
    
       ...
    
       @Override
       public void onEnable() {
           LOGGER = getLogger();
           Bukkit.getMessenger().registerIncomingPluginChannel(this, CHANNEL_AUTH, this);
           Bukkit.getMessenger().registerOutgoingPluginChannel(this, CHANNEL_AUTH);
       }
    
       @Override
       public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte @NotNull [] message) {
           System.out.println("Input on channel " + channel + " from player " + player.getName() + " with data " + message.length + " " + new String(message, StandardCharsets.UTF_8));
           if (channel.equals(CHANNEL_AUTH)) {
               sendResponse(player, "some data");
           }
       }
    
       private void sendResponse(Player player, String data) {
           ByteArrayDataOutput out = ByteStreams.newDataOutput();
           out.writeUTF(data);
           player.sendPluginMessage(this,CHANNEL_AUTH,out.toByteArray());
       }
    Сервер видит пакет игрока, который отправляется при заходе на сервер, отправляет пакет игроку, при этом на клиенте ничего не происходит и ничего не логируется (пакет от сервер не дошёл до клиента).
    Если кто-то знает почему и как это можно исправить - буду очень признателен
     
  2. Djstim

    Djstim Активный участник Пользователь

    Баллы:
    78
    Клиент

    public class TestNetworking {
    public static final Identifier CHANNEL = new Identifier("modid", "test");

    public static void register() {
    // Получение ответа от сервера
    ClientPlayNetworking.registerGlobalReceiver(CHANNEL, (client, handler, buf, responseSender) -> {
    String msg = buf.readString();
    System.out.println("CLIENT: got from server -> " + msg);
    });

    // Отправка на сервер при входе
    ClientPlayConnectionEvents.JOIN.register((handler, sender, client1) -> {
    PacketByteBuf buf = PacketByteBufs.create();
    buf.writeString("REG");
    ClientPlayNetworking.send(CHANNEL, buf);
    System.out.println("CLIENT: sent REG");
    });
    }
    }


    Сервер плагин
    public final class TestPlugin extends JavaPlugin implements PluginMessageListener {

    public static final String CHANNEL = "modid:test";

    @Override
    public void onEnable() {
    getServer().getMessenger().registerIncomingPluginChannel(this, CHANNEL, this);
    getServer().getMessenger().registerOutgoingPluginChannel(this, CHANNEL);
    getLogger().info("TestPlugin enabled, channel registered: " + CHANNEL);
    }

    @Override
    public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] message) {
    if (!channel.equals(CHANNEL)) return;

    DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
    try {
    String received = in.readUTF();
    getLogger().info("SERVER: got from " + player.getName() + " -> " + received);

    // Ответ клиенту
    sendResponse(player, "some data");
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    private void sendResponse(Player player, String msg) {
    ByteArrayDataOutput out = ByteStreams.newDataOutput();
    out.writeUTF(msg);
    player.sendPluginMessage(this, CHANNEL, out.toByteArray());
    getLogger().info("SERVER: sent to " + player.getName() + " -> " + msg);
    }
    }


    Логи

    Клиент

    CLIENT: sent REG
    CLIENT: got from server -> some data

    Сервер

    SERVER: got from Alexey -> REG
    SERVER: sent to Alexey -> some data
     
  3. Автор темы
    sweettie

    sweettie Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    _Sweettie_
    это для старых версий Fabric, данного конструктора больше не существует для 1.21


    как и данной лямбы (интерфейса)
    https://docs.fabricmc.net/develop/networking#receiving-a-packet-on-the-client
     

Поделиться этой страницей