Posted November 13, 20222 yr Hello, I've got one problem, while I have worked on my new project. This is first time when I tried to use networking in Forge, and also wanted to connect mod with bukkit plugin over PluginMessages. I've spent a few days to make me understand how can I do this. Used SimpleChannel, and already can handle packets forge-to-forge, but this is useless for my project where server must be vanilla only(Paper/Spigot/Bukkit). I will be glad if someone will give me some code examples for actual 1.19+ Minecraft versions, where forge mod communicates with bukkit plugins using networking. This is my Forge code Main.class Spoiler package io.github.liponex.customtasksmod; import com.mojang.logging.LogUtils; import io.github.liponex.customtasksmod.events.IsInstalledPacketEvents; import io.github.liponex.customtasksmod.networking.PluginMessages; import net.minecraft.client.Minecraft; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.slf4j.Logger; @Mod(CustomTasks.MODID) public class CustomTasks { public static final String MODID = "customtasksmod"; private static final Logger LOGGER = LogUtils.getLogger(); public CustomTasks() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus forgeEventBus = MinecraftForge.EVENT_BUS; modEventBus.addListener(this::commonSetup); forgeEventBus.addListener(IsInstalledPacketEvents::onPacketReceive); MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new IsInstalledPacketEvents()); } private void commonSetup(final FMLCommonSetupEvent event) { LOGGER.info("CustomTasksMod Setup"); PluginMessages.register(); } // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent @Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public static class ClientModEvents { @SubscribeEvent public static void onClientSetup(FMLClientSetupEvent event) { LOGGER.info("CLIENT SETUP"); LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); } } } Class that must handle packet IsInstalled Spoiler package io.github.liponex.customtasksmod.events; import io.github.liponex.customtasksmod.CustomTasks; import io.github.liponex.customtasksmod.networking.PluginMessages; import io.github.liponex.customtasksmod.networking.packets.IsInstalledC2SPacket; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.NetworkEvent; @Mod.EventBusSubscriber(modid = CustomTasks.MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.FORGE) public class IsInstalledPacketEvents { @SubscribeEvent public static void onPacketReceive(NetworkEvent.ClientCustomPayloadEvent event) { NetworkEvent.ClientCustomPayloadEvent e = event; PluginMessages.send(IsInstalledC2SPacket.isInstalled); } } Class PluginMessages that must prepare all for networking Spoiler package io.github.liponex.customtasksmod.networking; import io.github.liponex.customtasksmod.CustomTasks; import io.github.liponex.customtasksmod.networking.packets.IsInstalledC2SPacket; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; public class PluginMessages { private static int packetId = 0; private static int id() { return packetId++; } private static final String PROTOCOL_VERSION = "1.0"; public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( new ResourceLocation("custom_tasks_mod", "messages"), () -> PROTOCOL_VERSION, (s) -> true, (s) -> true ); public static void register() { INSTANCE.messageBuilder(IsInstalledC2SPacket.class, id(), NetworkDirection.PLAY_TO_SERVER) .decoder(IsInstalledC2SPacket::new) .encoder(IsInstalledC2SPacket::toBytes) .consumerMainThread(IsInstalledC2SPacket::handle) .add(); } public static <MSG> void send(MSG message) { INSTANCE.sendToServer( INSTANCE.toVanillaPacket(message, NetworkDirection.PLAY_TO_SERVER)); } } Class of IsInstalled packet Spoiler package io.github.liponex.customtasksmod.networking.packets; import com.mojang.logging.LogUtils; import io.github.liponex.customtasksmod.CustomTasks; import io.netty.buffer.ByteBufUtil; import net.minecraft.network.FriendlyByteBuf; import net.minecraftforge.network.NetworkEvent; import org.slf4j.Logger; import java.util.function.Supplier; public class IsInstalledC2SPacket { private static final Logger LOGGER = LogUtils.getLogger(); public static final boolean isInstalled = true; public String text; public IsInstalledC2SPacket() { } public IsInstalledC2SPacket(FriendlyByteBuf buf) { text = buf.toString(); } public void fromBytes(FriendlyByteBuf buf) { text = buf.toString(); } public void toBytes(FriendlyByteBuf buf) { ByteBufUtil.writeUtf8(buf, text); } public boolean handle(Supplier<NetworkEvent.Context> supplier) { NetworkEvent.Context context = supplier.get(); context.enqueueWork(() -> { LOGGER.info(context.toString()); }); context.setPacketHandled(true); return true; } } My Bukkit code, that I use for sending (ProtocolLib used) Spoiler @EventHandler public void onPlayerJoin(@NotNull PlayerJoinEvent event) { getServer().getConsoleSender().sendMessage("Player join detected!"); PacketContainer packet = protocolManager. createPacket(PacketType.Play.Server.CUSTOM_PAYLOAD); packet.getModifier().writeDefaults(); byte[] bytesTask = "IsInstalled".getBytes(StandardCharsets.UTF_8); MinecraftKey channel = new MinecraftKey("custom_tasks_mod", "messages"); packet.getMinecraftKeys().write(0, channel); Object actualData = MinecraftReflection.getPacketDataSerializer(Unpooled.wrappedBuffer(bytesTask)); packet.getModifier().withType(actualData.getClass()).write(0, actualData); try { protocolManager.sendServerPacket(event.getPlayer(), packet, false); } catch (InvocationTargetException e) { getServer().getConsoleSender().sendMessage(e.toString()); } } Log from client console Spoiler [Netty Client IO #0/DEBUG] [ne.mi.ne.NetworkRegistry/NETREGISTRY]: Channel 'custom_tasks_mod:messages' : Vanilla acceptance test: ACCEPTED [Netty Client IO #0/DEBUG] [ne.mi.ne.NetworkRegistry/NETREGISTRY]: Accepting channel list from vanilla [Render thread/INFO] [minecraft/ConnectScreen]: Connecting to 127.0.0.1, 25565 [Netty Client IO #1/DEBUG] [ne.mi.ne.HandshakeHandler/FMLHANDSHAKE]: Starting new vanilla impl connection. [Netty Client IO #1/INFO] [ne.mi.ne.NetworkHooks/]: Connected to a vanilla server. Catching up missing behaviour. [Netty Client IO #1/DEBUG] [ne.mi.co.ForgeConfig/FORGEMOD]: Loaded forge config file forge-server.toml [Netty Client IO #1/ERROR] [ne.mi.ne.si.IndexedMessageCodec/SIMPLENET]: Received invalid discriminator byte 208 on channel custom_tasks_mod:messages [Render thread/DEBUG] [ne.mi.ne.fi.NetworkFilters/]: Injected net.minecraftforge.network.filters.VanillaConnectionNetworkFilter@40db6136 into net.minecraft.network.Connection@5ced0537 [Render thread/DEBUG] [io.ne.ut.in.ThreadLocalRandom/]: -Dio.netty.initialSeedUniquifier: 0x854db3e7da8e9393 [Render thread/WARN] [minecraft/ClientPacketListener]: Unknown custom packet identifier: custom_tasks_mod:messages
November 14, 20222 yr Author I've solved this it was easier then that ways I've used. Sources that were changed (if someone fold have the same problem): For PluginMessages you must use Spoiler private static final String PROTOCOL_VERSION = "1.0"; public static final EventNetworkChannel EVENT_NETWORK_CHANNEL = NetworkRegistry.newEventChannel( new ResourceLocation("your_channel", "your_subchannel"), () -> PROTOCOL_VERSION, (s) -> true, (s) -> true ); public static void register() { EVENT_NETWORK_CHANNEL.addListener(IsInstalledPacketEvents::onPacketReceive); } For IsInstalledPacketEvents Spoiler @Mod.EventBusSubscriber(modid = CustomTasks.MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.FORGE) public class IsInstalledPacketEvents { private static final Logger LOGGER = LogUtils.getLogger(); @SubscribeEvent public static void onPacketReceive(NetworkEvent.ServerCustomPayloadEvent event) { NetworkEvent.ServerCustomPayloadEvent e = event; LOGGER.info(event.getPayload().toString(StandardCharsets.UTF_8)); } } Then you can handle it as you want. Good luck for everyone!
March 8, 20232 yr On 11/14/2022 at 1:49 PM, liponex said: I've solved this it was easier then that ways I've used. Sources that were changed (if someone fold have the same problem): For PluginMessages you must use Hide contents private static final String PROTOCOL_VERSION = "1.0"; public static final EventNetworkChannel EVENT_NETWORK_CHANNEL = NetworkRegistry.newEventChannel( new ResourceLocation("your_channel", "your_subchannel"), () -> PROTOCOL_VERSION, (s) -> true, (s) -> true ); public static void register() { EVENT_NETWORK_CHANNEL.addListener(IsInstalledPacketEvents::onPacketReceive); } For IsInstalledPacketEvents Hide contents @Mod.EventBusSubscriber(modid = CustomTasks.MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.FORGE) public class IsInstalledPacketEvents { private static final Logger LOGGER = LogUtils.getLogger(); @SubscribeEvent public static void onPacketReceive(NetworkEvent.ServerCustomPayloadEvent event) { NetworkEvent.ServerCustomPayloadEvent e = event; LOGGER.info(event.getPayload().toString(StandardCharsets.UTF_8)); } } Then you can handle it as you want. Good luck for everyone! Very cool, how about forge client send custom packet to (Paper/Spigot/Bukkit) server?
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.