Once more unto the breach (MUSH GMCP help request)

EldanienEldanien Member Posts: 369 Gifted
edited February 2016 in Mechanic's Corner
What started out as an intent to retire Eldanien turned into me coming back and giving him another go.  Of course, I decide to do this when there's a combat overhaul and afflictions are extra confusing.

More to the point, Mudlet hates me and vice versa, so I'll be building my system from scratch in MUSH.  Here's the question: is there anyone willing to walk me through accessing GMCP info through Nick Gammon's plugin?  I'd gotten hold of GMCP info through MUSH before, but for the life of me I can't figure it out now and it's driving me nuts.

Please and thank you.



  • AltreaAltrea Member Posts: 193 Gifted
    edited February 2016
    Okay, so getting information from GMCP in MUSHclient is fairly simple in the long run. I'm not overly familiar with Nick Gammon's plugin, but I've got a feeling it'll require some modification anyway to fit your purposes, so I'll cover the whole thing from the start and you can adapt as necessary. I'll also include example code 

    The general trick to start any form of subnegotiation in MUSHclient is to use the function OnPluginTelnetRequest(protocol, cmd) - if protocol is equal to 201 (The 'protocol' byte for GMCP expanded out to an integer) and cmd is equal to the string "WILL", you want to return true which will signal for MUSHclient to allow it. On cmd being equal to the string "SENT_DO", which means MUSHclient sent IAC DO GMCP, you want to establish your GMCP handshake and return true. You will likely want to return false in any other situations.

    For sending a handshake, you'll want to send two GMCP packets. The first is Core.Hello, which identifies your client and its version. The second is Core.Supports.Set, which tells Lusternia which GMCP namespaces you want to support. Generally, there's no downside to supporting the majority of them and just ignoring what you don't want to use (unless maybe you're on a particularly high-latency connection, in which case it might be worth narrowing that down). A full list of namespaces can be found either in IRE's official documentation, or in the Github repository here provided by a particularly awesome Achaean: https://github.com/keneanung/GMCPAdditions

    To take the data, you'll want to define the function stub OnPluginTelnetSubnegotiation(protocol, data) - The protocol argument is the same as in OnPluginTelnetRequest, and you can generally just exit early out of the function if it's not equal to the protocol you want. The data is the raw string data of the GMCP, which follows the format

        <Command> [Data]

    Upon receiving the data, you have a few choices with it. You can either parse it in the plugin, or if you're needing to send it to your main world's script, you'll likely want to pass it in by some method or another (most people pass it to an Execute function that's picked up by an alias in the world. There's other ways, but they're less convenient.)

    Wherever you're parsing it, you can do require "json" near the beginning of the script, and after separating the command and data from the packet, you can go ahead and pass the data if it exists to json.decode(data) which will convert it to a standard Lua table.

    The following is what one's code might look like in the plugin with everything said and done. There's a few extraneous bits to fix errors and comply with the Telnet RFC, most of which should already be in Nick Gammon's plugin as is:

    EDIT: Pastebin link because forum formatting is hard: http://pastebin.com/bg3MPUiX

    An example of how to parse the data and ideas on how to use it is here: http://pastebin.com/rkvdpnPh - If you have any specific questions regarding this, feel free to ask.
Sign In or Register to comment.