UPDATED : The Bukkit & Bungee Plugin Messaging Channel

Discussion in 'BungeeCord Plugin Development' started by roblabla, Jun 8, 2013.

Thread Status:
Not open for further replies.
  1. THIS IS THE OLD THREAD. USE http://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/?noRedirect=1 FOR UP TO DATE INFO.

    Work-In-Progress. The documentation is done though.

    NOTE: This thread is for Bukkit plugins communicating with Bungee.
    Here, I will explain how to use the BungeeCord Plugin Channel from a Bukkit plugin. This channel allows you to query information from bungeecord, as well as make your plugin communicate between the different bukkit subservers.

    What is a Plugin Message ?
    Originally, Plugin Messaging was implemented so server-side plugins could send any kind of data to client-side mods. Before, they would have needed to implement custom packets, but the problem with this is that it meant the minecraft client would get disconnected from the servers using those custom packets with an incomprehensible error message, because it would be unable to read that packet. To fix this issue, mojang introduced the "Custom Plugin Message Packet".

    The anatomy of a Plugin Message Packet is as such :
    1) The size of the plugin message (in a short)
    2) The name of the "channel" (also named "tag" in bungeecord) the plugin message transits through (in a string)
    3) The actual data (in a byte array)

    BungeeCord Plugin Channel ?
    First of all, BungeeCord's byte array is organized around the output of a Data(In/Out)putStream

    Before using the BungeeCord plugin channel, you'll need to register it. That is, you need to tell Bukkit "Hey, I wanna use this channel". We'll also need to tell Bukkit what method to call whenever he receives a new message on channel "BungeeCord". I suggest you make your plugin class look like this :

    PHP:
    public class MyPlugin extends JavaPlugin implements PluginMessageListener {
        @Override
        public void onEnable() {
            this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
            this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", this);
        }
     
        @Override
        public void onPluginMessageReceived(String channel, Player player, byte[] message) {
            if (!channel.equals("BungeeCord")) {
                return;
            }
     
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
            String subchannel = in.readUTF();
            if (subchannel.equals("SomeSubChannel")) {
                // Do something
            } else if (subchannel.equals("SomeOtherSubChannel")) {
              // Do something else.
            }
        }
    }
    As for sending plugin messages, here is the way I recommend to do it :
    PHP:
    ByteArrayOutputStream b = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(b);
     
    out.writeUTF("subchannel");
    out.writeUTF("AnArgument");
     
     
    // If the player is important :
    Player p = Bukkit.getPlayer("someplayer");
    // OR, if you don't need to send it to a specific player
    Player p = Bukkit.getOnlinePlayers()[0];
     
    p.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
    BungeeCord's SubChannel Spec :
    Connect
    Connect a player to said subserver.

    Arguments
    String name of server to connect to, as defined in bungeecord config.yml

    Receiver
    the player you want to teleport.

    Sending Example
    PHP:
    out.writeUTF("Connect");
    out.writeUTF("pvp");
    Response
    None


    IP
    Get the (real) IP of a player.

    Arguments
    None

    Receiver
    The player you wish to get the IP of.

    Example
    PHP:
    out.writeUTF("IP");
    Response
    PHP:
    String ip = in.readUTF();
    int port = in.readInt();

    PlayerCount
    Get the amount of players on a certain server, or on ALL the servers.

    Arguments
    String the name of the server to get the playercount of, or ALL to get the global player count

    Receiver
    Any player

    Example
    PHP:
    out.writeUTF("PlayerCount");
    out.writeUTF("pvp");
    Response
    PHP:
    String server = in.readUTF(); // Name of server, as given in the arguments
    int playercount = in.readInt();

    PlayerList
    Get a list of players connected on a certain server, or on ALL the servers.

    Arguments
    String the name of the server to get the list of connected players, or ALL for global online player list

    Receiver
    Any player

    Example
    PHP:
    out.writeUTF("PlayerList");
    out.writeUTF("pvp");
    Response
    PHP:
    String server = in.readUTF(); // The name of the server you got the player list of, as given in args.
    String[] playerList = in.readUTF().split(", ");

    GetServers
    Get a list of server name strings, as defined in bungeecord's config.yml

    Arguments
    None

    Receiver
    Any player

    Example
    PHP:
    out.writeUTF("GetServers");
    Response
    PHP:
    String[] serverList = in.readUTF().split(", ");

    Message
    Send a message (as in, a chat message) to the specified player.

    Arguments
    String the name of the player to send the chat message
    String the message to send to the player

    Receiver
    Any player

    Example
    PHP:
    out.writeUTF("roblabla");
    out.writeUTF(ChatColor.RED + "Congrats, you just won 1$!");
    Response
    None


    GetServer
    Get this server's name, as defined in bungeecord's config.yml

    Arguments
    None

    Receiver
    Any player

    Example
    PHP:
    out.writeUTF("GetServer");
    Response
    PHP:
    String servername = in.readUTF();

    Forward
    Send a custom plugin message to said server. This is one of the most useful channel ever.

    Arguments
    String server to send to, or ALL to send to every server (except the one sending the plugin message)
    String Subchannel to send to.
    Short The size of the plugin message array.
    Byte[] message to send.

    Receiver
    Any player

    Example
    PHP:
    out.writeUTF("ALL");
    out.writeUTF("MyChannel");
     
    ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
    DataOutputStream msgout = new DataOutputStream(msgbytes);
    msgout.writeUTF("Some kind of data here"); // You can do anything you want with msgout
    msgout.writeShort(123);
     
    out.writeShort(msgbytes.toByteArray().length);
    out.write(msgbytes.toByteArray());
    Response
    VERY IMPORTANT : the subchannel will NOT be Forward. It will be the subchannel you sent as an argument.
    PHP:
    short len = in.readShort();
    byte[] msgbytes = new byte[len];
    in.readFully(msgbytes);
     
    DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
    String somedata = msgin.readUTF(); // Read the data in the same way you wrote it
    short somenumber = msgin.readShort();
     
    #1 roblabla, Jun 8, 2013
    Last edited: Jun 9, 2013
    • Winner Winner x 2
    • Useful Useful x 1
  2. Beat me to it! Thanks for writing this, you've saved me a bit of time. Enjoy your caffeine :)
     
    • Like Like x 1
  3. Thank you :D
     
    • Like Like x 1
  4. Very well written, thanks for making this!
     
  5. md_5

    Administrator Developer

    • Like Like x 1
  6. #7 roblabla, Jun 9, 2013
    Last edited: Jun 9, 2013
    • Like Like x 1
  7. jtaylor69

    jtaylor69 Retired Moderator
    Retired

    • Agree Agree x 1
  8. Yeah, I personally like the wiki, especially what you wrote. I will try contribute tonight.
     
  9. jtaylor69

    jtaylor69 Retired Moderator
    Retired

    Thanks Micheal. If you can get the layout similar to the Spigot config guide, that's be great as I saw you wish to contribute the BungeeCord configuration :)
     
  10. Yeah, I will make it look similar. Don't ninja me please anyone.
     
  11. brajo Finished the page.
     
  12. The typefont is so small, it's hard to read ._.
     
  13. Shall fix.
     
    • Informative Informative x 1
  14. jtaylor69

    jtaylor69 Retired Moderator
    Retired

  15. jtaylor69

    jtaylor69 Retired Moderator
    Retired

    Roblabla created the content on the Wiki, I was the one who attached a discussion thread to it as it's only possible by myself and md_5 at the moment :)
     
  16. That is some cool beans beans stuff right there ._. And yes, this thread should be closed. LiLChris .
     
  17. LiLChris

    LiLChris Retired Moderator
    Retired

    1:40 am, closed upon request...too tired to read why. :p
     
    • Like Like x 1
Thread Status:
Not open for further replies.