• 游客, 欢迎您来到九域资源社区,如果您是新人,请前往 论坛公告 板块查看新人引导教程 或者 点我打开
    如果您发现没有下载许可, 请先验证邮箱再进行下载;金锭可通过每日登陆或资源出售获取,目前没有其他渠道可获取。

Minecraft 1.16.5 中 Forge 与 Bukkit 的发包通信

Laotou

Lv.1 泥土
高级创作者
2019-04-07
24
56
0
钻石
1.00 钻石
金锭
27,147 金锭
服务端 Bukkit部分:

1. 注册通道


Java:
getServer().getMessenger().registerOutgoingPluginChannel(this, "myplugin:channel");
getServer().getMessenger().registerIncomingPluginChannel(this, "myplugin:channel", this);



1. registerOutgoingPluginChannel(Plugin plugin, String channel):

这个方法用于注册一个用于发送数据到客户端的插件消息通道。


  • 参数:
    • plugin:插件实例,通常为 this。
    • channel:要注册的通道名,必须符合 namespace:channel_name 的格式(例如:"myplugin:channel")。

2. registerIncomingPluginChannel(Plugin plugin, String channel, PluginMessageListener listener):

这个方法用于注册一个用于接收来自客户端的插件消息通道。


  • 参数:
    • plugin:插件实例,通常为 this。
    • channel:要注册的通道名,必须符合 namespace:channel_name 的格式(例如:"myplugin:channel")。
    • listener:PluginMessageListener 的实例,用于处理从客户端接收到的消息。通常,插件主类会实现这个接口,并传入 this。


注册为接收客户端消息的类需要实现 PluginMessageListener 类

Java:
public final class PluginMain extends JavaPlugin implements PluginMessageListener, Listener {

    @Override
    public void onEnable() {

        getServer().getMessenger().registerOutgoingPluginChannel(this, CHANNEL);
        getServer().getMessenger().registerIncomingPluginChannel(this, CHANNEL, this);

        Bukkit.getPluginManager().registerEvents(this,this);
        // Plugin startup logic

    }



}


接收客户端发送来的消息:


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

        // 处理收到的数据包
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(message);
        DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream);

        try {
            while (dataInputStream.available() > 0) {
                String receivedMessage = dataInputStream.readUTF();
                getLogger().info("收到来自 Forge Mod 的消息: " + receivedMessage);

                sendMessageToForgeClient(player,"你好,客户端 这里是服务端");

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                dataInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


向玩家客户端发送消息
Java:
 public void sendMessageToForgeClient(Player player, String message) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);

        try {
            dataOutputStream.writeUTF(message);
            player.sendPluginMessage(this, CHANNEL, byteArrayOutputStream.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                dataOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


我们已经写完了服务端的接收和发送,那我们开始客户端部分的代码

客户端部分:

Java:
package lt.uicore.screen.network;

import lt.uicore.MessageFromClient;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ChatType;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.simple.SimpleChannel;

public class BQNetwork {

    public SimpleChannel channel;
    private static final ResourceLocation CHANNEL = new ResourceLocation("myplugin:channel");


    public BQNetwork() {


        channel = NetworkRegistry.newSimpleChannel(CHANNEL, () -> "1.0", (s) -> true, (s) -> true);

        registerMessages();

    }

    public void sendPacketToServer(String str) {



        channel.sendToServer(new MessageFromClient(str));

    }

    public void registerMessages() {

        channel.registerMessage(0, MessageFromClient.class, MessageFromClient::encode, MessageFromClient::decode, (message, context) -> {
            // 在这里处理收到的消息
            System.out.println("收到来自 Bukkit 服务端的消息: " + message);

            // 注意,这里的 context 可能在一个不同的线程中运行,所以如果要与 Minecraft 对象进行交互,需要使用 context.enqueueWork(Runnable) 方法。
            context.get().enqueueWork(() -> {
                Minecraft.getInstance().gui.handleChat(ChatType.SYSTEM,new StringTextComponent(message.getMessage()), Minecraft.getInstance().getPlayerSocialManager().getDiscoveredUUID("LaotouY"));

                // 与 Minecraft 对象交互的代码
            });
        });
    }

}


客户端发送消息的类
















Java:
import net.minecraft.network.PacketBuffer;

public class MessageFromClient {
    private final String message;

    public MessageFromClient(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public static void encode(MessageFromClient msg, PacketBuffer buf) {
        buf.writeUtf(msg.message);
    }

    public static MessageFromClient decode(PacketBuffer buf) {
        return new MessageFromClient(buf.readUtf());
    }


}


1685525652605.png
 
最后编辑:
  • Like
反馈: Eason.箱
老头这是准备做1.16.5的宝可梦插件了么?