Sending a custom plugin message from BungeeCord

Mar 5, 2019
Sending a custom plugin message from BungeeCord
  • Since me (MrIvanPlays) found a way how to play sounds via the plugin messaging channel, i've decided to create this wiki page for the developers who want to do custom things that BungeeCord doesnt support directly, but with the plugin messaging channel. This kinda "tutorial" is divided by two parts: BungeeCord (sending) and Spigot (receiving) part.

    BungeeCord part
    Firstly, we need to register our custom channel into onEnable() in our main class. We do this with ProxyServer#registerChannel(String). The channel should be lowercase and should contain ":".

    Example:
    Code (Java):
    public class ExampleMain extends Plugin {

      @Override
      public void onEnable() {
        getProxy().registerChannel("my:channel");
        getLogger().info("Plugin enabled!");
      }

      @Override
      public void onDisable() {
        getLogger().info("Plugin disabled!");
      }
    }
    Now, we can send messages via this channel!

    Sending a custom message is simple. You can create a method into the class where you want the plugin message to be send. Remember, for the plugin messaging channel to work you need atleast 1 player online at the server. Always check if the online players globally are null.

    Example:
    Code (Java):
    private void sendCustomData(ProxiedPlayer player, String data1, int data2) {
        if (ProxyServer.getInstance().getPlayers() == null || ProxyServer.getInstance().getPlayers().isEmpty()) {
          return;
        }
        ByteArrayDataOutput out = ByteStreams.newDataOutput();
        out.writeUTF("MySubChannel"); // the channel could be whatever you want
        out.writeUTF(data1); // this data could be whatever you want
        out.writeInt(data2); // this data could be whatever you want

        player.getServer().sendData("my:channel", out.toByteArray()); // we send the data to the server
      }
    Since I see alot of people having trouble with receiving plugin messages from Spigot to BungeeCord, this is how you should do it.
    In Spigot, its a listener, in BungeeCord it's an event.
    Code (Java):
    public class PluginMessageReceiver implements Listener
    {

        @EventHandler
        public void on(PluginMessageEvent event)
        {
            if ( !event.getTag().equalsIgnoreCase( "my:channel" ) )
            {
                return;
            }
            ByteArrayDataInput in = ByteStreams.newDataInput( event.getData() );
            String subChannel = in.readUTF();
            if ( subChannel.equalsIgnoreCase( "OtherSubchannel" ) )
            {
                // Do things without need of a server
               
                //------------------------------------------------------------------------
                // This is if you want to do things with server
                // We can't know if the sender is a player or a server, that's why we check it
                if ( event.getSender() instanceof Server )
                {
                    Server server = (Server) event.getSender();
                    // Do things with need of a server
                    return;
                }
                if ( event.getSender() instanceof ProxiedPlayer )
                {
                    ProxiedPlayer sender = (ProxiedPlayer) event.getSender();
                    Server server = sender.getServer();
                    // Do things with need of a server
                }
            }
        }

    }
    Spigot part
    Receiving the messages from the specified channel is easy. Also, when you create your receiver, make sure to check if the server is BungeeCord (how? its showed in the example).

    Example main:

    Code (Java):
    public class ExampleMainDriver extends JavaPlugin implements PluginMessageListener {

      @Override
      public void onEnable() {
        checkIfBungee();
        if (!getServer().getPluginManager().isPluginEnabled(this)) return;
        getServer().getMessenger().registerIncomingPluginChannel(this, "my:channel", this); // we register the incoming channel
        getLogger().info("<pluginName> driver enabled successfully.");
      }

      @Override
      public void onDisable() {
        getLogger().info("<pluginName> driver was disabled!");
      }

      @Override
      public void onPluginMessageReceived(String channel, Player player, byte[] bytes) {
        if (!channel.equalsIgnoreCase("my:channel")) {
          return;
        }
        ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
        String subChannel = in.readUTF();
        if (subChannel.equalsIgnoreCase("MySubChannel")) {
          String data1 = in.readUTF();
          int data2 = in.readInt();

          // do things with the data
        }
      }

      // we check like that if the specified server is BungeeCord.
      private void checkIfBungee() {
        // we check if the server is Spigot/Paper (because of the spigot.yml file)
        if (!getServer().getVersion().contains("Spigot") || !getServer().getVersion().contains("Paper")) {
          getLogger().severe("You probably run CraftBukkit... Please update atleast to spigot for this to work...");
          getLogger().severe("Plugin disabled!");
          getServer().getPluginManager().disablePlugin(this);
          return;
        }
        File file = new File(getDataFolder().getParentFile().getParent(), "spigot.yml");
        FileConfiguration configuration = YamlConfiguration.loadConfiguration(file);
        if (!configuration.getBoolean("settings.bungeecord")) {
          getLogger().severe("This server is not BungeeCord.");
          getLogger().severe("If the server is already hooked to BungeeCord, please enable it into your spigot.yml aswell.");
          getLogger().severe("Plugin disabled!");
          getServer().getPluginManager().disablePlugin(this);
        }
      }
    }
    I think you now understood how to send custom plugin messages! Its literally so easy!
  • Loading...
  • Loading...