diff --git a/README.md b/README.md index bdfa1c7..ee870b9 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,75 @@ modlink.onReceive { packet -> ### Forge -和 Fabric 一样,需要手动实现发送和接受函数。 +对于1.12.2-1.13+ 请参考[海螺的博客](https://izzel.io/2017/08/28/minecraft-plugin-message/) + +对于1.16.5-1.20.1,一种方法是使用Mixin手动接管数据包处理 + +下面以1.20.1 Forge 47.4.3 为例 +#### Mixin +```java +@Mixin({ClientPacketListener.class}) +public class ClientPacketListenerMixin { + @Inject( + method = {"handleCustomPayload"}, + at = {@At("HEAD")}, + cancellable = true + ) + public void onCustomPayload(ClientboundCustomPayloadPacket packet, CallbackInfo callbackInfo) { + if (packet.getIdentifier().equals(ResourceLocation.tryBuild("modlink", "default"))) { + CustomPacketEvent event = new CustomPacketEvent(packet.getData()); + MinecraftForge.EVENT_BUS.post(event); + callbackInfo.cancel(); + } + } +} +``` +#### Forge端 +创建事件类 +```kotlin +class CustomPacketEvent(val buf: FriendlyByteBuf): Event() +``` +之后实现收发信逻辑 +```kotlin + // 此事件需要在Forge的EVENT_BUS上注册 + fun onCustomPacketReceive(event: CustomPacketEvent) { + Minecraft.getInstance().execute { + val buf = event.buf + val readableBytes = buf.readableBytes() + if (readableBytes <= 0) { + return@execute + } + val data = ByteArray(readableBytes) + buf.readBytes(data) + modlink.handleMessageReceived(data) + } + } + + fun sendToServer(packet: ModLinkPacket) { + modlink.sendPacket(packet) { bytes -> + Minecraft.getInstance().connection?.send( + ServerboundCustomPayloadPacket( + ResourceLocation.tryBuild("modlink", "default"), + FriendlyByteBuf(Unpooled.wrappedBuffer(bytes)) + ) + ) + } + } +``` +### 关于其他版本 + +已知在1.20.4时,使用上面的方法Mixin的类要换为`ClientCommonPacketListenerImpl` + +同时由于Forge在此版本又出现了[#5730](https://github.com/MinecraftForge/MinecraftForge/issues/5730)中的问题,需要在Bukkit端手动注册通道 +```kotlin + // 使用Taboolib + @SubscribeEvent + fun onPlayerJoin(event: PlayerJoinEvent) { + (event.player as CraftPlayer).addChannel("modlink:default") + } +``` +之后便可正常通过`CustomPacketEvent`收到数据包的数据 ## 注意事项 在 Channel 没有注册前是不能发包给玩家的,通常表现在 Join 事件前后发包无效。下面是一个简单的解决办法: