Minecraft Plugin Channels + Messaging

Some keen eyed developers may have noticed that there's a new packet in Minecraft 1.1, with no purpose or usage anywhere in the codebase. You may be wondering why this was added, and what use it could possibly have. You may also be wondering who cares, and why you have this page open. I'm here to answer all of these questions in a nice little (disclaimer: may not be little) blog post!

Update: See the FAQ on this over here! Now with simple questions like "but what does this actually mean?"

Backstory

We did some thinking a while back, about how the state of client mods and server mods for minecraft isn't really what it could be. There's so many problems with conflicts and one mod causing a bug in another and so forth, that it's really harming the potential of Minecraft modding in general. While we by no means think that we can solve this, we did start hypothesizing ways that could at least improve how mods play together, and try to make things a nicer experience for everyone - the users, the client modders, and the server modders. Most importantly, those who fit in all of the above!

One of the biggest issues with client and server modding is that having both can be hell for your users. If you have a server mod that needs a client mod, if a user without the client mod tries to join then they'll crash with seemingly no cause. Ditto for users with client mods joining a server and crashing themselves, because the server mod isn't compatible with that client mod.

Honestly, this whole thing is a mess. I'm sure most people will agree with me here. There are attempted workarounds, sure, but they can break with a minecraft update and things just get worse from there. So this is where we started to talk to Mojang about improving this.

We designed a system with the help of Jens that should solve the compatibility issues between client and server mods, permanently. It's inspired by World of Warcrafts own approach to a similar (but not quite as big) issue, and we've just expanded on it. I call it Plugin Channels.

For All Modders

The system is basically as follows:

The server and client both have a list of their own installed mods, and these mods register for specific channel(s) each (they can mix'n'match, or have none at all, it doesn't matter). The client tells the server what channels it's listening on, and the server does the same to the client. Now they have a good idea about what the other side can support.

A client mod can then send a Plugin Message to the server by using a channel specific for that type of message that it wishes to send. The server will receive this message and the mod on the server side will read it and do its thing with the contents.

Because they have a list of what the other side supports, there's no bandwidth loss here. If the server wants to send a picture to the client (these messages are pure bytes, it can hold anything), but the client doesn't have anything listening on this Plugin Channel, it will know not to send it.

This system is implemented in vanilla, and you will not crash any vanilla client (or server!) using this system, not or in the future. What's not to love about that?

Example

Let's pretend our server has a mod installed that allows custom client skins. This works by sending a Plugin Message on the channel "SuperSkin:Set". A client mod by the same author listens on this channel for a Plugin Message, and turns that into a png, which is very easy because the message entirety is just the png compressed into an array of bytes. It then changes the players skin to the png upon receipt.

We have a player join, "James". He has this client mod installed. His client contacts the server and informs it that it has a mod listening for "SuperSkin:Set", and the server remembers this. We have another player join, "Sarah". She does not have this client mod installed.

The server mod decides to give both players a new skin with funky t-shirts, so it sends a Plugin Message to both players through the channel "SuperSkin:Set" with the skin encoded into the message. The server mod goes through whatever API wrapper is in place, and it decided to send the message to James because he's listening for this channel and thus can support the message. It doesn't send it to Sarah, because her client didn't inform the server that she can support this, because she can't.

James goes into third-person-view and notices he has a cool T-Shirt on, and wonders what sorcery makes this possible. He tells Sarah to do the same, because it looks really cool. She gives it a try, but no dice - she didn't have the mod installed, so nothing happened. However, she didn't crash from receiving a bad packet - so she's happy!

For API writers

There should be a basic API in place for this system to be easy for ordinary client and server modders to use. It should handle registering of Plugin Channels, unregistering also if required, and should make sure that no Plugin Messages are sent to any clients that haven't announced that they are listening for that specific channel.

On a packet scale, this is pretty simple. The packet ID is 250 (0xFA), and the format is as follows:

String,         // Plugin Channel - something unique to the mod and this type of message. 16 chars max.
int,            // Message Length - length of the message, must be below short.MAX_LENGTH (32,767).
byte[]          // Plugin Message - the message itself, whatever it may be.

The channel can be anything at all, with two exceptions (to follow shortly), but is case sensitive. It has a 16 char restriction which should be plenty for now, but I'm sure Mojang will increase it if required. The message contents is entirely up to the mod sending the message, but has a max length of 32,766. If this is an issue, you can easily make something split across multiple messages.

When you have a mod that requests to listen on a specific Plugin Channel, you should send a Plugin Message with the channel "REGISTER", followed by the name (or names, separated by \0) of the channels it's now listening on. If a plugin decided that it's no longer listening on a channel, you can send an "UNREGISTER" message the same way as a "REGISTER". These two channels are marked as off-limits and no mods should be able to register these two channels. They are currently the only reserved channels.

Bukkit Plugin Devs

The API for Bukkit has already been designed and at time of writing, has been pushed live. The basic usage is this:

// This informs Bukkit that you will send messages through that channel
Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, channel);

// This informs Bukkit that you want to receive messages through that channel, to myPluginMessageListener
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, channel, myPluginMessageListener);

class MyPluginMessageListener implements PluginMessageListener {
    public void onPluginMessageReceived(String channel, Player player, byte[] message) {
        // Do something with this message from the player
    }
}

somePlayer.sendPluginMessage(plugin, channel, message);

For full API documentation, consult the javadocs. You can find the commit over yonder

For the Users

Hopefully, you won't have any big issues between client mods and server mods anymore. Rejoice :)

For those who bothered to read to the bottom

I salute you.

Next entry

Previous entry

Similar entries

Comments

  1. turt2live

    # turt2live on 01/13/2012 8:33 a.m.

    Now I can make tabbed chat, better expansions on my current plugins, stuff that was nearly impossible but I wanted to do anyways, AND I can ditch my code I was going to write for something exactly like this :)

  2. Tahkeh

    # Tahkeh on 01/13/2012 8:38 a.m.

    You guys are brilliant!

  3. Marlamin

    # Marlamin on 01/13/2012 8:45 a.m.

    All I have to say is..

    http://www.youtube.com/watch?v=P3ALwKeSEYs

  4. Darren Straight

    # Darren Straight on 01/13/2012 9:04 a.m.

    Thank you for the update! :)

  5. james

    # james on 01/13/2012 9:22 a.m.

    So this means the next Worldedit CUI could be done over plugin channels instead of chat messages?
    AWESOME!

    Thanks for the explanation dinnerbone, looking forward to the next RB.

  6. David

    # David on 01/13/2012 9:29 a.m.

    Amazing! Thanks for this, Bukkit Team! :D

  7. TheGurw

    # TheGurw on 01/13/2012 9:56 a.m.

    I return your salute, good sir!

  8. DaLeberkasPepi

    # DaLeberkasPepi on 01/13/2012 10:54 a.m.

    You should have worked together with the spout team on this. They work on this problem since months and they have some really cool features
    In it. Why making 2 plugins for 1 problem instead of working together on one problem?

  9. Alex

    # Alex on 01/13/2012 11:08 a.m.

    Issue is the bukkit team (minecon) were asked if they supported or liked spout... there reply was somewhere along the lines of that its not nessasary or somthing... but this is good news for the developer (me) who have no idea how to develop with spout.

  10. Zarius

    # Zarius on 01/13/2012 11:58 a.m.

    I think Spout is better for the users though. With this system players have to install multiple client mods (and decide on which they trust) and players will have different experiences when they have different mixes of client mods.

    With Spout you have one client mod only that's used by a large user base (helps gain trust) and players have only two choices/experiences - Spout or no Spout (or one if you decide to enforce Spout).

    This sounds great though and hope it leads to cool things.

  11. Kiskae

    # Kiskae on 01/13/2012 12:09 p.m.

    The problem is that the spout team is doing their own thing, adding stuff that the bukkit team might deem unnecessary.
    The idea behind Bukkit is that is provides a framework, not features.

  12. Dykam

    # Dykam on 01/13/2012 2:41 p.m.

    About Spout, Spout can now use this internally as the messaging system, and still offer a higher level API to their plugins and addins. This change does benefit Spout as well.

  13. 4am

    # 4am on 01/13/2012 5:43 p.m.

    Oh please oh please let this mean support for BuildCraft/IndustrialCraft for Bukkit will become reality!

    Now the client needs a mod install system and a standard API so that users won't be baffled on how to use this stuff. Most kids don't know how to edit JAR files...

  14. rakiru

    # rakiru on 01/13/2012 6:11 p.m.

    You know what's better? Spout.

  15. ElliottB

    # ElliottB on 01/13/2012 6:31 p.m.

    For those who are comparing Spout and this change. Did you bother to read this whole blog? This is now a component of Vanilla minecraft. It's intended to make a standard messaging method between clients and servers for mod use. As such it actually benefits spout. Spout can use this standard conversation technique so that it's compatible and more standard. This isn't a bukkit specific upgrade, but a modding support change in minecraft itself. Read before you complain that 'why didn't you work with spout' or 'spout is better'. This is an API that spout can use to better itself and compatibility.

  16. BjarkeBS

    # BjarkeBS on 01/13/2012 7:45 p.m.

    Does this mean the server will be able to ask the client if there has been made modifications to the minecraft.jar file? so we can check if the client is using any altering mods.

  17. Robinton

    # Robinton on 01/13/2012 10:41 p.m.

    @BjarkeBS: TL;DR: Yes, but not securely.

    Long answer: If I understood it right, the client tells the server that it supports a specific mod functionality. Then, the server (if it has that mod enabled) sends the data for that mod functionality to the client. So that works great!

    However, a Fly Hack or whatever wouldn't tell the server that it supports fly hack functionality... So you couldn't detect fly hacks.

  18. SwearWord

    # SwearWord on 01/14/2012 12:50 a.m.

    Just so we have something consistent to call this and it doesn't turn out like superperms/bukkitperms/dinnerperms refer to it as either Plugin Channels or shortly Channels

  19. Shirou

    # Shirou on 01/14/2012 1:04 a.m.

    Good Good, Finally ^.^

  20. Activat0r

    # Activat0r on 01/14/2012 5:16 a.m.

    Awesome work! Now I'm wondering how would one go about making a client-side mod to utilize this feature? I can't seem to find anything about it.

  21. Smallperuvian

    # Smallperuvian on 01/14/2012 6:59 p.m.

    Ahh messaging... It truly is the answer to a lot of software problems like this :) Glad to see it implemented in Vanilla. That is very awesome.

  22. gomme600

    # gomme600 on 01/31/2012 5:40 p.m.

    Hi, i think it would be better if when someone joins a server with mods the client downloads the mods off the server and installs them.
    That way the client user dosent have to do anything, just wait for them to download and login.

Comments are closed.