Difference between revisions of "Manual:Supported Protocols"

From Mudlet
Jump to navigation Jump to search
 
(43 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
{{TOC right}}
 
{{TOC right}}
 +
{{#description2:Manual on supported protocols like CHARSET, GMCP, MSSP, MSP, ATCP, MSDP, MXP, etc.}}
 
= Supported Protocols =
 
= Supported Protocols =
  
Mudlet supports GMCP, MSSP, MSP, ATCP, Aardwolfs 102, MSDP, and the MXP Protocol. MXP, MSSP, MSP, GMCP and 102 are enabled by default, MSDP can be enabled in settings.
+
Mudlet supports CHARSET, GMCP, MSSP, MSP, ATCP, Aardwolfs 102, MSDP, and the MXP Protocol.  
 +
 
 +
CHARSET, MXP, MSSP, MSP, GMCP and 102 are enabled by default, MSDP can be enabled in settings.
  
 
[[File:Game protocols toggle.png|center]]
 
[[File:Game protocols toggle.png|center]]
  
 
==GMCP==
 
==GMCP==
Generic Mud Communication Protocol, or GMCP, is a protocol for MUD servers to communicate information with MUD clients in a separate channel from the one which carries all of the text that makes up the game itself. Enabling the Debug window will show you GMCP events as they are coming in, and to get an idea of what information is currently stored, hit the Statistics button.
+
Generic Mud Communication Protocol, or GMCP, is a protocol for game servers to communicate information with game clients in a separate channel from the one which carries all of the text that makes up the game itself. Enabling the Debug window will show you GMCP events as they are coming in, and to get an idea of what information is currently stored, hit the Statistics button.
  
 
When working with GMCP on IRE games, this [https://github.com/keneanung/GMCPAdditions GMCP reference] is a useful tool.
 
When working with GMCP on IRE games, this [https://github.com/keneanung/GMCPAdditions GMCP reference] is a useful tool.
Line 24: Line 27:
  
 
====Sending GMCP data====
 
====Sending GMCP data====
Certain modules will only send data when a request is made by your client. In Mudlet, you can make such a request using the command '''sendGMCP("command")'''. Read your MUD's relevant documentation, such as the [http://nexus.ironrealms.com/GMCP IRE document on GMCP], for information about specific modules.
+
Certain modules will only send data when a request is made by your client. In Mudlet, you can make such a request using the command '''sendGMCP("command")'''. Read your game's relevant documentation, such as the [http://nexus.ironrealms.com/GMCP IRE document on GMCP], for information about specific modules.
  
 
:See Also: [[Manual:Networking Functions#sendGMCP | sendGMCP]]
 
:See Also: [[Manual:Networking Functions#sendGMCP | sendGMCP]]
  
 
===Managing GMCP modules===
 
===Managing GMCP modules===
While some GMCP modules are enabled by Mudlet by default when you connect with a GMCP enabled MUD, others may not be 'standard' modules and are instead specific to the MUD itself. In order to provide a way to manage GMCP modules without scripts causing modules in use by other scripts to be disabled.
+
While some GMCP modules are enabled by Mudlet by default when you connect with a GMCP enabled game, others may not be 'standard' modules and are instead specific to the game itself. In order to provide a way to manage GMCP modules without scripts causing modules in use by other scripts to be disabled.
{{note}} The gmod lua module has been included with Mudlet (rc2.0+).  
 
  
 
====Registering user====
 
====Registering user====
Line 63: Line 65:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
The main difference being that the module will be turned on as soon as you enable it if it is not already enabled. If you disable it, it will not be disabled with the server until every user of that module has disabled it. This prevents script A from disabling modules that script B may still be using.
 
The main difference being that the module will be turned on as soon as you enable it if it is not already enabled. If you disable it, it will not be disabled with the server until every user of that module has disabled it. This prevents script A from disabling modules that script B may still be using.
 
===Client.Media===
 
Want to add accessibility and excitement into your game? How about implementing sound and music via GMCP?
 
 
The Client.Media family of GMCP packages provide a way for games to send sound and music events. GMCP media events are sent in one direction: from game server to to game client.
 
 
====Client.Media in Mudlet====
 
 
Media files may be downloaded manually or automatically if certain conditions are met.
 
 
Client.Media GMCP packages are available in Mudlet 4.4+
 
 
====Enabling Media====
 
When a new profile opens, Mudlet adds to the Core.Supports.Set GMCP package "Client.Media 1" to signal to servers that it supports processing media files via GMCP:
 
 
<syntaxhighlight lang="json">
 
Core.Supports.Set ["Client.Media 1", ...]
 
</syntaxhighlight>
 
 
To process Client.Media GMCP data in Mudlet, these boxes in the Settings window of Mudlet must be checked:
 
 
# The "Enable GMCP" box in the Miscellaneous section.
 
# The "Allow server to download and play media" box in the Game protocols section.
 
 
These boxes are checked by default upon the start of a new profile in Mudlet.
 
 
====Storing Media====
 
 
Mudlet plays files cached in the "media" folder within a game's profile. To get files into the "media" folder you could perform either of these options:
 
 
# Copy media files or extract them from an archive (zip)
 
# Automatically download them from external resources such as your game's web server on the Internet.
 
 
To enable the second option (Internet), use the "url" parameter made available in the "Client.Media", "Client.Media.Load" and "Client.Media.Play" GMCP packages described below.
 
 
====Loading Media====
 
 
Send a '''Client.Media''' GMCP event to setup the default URL directory to load sound or music files from external resources. This would typically be done once upon player login.
 
 
{| class="wikitable"
 
! Required
 
! Key
 
! Value
 
! style="text-align:left;"| Purpose
 
|- style="color: green;"
 
| style="text-align:center;"| Yes
 
| "url"
 
| <url>
 
| style="text-align:left;"|
 
* Resource location where the media file may be downloaded.
 
|-
 
|}
 
 
For example, to setup the default URL directory for your game:
 
 
<syntaxhighlight lang="json">
 
Client.Media {
 
  "url": "https://www.example.com/media/"
 
}
 
</syntaxhighlight>
 
 
If downloading from external resources, it is recommended to use Client.Media, set this default URL directory once, and let Mudlet download all of your media files automatically from this one resource location. Otherwise, explicitly set the "url" parameter on all of your Client.Media.Load GMCP and Client.Media.Play GMCP events to ensure that files are downloaded from the intended location(s).
 
 
Send '''Client.Media.Load''' GMCP events to load sound or music files. This could be done when the player logs into your game or at the beginning of a zone that will need the media.
 
 
{| class="wikitable"
 
! Required
 
! Key
 
! Value
 
! style="text-align:left;"| Purpose
 
|- style="color: green;"
 
| style="text-align:center;"| Yes
 
| "name"
 
| <file name>
 
| style="text-align:left;"|
 
* Name of the media file.
 
|- style="color: blue;"
 
| style="text-align:center;"| Maybe
 
| "url"
 
| <url>
 
| style="text-align:left;"|
 
* Resource location where the media file may be downloaded.
 
* Only required if a url was not set above with Client.Media.
 
|-
 
| style="text-align:center;"| No
 
| "tag"
 
| <tag>
 
| style="text-align:left;"|
 
* Stores media in folders and helps categorize media.
 
|-
 
|}
 
 
For example, download the sound of a sword swooshing and categorize it in the "combat" folder within the "media" folder:
 
 
<syntaxhighlight lang="json">
 
Client.Media.Load {
 
  "name": "sword1.wav",
 
  "url": "https://www.example.com/media/",
 
  "tag": "combat"
 
}
 
</syntaxhighlight>
 
 
====Playing Media====
 
 
Send '''Client.Media.Play''' GMCP events to play sound or music files.
 
 
{| class="wikitable"
 
! Required
 
! Key
 
! Value
 
! Default
 
! style="text-align:left;"| Purpose
 
|- style="color: green;"
 
| style="text-align:center;"| Yes
 
| "name"
 
| <file name>
 
| &nbsp;
 
| style="text-align:left;"|
 
* Name of the media file.
 
* Wildcards ''*'' and ''?'' may be used within the name to randomize media files selection.
 
|- style="color: blue;"
 
| style="text-align:center;"| Maybe
 
| "url"
 
| <url>
 
| &nbsp;
 
| style="text-align:left;"|
 
* Resource location where the media file may be downloaded.
 
* Only required if the file is to be downloaded remotely and a url was not set above with Client.Media or Client.Media.Load.
 
|-
 
| style="text-align:center;"| No
 
| "type"
 
| "sound" or "music"
 
| "sound"
 
| style="text-align:left;"|
 
* Identifies the type of media.
 
|-
 
| style="text-align:center;"| No
 
| "tag"
 
| <tag>
 
| &nbsp;
 
| style="text-align:left;"|
 
* Stores media in folders and helps categorize media.
 
|-
 
| style="text-align:center;"| No
 
| "volume"
 
| 1 to 100
 
| 50
 
| style="text-align:left;"|
 
* Relative to the volume set on the player's client.
 
|-
 
| style="text-align:center;"| No
 
| "loops"
 
| -1, or >= 1
 
| 1
 
| style="text-align:left;"|
 
* Number of iterations that the media plays.
 
|-
 
| style="text-align:center;"| No
 
| "priority"
 
| 1 to 100
 
| &nbsp;
 
| style="text-align:left;"|
 
* Halts the play of current or future played media files with a lower priority while this media plays.
 
|-
 
| style="text-align:center;"| No
 
| "continue"
 
| true or false
 
| true
 
| style="text-align:left;"|
 
* Only valid for media files with a "type" of "music".
 
* Continues playing matching new music files when true
 
* Restarts matching new music files when false.
 
|-
 
| style="text-align:center;"| No
 
| "key"
 
| <key>
 
| &nbsp;
 
| style="text-align:left;"|
 
* Uniquely identifies media files with a "key" that is bound to their "name" or "url".
 
* Halts the play of current media files with the same "key" that have a different "name" or "url" while this media plays.
 
|-
 
|}
 
 
===== name =====
 
 
For example, to simply play the sound of a cow mooing already stored in the "media" folder:
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "cow.wav"
 
}
 
</syntaxhighlight>
 
 
The "name" parameter may be used for stopping media with the Client.Media.Stop GMCP event.
 
 
===== url =====
 
 
If you maintain your sound files on the Internet and don't set a default URL with Client.Media, or preload them with Client.Media.Load, include the "url" parameter:
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "cow.wav",
 
  "url": "https://www.example.com/media/"
 
}
 
</syntaxhighlight>
 
 
===== type: sound =====
 
 
Media files default to a "type" of "sound" when the "type" parameter is not specified, such as in the example above. It is good practice to specify the "type" parameter to best keep media organized within your implementation:
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "cow.wav",
 
  "type": "sound"
 
}
 
</syntaxhighlight>
 
 
The "type" parameter may be used for stopping matching media with the Client.Media.Stop GMCP event.
 
 
===== tag =====
 
 
To play the sound of a sword swooshing and categorized in the "combat" folder within the "media" folder:
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "sword1.wav",
 
  "type": "sound",
 
  "tag": "combat"
 
}
 
</syntaxhighlight>
 
 
The "tag" parameter may be used for stopping matching media with the Client.Media.Stop GMCP event.
 
 
===== type: music =====
 
 
Add background music to your environment through use of the "music" value set upon the "type" parameter:
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "river.wav",
 
  "type": "music",
 
  "tag": "environment"
 
}
 
</syntaxhighlight>
 
 
The "type" parameter may be used for stopping matching media with the Client.Media.Stop GMCP event.
 
 
===== volume: 1 to 100 =====
 
 
As the character draws nearer to or farther from the environmental feature, consider adjusting the "volume" parameter.  Example values, followed by syntax examples:
 
 
* Maximum: 100 (recommended to use rarely)
 
* High: 75
 
* Default: 50
 
* Low: 25
 
* Minimum: 1 (recommended to use rarely)
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "river.wav",
 
  "type": "music",
 
  "tag": "environment",
 
  "volume": 75
 
}
 
</syntaxhighlight>
 
 
Although using the integer type is recommended, Mudlet parses "volume" values of type string ("75") into integers (75) as needed.
 
 
===== loops: -1, 1 or more =====
 
 
The "loops" parameter controls how many times the sound repeats and defaults to 1 if not specified. A value of -1 will loop the file indefinitely.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "hour_bell.wav",
 
  "type": "sound",
 
  "loops": 3
 
}
 
 
Client.Media.Play {
 
  "name": "underdark.mp3",
 
  "type": "music",
 
  "tag": "environment",
 
  "loops": -1
 
}
 
</syntaxhighlight>
 
 
Although using the integer type is recommended, Mudlet parses "loops" values of type string ("-1") into integers (-1) as needed.
 
 
===== priority: 1 to 100 =====
 
 
The "priority" parameter sets precedence for Client.Media.Play GMCP events that include a "priority" setting. The values for the "priority" parameter range between 1 and 100. Given that two Client.Media.Play GMCP events have the same priority, the media already playing will continue playing. In Mudlet, media without priority set is not included comparisons based on priority.
 
 
A common place to find priority implemented is with combat. In the following example, imagine a combat scenario where some sounds of sword thrusts were interrupted by a successful blocking maneuver.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "sword1.wav",
 
  "type": "sound",
 
  "tag": "combat",
 
  "loops": 3,
 
  "priority": 60
 
}
 
 
Client.Media.Play {
 
  "name": "block1.wav",
 
  "type": "sound",
 
  "tag": "combat",
 
  "priority": 70
 
}
 
</syntaxhighlight>
 
 
Although using the integer type is recommended, Mudlet parses "priority" values of type string ("25") into integers (25) as needed.
 
 
The "priority" parameter may be used for stopping matching media with the Client.Media.Stop GMCP event.
 
 
===== continue: true or false (for music) =====
 
 
Typically sent with the "type" of "music" is the parameter "continue", which presents the following values:
 
 
* true: continues music that is already playing if it is requested again through a new Client.Media.Play GMCP event
 
* false: restarts music that is already playing if it is requested again through a new Client.Media.Play GMCP event
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "city.mp3",
 
  "type": "music",
 
  "tag": "environment",
 
  "continue": true
 
}
 
</syntaxhighlight>
 
 
If the "continue" parameter is not specified, behavior will default to ''true'' for music.
 
 
Although using the boolean type is recommended, Mudlet parses "continue" values of type string ("true" and "false") into boolean (''true'' and ''false'') as needed, as not all game drivers support a boolean type.
 
 
===== key =====
 
 
The "key" parameter enables media categorization, similar to the "tag" parameter, however it adds a feature of uniqueness that halts media currently playing with the same key, replacing it with the media that arrived from a new Client.Media.Play GMCP event. This update will only occur if the "name" or "url" associated with the currently playing media does not match the new media, while the key is identical.
 
 
In the example below, consider that a player moves from a sewer area to a village.  The "key" parameter is used to stop the previously playing ''sewer.mp3'' and start playing ''village.mp3'' within the second Client.Media.Play GMCP event.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "sewer.mp3",
 
  "type": "music",
 
  "tag": "environment",
 
  "loops": -1,
 
  "continue": true,
 
  "key": "area-music"
 
}
 
 
Client.Media.Play {
 
  "name": "village.mp3",
 
  "type": "music",
 
  "tag": "environment",
 
  "loops": -1,
 
  "continue": true,
 
  "key": "area-music"
 
}
 
</syntaxhighlight>
 
 
The "key" parameter may be used for stopping matching media with the Client.Media.Stop GMCP event.
 
 
=====randomization=====
 
 
Wildcards ''*'' (asterisk) and ''?'' (question mark) may be used within the name to randomize media file(s) selection.
 
 
Given that media files underdark.wav, underdark.mp3 and underdark_dark_elven_moshpit.mp3 were all present in the media/environment directory under the current game profile, the following Client.Media.Play GMCP event would randomly choose one of those files to play using the ''*'' wildcard.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "underdark*",
 
  "type": "music",
 
  "tag": "environment",
 
  "loops": -1,
 
  "continue": false
 
}
 
</syntaxhighlight>
 
 
If media files sword1.wav, sword2.wav and sword3.wav were all present in the media/combat directory under the current game profile, the following Client.Media.Play GMCP event would randomly choose one of those files to play per each loop using the ''?'' wildcard.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Play {
 
  "name": "sword?.wav",
 
  "type": "sound",
 
  "tag": "combat",
 
  "loops": 3
 
}
 
</syntaxhighlight>
 
 
====Stopping Media====
 
 
Send '''Client.Media.Stop''' GMCP events to stop sound or music media.
 
 
{| class="wikitable"
 
! Required
 
! Key
 
! Value
 
! style="text-align:left;"| Purpose
 
|-
 
| style="text-align:center;"| No
 
| "name"
 
| <file name>
 
| style="text-align:left;"|
 
* Stops playing media by name matching the value specified.
 
|-
 
| style="text-align:center;"| No
 
| "type"
 
| "sound" or "music"
 
| style="text-align:left;"|
 
* Stops playing media by type matching the value specified.
 
|-
 
| style="text-align:center;"| No
 
| "tag"
 
| <tag>
 
| style="text-align:left;"|
 
* Stops playing media by tag matching the value specified.
 
|-
 
| style="text-align:center;"| No
 
| "priority"
 
| 1 to 100
 
| style="text-align:left;"|
 
* Stops playing media with priority less than or equal to the value.
 
|-
 
| style="text-align:center;"| No
 
| "key"
 
| <key>
 
| style="text-align:left;"|
 
* Stops playing media by key matching the value specified.
 
|-
 
|}
 
 
=====all=====
 
 
Send the Client.Media.Stop GMCP event with no parameters to stop all playing media within a given game profile.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Stop {}
 
</syntaxhighlight>
 
 
=====parameters=====
 
 
Send any combination of the name, type, tag, priority or sound parameters and valid corresponding values to stop playing media that matches ''all'' combinations of the parameters.
 
 
Stop the rain.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Stop {
 
  "name": "rain.wav"
 
}
 
</syntaxhighlight>
 
 
Stop all media using the "type" of "sound".
 
 
<syntaxhighlight lang="json">
 
Client.Media.Stop {
 
  "type": "sound"
 
}
 
</syntaxhighlight>
 
 
Stop all media categorized with the "tag" of "combat" ''and'' that has a "priority" less than or equal to 50.
 
 
<syntaxhighlight lang="json">
 
Client.Media.Stop {
 
  "tag": "combat",
 
  "priority": 50
 
}
 
</syntaxhighlight>
 
 
Stop all media categorized with the "key" of "area-music".
 
 
<syntaxhighlight lang="json">
 
Client.Media.Stop {
 
  "key": "area-music"
 
}
 
</syntaxhighlight>
 
  
 
===Thorough GMCP tutorial===
 
===Thorough GMCP tutorial===
Line 545: Line 70:
  
 
==MSDP==
 
==MSDP==
MSDP is a protocol for MUD servers to communicate information with MUD clients in a separate channel from the one which carries all of the text that makes up the game itself. Mudlet can be configured to use MSDP by clicking on the Settings button (or Options->Preferences in the menu, or <alt>p). The option is on the General tab.  
+
MSDP (Mud Server Data Protocol) is a protocol for game servers to communicate information with game clients in a separate channel from the one which carries all of the text that makes up the game itself. Mudlet can be configured to use MSDP by clicking on the Settings button (or Options->Preferences in the menu, or <alt>p). The option is on the General tab.  
  
Once MSDP is enabled, you will need to reconnect to the MUD so that Mudlet can inform the server it is ready to receive GMCP information. Please note that some servers don't both send MSDP and GMCP at the same time, so even if you enable both in Mudlet, the server will choose to send only one of them.
+
Once MSDP is enabled, you will need to reconnect to the game so that Mudlet can inform the server it is ready to receive MSDP information. Please note that some servers don't both send MSDP and GMCP at the same time, so even if you enable both in Mudlet, the server will choose to send only one of them.
  
Enabling the Debug window will show you MSDP events as they are coming in, and to get an idea of what information is currently stored, hit the Statistics button. Also see [http://tintin.sourceforge.net/msdp/ MSDP reference] for some of the commands and values your server might support.
+
Enabling the Debug window will show you MSDP events as they are coming in, and to get an idea of what information is currently stored, hit the Statistics button. Also see [http://tintin.sourceforge.net/protocols/msdp/ MSDP reference] for some of the commands and values your server might support.
  
 
===Using MSDP===
 
===Using MSDP===
Line 570: Line 95:
  
 
====Sending MSDP data====
 
====Sending MSDP data====
You can use [[Manual:Networking Functions#sendMSDP | sendMSDP]] to send information via MSDP back to the game. The first parameter to the function is the MSDP variable, and all the subsequent ones are values. See the [http://tintin.sourceforge.net/msdp/ MSDP documentation] for some examples of data that you can send:
+
You can use [[Manual:Networking Functions#sendMSDP | sendMSDP]] to send information via MSDP back to the game. The first parameter to the function is the MSDP variable, and all the subsequent ones are values. See the [https://mudhalla.net/tintin/protocols/msdp/ MSDP documentation] for some examples of data that you can send:
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Line 581: Line 106:
  
 
:See Also: [[Manual:Networking Functions#sendMSDP | sendMSDP]]
 
:See Also: [[Manual:Networking Functions#sendMSDP | sendMSDP]]
 +
 +
==Encoding==
 +
More and more game servers are looking beyond ASCII encoding to support extended character sets, like UTF-8 encoding, to meet demand for localization of language and the use of emoji characters.
 +
 +
===Encoding in Mudlet===
 +
Reference our manual page on [[Manual:Unicode | Unicode]] for more information on Unicode updating, scripting and trigger support in Mudlet.
 +
 +
====Manual Encoding Updates====
 +
Mudlet supports manual selection of a server data encoding. Mudlet users may update the server data encoding for a profile by choosing Settings, General and selecting a server data encoding from the corresponding drop-down menu. The server data encoding defaults to ASCII. When the setting is changed, the selected encoding saves with the user's profile information.
 +
 +
====Automated Encoding Updates====
 +
Negotiating the '''CHARSET''' telnet option provides game servers the capability to automatically request a preferred character set with Mudlet per [https://tools.ietf.org/html/rfc2066 RFC 2066]. Game servers may send a telopt WILL CHARSET (42), Mudlet responds with a DO CHARSET (42), then the game server may send SB CHARSET (42) REQUEST (1) <separator_character> <charset>. Mudlet will respond with SB CHARSET (42) ACCEPTED (2) <charset> if it supports that character set. Mudlet will respond with SB CHARSET (42) REJECTED (3) if it refuses the requested character set(s). When Mudlet accepts a requested character set, it automatically updates the server data encoding viewable in the Settings menu. It is possible to send a list of requested character sets to Mudlet by appending additional "<separator_character> <charset>" byte groups to a SB CHARSET (42) REQUEST (1).
 +
 +
Success example:
 +
{| class="wikitable"
 +
! Server
 +
! Mudlet
 +
|-
 +
| IAC WILL CHARSET (42)
 +
| IAC DO CHARSET (42)
 +
|-
 +
| IAC SB CHARSET (42) REQUEST (1) <space> ''UTF-8'' IAC SE
 +
| IAC SB CHARSET (42) ACCEPTED (2) ''UTF-8'' IAC SE
 +
|-
 +
|}
 +
 +
The following is an example of an attempted negotiation where the encoding was not available with Mudlet:
 +
{| class="wikitable"
 +
! Server
 +
! Mudlet
 +
|-
 +
| IAC WILL CHARSET (42)
 +
| IAC DO CHARSET (42)
 +
|-
 +
| IAC SB CHARSET (42) REQUEST (1) <space> ''DEEP-6'' IAC SE
 +
| IAC SB CHARSET (42) REJECTED (3) IAC SE
 +
|-
 +
|}
 +
 +
If a Mudlet user does not want to negotiate character set, they may choose the Settings, Special Options menu item in Mudlet and enable "Force CHARSET negotiation off". The following is an example of an attempted negotiation where "Force CHARSET negotiation off" is enabled.
 +
{| class="wikitable"
 +
! Server
 +
! Mudlet
 +
|-
 +
| IAC WILL CHARSET (42)
 +
| IAC DONT CHARSET (42)
 +
|-
 +
|}
 +
 +
CHARSET negotiation is available in Mudlet 4.10+.
  
 
==MSSP==
 
==MSSP==
'''Mud Server Status Protocol''', or MSSP, provides a way for MUD crawlers (i.e. [https://tintin.sourceforge.io/protocols/mssp/mudlist.html MSSP Mud Crawler]) and MUD listing sites (search for Listings [https://www.reddit.com/r/MUD/ here]) to gather detailed information about a game, including dynamic information like boot time and the current amount of online players. It also makes submitting a new game entry very simple on MUD listing sites. A player or administrator is only required to fill in the hostname and port and other information is gathered from behind the scenes.
+
'''Mud Server Status Protocol''', or MSSP, provides a way for game crawlers (i.e. [https://tintin.sourceforge.io/protocols/mssp/mudlist.html MSSP Mud Crawler]) and game listing sites (search for Listings [https://www.reddit.com/r/MUD/ here]) to gather detailed information about a game, including dynamic information like boot time and the current amount of online players. It also makes submitting a new game entry very simple on game listing sites. A player or administrator is only required to fill in the hostname and port and other information is gathered from behind the scenes.
  
 
===MSSP in Mudlet===
 
===MSSP in Mudlet===
Line 593: Line 168:
 
To receive MSSP data in Mudlet, these conditions must be met:
 
To receive MSSP data in Mudlet, these conditions must be met:
  
# The ''Enable MSSP'' box in the Settings window of Mudlet must be checked.
+
# The ''Enable MSSP'' box in the Settings window of Mudlet must be checked (default on).
 
# The game must negotiate MSSP with clients like Mudlet at its login screen.  Details [https://tintin.sourceforge.io/protocols/mssp/ here].
 
# The game must negotiate MSSP with clients like Mudlet at its login screen.  Details [https://tintin.sourceforge.io/protocols/mssp/ here].
  
Line 632: Line 207:
 
   CLASSES = "8",
 
   CLASSES = "8",
 
   NAME = "StickMUD",
 
   NAME = "StickMUD",
   SSL = "0",
+
   SSL = "7670", -- legacy key, use TLS now please!
 +
  TLS = "7670",
 
   ANSI = "1",
 
   ANSI = "1",
 
   ICON = "https://www.stickmud.com/favicon.ico",
 
   ICON = "https://www.stickmud.com/favicon.ico",
Line 662: Line 238:
 
===MSP in Mudlet===
 
===MSP in Mudlet===
  
Mudlet processes MSP sound and music triggers in two ways:
+
Mudlet processes MSP sound and music triggers in three ways:
  
# '''MSP for Lua''' - Mudlet triggers may capture and invoke the [[Manual:Lua Functions#receiveMSP | receiveMSP]] function available through the Lua interpreter of Mudlet to process MSP.
+
#'''MSP over OOB''' - Mudlet is capable of receiving hidden, out-of-band telnet sound and music triggers from game servers via messaging with TELOPT 90.
# '''MSP over OOB''' - Mudlet is capable of receiving hidden, out-of-band telnet sound and music triggers from game servers via messaging with TELOPT 90.  
+
#'''MSP for Lua''' - Mudlet triggers may capture and invoke the [[Manual:Lua Functions#receiveMSP | receiveMSP]] function available through the Lua interpreter of Mudlet to process MSP.
 +
#'''MSP over GMCP''' - Mudlet may receive GMCP events from game servers sent with the [[Manual:Scripting#MUD_Client_Media_Protocol | Client.Media]] package.
  
 
Sound or music triggers that contain a media file name will be searched for in the '''media''' folder of the corresponding Mudlet profile that matches the host for the game. If the ''media'' folder and the file are found by Mudlet, it will be played, given the host's operating system supports playing that type of media file. If the file is not found, Mudlet could initiate a download of the media file when provided a URL to find the file. Alternatively, game administrators may instruct players on other ways to transfer media files by 1) creating a ''media'' folder in their game's Mudlet profile and 2) copying files or extracting them from an archive (zip).
 
Sound or music triggers that contain a media file name will be searched for in the '''media''' folder of the corresponding Mudlet profile that matches the host for the game. If the ''media'' folder and the file are found by Mudlet, it will be played, given the host's operating system supports playing that type of media file. If the file is not found, Mudlet could initiate a download of the media file when provided a URL to find the file. Alternatively, game administrators may instruct players on other ways to transfer media files by 1) creating a ''media'' folder in their game's Mudlet profile and 2) copying files or extracting them from an archive (zip).
Line 674: Line 251:
  
 
Processing of MSP is enabled by default on new game profiles. Control whether the processing is on or off through the Settings menu in Mudlet.
 
Processing of MSP is enabled by default on new game profiles. Control whether the processing is on or off through the Settings menu in Mudlet.
 +
 +
====MSP over OOB====
 +
 +
Game administrators may send sound and music triggers over the out-of-bounds (hidden) telnet channel encoded with TELOPT 90 after performing telnet negotiation with Mudlet. The advantage to this is that all of the communication is behind the scenes with no additional trigger requirements for the player (see ''MSP over Lua'').  Games will send the bytes of out-of-band messages to Mudlet in a format like this: <pre>IAC SB TELOPT_MSP !!SOUND(cow.wav L=2 V=100) IAC SE</pre>
 +
 +
{{note}} Game admins: This option does require a TELOPT 90 WILL message.
  
 
====MSP for Lua====
 
====MSP for Lua====
  
 
Check for MSP support with your game and enable any options that allow sound and music triggers to be sent to your screen.
 
Check for MSP support with your game and enable any options that allow sound and music triggers to be sent to your screen.
 +
 +
You can download the package from [[Media:MSP.zip]] or follow the instructions below.
  
 
Create a sound trigger to invoke the Lua interpreter:
 
Create a sound trigger to invoke the Lua interpreter:
  
 
{| class="wikitable"
 
{| class="wikitable"
! Name
+
!Name
! Text
+
!Text
! Type
+
!Type
! Script
+
!Script
 
|-
 
|-
| style="text-align:center;"| Sound Trigger
+
| style="text-align:center;" |Sound Trigger
| ^!!SOUND\((\S+?)(?: (.+))?\)$
+
|^!!SOUND\((\S+?)(?: (.+))?\)$
| perl regex
+
|perl regex
| style="text-align:left;"|
+
| style="text-align:left;" |
* deleteLine()
+
*deleteLine()
* [[Manual:Lua Functions#receiveMSP | receiveMSP]](matches[1])
+
*[[Manual:Lua Functions#receiveMSP | receiveMSP]](matches[1])
 
|-
 
|-
 
|}
 
|}
Line 699: Line 284:
  
 
{| class="wikitable"
 
{| class="wikitable"
! Name
+
!Name
! Text
+
!Text
! Type
+
!Type
! Script
+
!Script
 
|-
 
|-
| style="text-align:center;"| Music Trigger
+
| style="text-align:center;" |Music Trigger
| ^!!MUSIC\((\S+?)(?: (.+))?\)$
+
|^!!MUSIC\((\S+?)(?: (.+))?\)$
| perl regex
+
|perl regex
| style="text-align:left;"|
+
| style="text-align:left;" |
* deleteLine()
+
*deleteLine()
* [[Manual:Lua Functions#receiveMSP | receiveMSP]](matches[1])
+
*[[Manual:Lua Functions#receiveMSP | receiveMSP]](matches[1])
 
|-
 
|-
 
|}
 
|}
  
====MSP over OOB====
+
{{note}} Game admins: Best practice is to implement a TELOPT 90 WILL message as a signal to the client that MSP is supported. This is not required.
 +
 
 +
If your game does not negotiate MSP, you can download [[Media:MSP-Alternate.zip]] or you can use this script in your trigger instead of receiveMSP for MSP Sound:
 +
<syntaxhighlight lang="lua">
 +
deleteLine()
 +
local mspFile = nil
 +
local mspVolume = 100
 +
local mspLength = 1
 +
local mspPriority = 50
 +
local mspType = nil
 +
local mspURL = nil
 +
-- Strip !!SOUND() from the line
 +
local line = matches[1]:sub(9, -2)
 +
-- Break up the line into tokens
 +
local tokens = line:split(" ")
 +
-- Iterate through the tokens to discover MSP values
 +
for index, value in ipairs(tokens) do
 +
  if index == 1 then
 +
    mspFile = value
 +
  elseif value:find("V=", 1, true) == 1 or value:find("v=", 1, true) == 1 then
 +
    mspVolume = tonumber(value:sub(3))
 +
  elseif value:find("L=", 1, true) == 1 or value:find("l=", 1, true) == 1 then
 +
    mspLength = tonumber(value:sub(3))
 +
  elseif value:find("P=", 1, true) == 1 or value:find("p=", 1, true) == 1 then
 +
    mspPriority = tonumber(value:sub(3))
 +
  elseif value:find("T=", 1, true) == 1 or value:find("t=", 1, true) == 1 then
 +
    mspType = value:sub(3)
 +
  elseif value:find("U=", 1, true) == 1 or value:find("u=", 1, true) == 1 then
 +
    mspURL = value:sub(3)
 +
  end
 +
end
 +
if mspFile == "Off" and mspURL == nil then
 +
  stopSounds()
 +
else
 +
  playSoundFile(
 +
    {
 +
      name = mspFile,
 +
      volume = mspVolume,
 +
      loops = mspLength,
 +
      priority = mspPriority,
 +
      tag = mspType,
 +
      url = mspURL,
 +
    }
 +
  )
 +
end
 +
</syntaxhighlight>
 +
 
 +
If your game does not negotiate MSP, you can use this script in your trigger instead of receiveMSP for MSP Music:
 +
<syntaxhighlight lang="lua">
 +
deleteLine()
 +
local mspFile = nil
 +
local mspVolume = 100
 +
local mspLength = 1
 +
local mspContinue = true
 +
local mspType = nil
 +
local mspURL = nil
 +
-- Strip !!MUSIC() from the line
 +
local line = matches[1]:sub(9, -2)
 +
-- Break up the line into tokens
 +
local tokens = line:split(" ")
 +
-- Iterate through the tokens to discover MSP values
 +
for index, value in ipairs(tokens) do
 +
  if index == 1 then
 +
    mspFile = value
 +
  elseif value:find("V=", 1, true) == 1 or value:find("v=", 1, true) == 1 then
 +
    mspVolume = tonumber(value:sub(3))
 +
  elseif value:find("L=", 1, true) == 1 or value:find("l=", 1, true) == 1 then
 +
    mspLength = tonumber(value:sub(3))
 +
  elseif value:find("C=", 1, true) == 1 or value:find("c=", 1, true) == 1 then
 +
    if tonumber(value:sub(3)) == 0 then
 +
      mspContinue = false
 +
    else
 +
      mspContinue = true
 +
    end
 +
  elseif value:find("T=", 1, true) == 1 or value:find("t=", 1, true) == 1 then
 +
    mspType = value:sub(3)
 +
  elseif value:find("U=", 1, true) == 1 or value:find("u=", 1, true) == 1 then
 +
    mspURL = value:sub(3)
 +
  end
 +
end
 +
if mspFile == "Off" and mspURL == nil then
 +
  stopMusic()
 +
else
 +
  playMusicFile(
 +
    {
 +
      name = mspFile,
 +
      volume = mspVolume,
 +
      loops = mspLength,
 +
      continue = mspContinue,
 +
      tag = mspType,
 +
      url = mspURL,
 +
    }
 +
  )
 +
end
 +
</syntaxhighlight>
 +
 
 +
====MSP over GMCP ====
 +
 
 +
Reference Mudlet's [[Manual:Scripting#MUD_Client_Media_Protocol | documentation]] on the [[Standards:MUD_Client_Media_Protocol | MUD Client Media Protocol]] specification for more information.
  
Game administrators may send sound and music triggers over the out-of-bounds (hidden) telnet channel encoded with TELOPT 90 after performing telnet negotiation with Mudlet. The advantage to this is that all of the communication is behind the scenes with no additional trigger requirements for the player (see ''MSP over Lua'').  Games will send the bytes of out-of-band messages to Mudlet in a format like this: <syntaxhighlight>IAC SB TELOPT_MSP !!SOUND(cow.wav L=2 V=100) IAC SE</syntaxhighlight>
+
{{note}} Game admins: Do not implement a TELOPT 90 WILL message exchange when exclusively using this option.
  
 
===MSP Troubleshooting===
 
===MSP Troubleshooting===
  
* Wildcards ''?'' or ''*'' within the file name do not trigger automatic sound or music downloads. Ensure the sound was downloaded previously prior to using a wildcard.
+
*Wildcards ''?'' or ''*'' within the file name do not trigger automatic sound or music downloads. Ensure the sound was downloaded previously prior to using a wildcard.
 +
*Mudlet < 4.11 would not play the MSP sound if it had unknown elements, Mudlet 4.12+ will ignore the unknown elements and do the best it can to play the sound.
  
 
===MSP Specification===
 
===MSP Specification===
 
For more insight into the syntax of sound and music triggers, please reference the [https://www.zuggsoft.com/zmud/msp.htm specification].
 
For more insight into the syntax of sound and music triggers, please reference the [https://www.zuggsoft.com/zmud/msp.htm specification].
  
==ATCP==
+
===Sound packs===
 +
As most games have been around for a long time, they often use Mud Sound Protocol (MSP) to play sounds.  We often find that the game administrators have documented a downloadable soundpack on their website, or that a 3rd party has made one.  In Mudlet, a profile is created for each game, and you can manually create a media folder inside of it and drop in the media files (sound, music).  For games using MSP, you can create simple triggers to play them which are [[#MSP_for_Lua|documented above]].
 +
 
 +
== ATCP==
  
Since version 1.0.6, Mudlet includes support for ATCP. This is primarily available on IRE-based MUDs, but Mudlet's implementation is generic enough such that any it should work on others.
+
Mudlet includes support for ATCP. This is primarily available on IRE-based MUDs, but Mudlet's implementation is generic enough such that any it should work on others.
 +
 
 +
{{Note}} ATCP has been overtaken by GMCP, prefer to use that instead.
  
 
The latest ATCP data is stored in the atcp table. Whenever new data arrives, the previous is overwritten. An event is also raised for each ATCP message that arrives. To find out the available messages available in the atcp table and the event names, you can use display(atcp).
 
The latest ATCP data is stored in the atcp table. Whenever new data arrives, the previous is overwritten. An event is also raised for each ATCP message that arrives. To find out the available messages available in the atcp table and the event names, you can use display(atcp).
Line 753: Line 442:
 
Feel free to experiment with this to achieve the desired results. A ATCP demo package is also available on the forums for using event handlers and parsing its messages into Lua datastructures.
 
Feel free to experiment with this to achieve the desired results. A ATCP demo package is also available on the forums for using event handlers and parsing its messages into Lua datastructures.
  
=== Mudlet-specific ATCP ===
+
===Mudlet-specific ATCP===
 
See [[Manual:ATCP_Extensions|ATCP Extensions]] for ATCP extensions that have been added to Mudlet.
 
See [[Manual:ATCP_Extensions|ATCP Extensions]] for ATCP extensions that have been added to Mudlet.
  
 
==Aardwolf’s 102 subchannel==
 
==Aardwolf’s 102 subchannel==
  
Similar to ATCP, Aardwolf includes a hidden channel of information that you can access in Mudlet since 1.1.1. Mudlet deals with it in the same way as with ATCP, so for full usage instructions see the ATCP section. All data is stored in the channel102 table, such that you can do:
+
Similar to ATCP, Aardwolf includes a hidden channel of information that you can access in Mudlet. Mudlet deals with it in the same way as with ATCP, so for full usage instructions see the ATCP section. All data is stored in the channel102 table, such that you can do:
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Line 779: Line 468:
  
 
==MXP==
 
==MXP==
MXP is based loosely on the HTML and XML standards supported by modern web browsers.  It is only "loosely" based upon these standards because MUDs require dynamic, streaming text, rather than the page-oriented view of web browsers.  Also, the existing standards are needlessly verbose for use on a MUD where text efficiency is important.
+
MXP is based loosely on the HTML and XML standards supported by modern web browsers.  It is only "loosely" based upon these standards because games require dynamic, streaming text, rather than the page-oriented view of web browsers.  Also, the existing standards are needlessly verbose for use on a game where text efficiency is important.
  
In addition, there are additional security concerns to worry about with MXP.  While support for HTML tags within a line is desired, players on a MUD can exploit this power and cause problems.  Certain HTML functions need to be restricted so that MUD players cannot abuse them.  For example, while it might be desirable to allow players to change the font or color of their chat messages, you would not want to allow them to display a large graphics image, or execute script commands on the client of other users.  MXP handles this by grouping the various tags and commands into secure and open categories, and preventing the secure tags from being used by MUD players.
+
In addition, there are additional security concerns to worry about with MXP.  While support for HTML tags within a line is desired, players on a game can exploit this power and cause problems.  Certain HTML functions need to be restricted so that players cannot abuse them.  For example, while it might be desirable to allow players to change the font or color of their chat messages, you would not want to allow them to display a large graphics image, or execute script commands on the client of other users.  MXP handles this by grouping the various tags and commands into secure and open categories, and preventing the secure tags from being used by players.
  
Mudlet implements a subset of MXP features - the most popular ones that are actually in use. Mudlet supports MXP links (including send to prompt and open in browser (Mudlet 3.17+)), pop-up menus, creation of custom elements, and line modes.
+
Mudlet implements a subset of MXP features - the most popular ones that are actually in use. Mudlet supports MXP links (including send to prompt and open in browser in Mudlet 3.17+), pop-up menus, creation of custom elements, and line modes. As a game admin, you can ask what features are supported with the <code><SUPPORT></code> command.
 +
 
 +
=== MXP in Mudlet ===
 +
Just like GMCP, MXP data is available in the <code>mxp.</code> namespace and events are raised. To see all MXP events, turn on Debug mode.
 +
 
 +
[[File:MXP data.png]]
 +
 
 +
<syntaxhighlight lang="lua">
 +
function testmxpsend()
 +
  print("Text for the link is: ".. mxp.send.href)
 +
  print("Commands to do are: ")
 +
  display(mxp.send.actions)
 +
  print("\n")
 +
end
 +
 
 +
registerAnonymousEventHandler("mxp.send", "testmxpsend")
 +
</syntaxhighlight>
 +
 
 +
{{Note}} Available in Mudlet 4.8+
 +
 
 +
=== Receiving MXP Data ===
 +
[[File:Mudlet MXP example.gif|alt=shows how MXP can be used to BUY an item at a shop, then within the inventory they can select what to do with their items. i.e. Drop, Eat, Wear, Drink...|thumb|MXP example in Mudlet]]
 +
Processing of MXP is enabled by default on new game profiles. Control whether the processing is on or off through the Settings menu in Mudlet.
 +
 
 +
==== Simple example of receiving MXP Data (Server owners) ====
 +
<syntaxhighlight lang="html">
 +
<SEND href=\"&text;\">  go north...  </SEND>"
 +
</syntaxhighlight>This creates a clickable link that will enable the player to navigate without typing the directions into Mudlet. MXP sends the data immediately when clicked.
 +
 
 +
==== Advanced example of receiving MXP Data (Server owners) ====
 +
<syntaxhighlight lang="html">
 +
<send href='examine &#34;&name;&#34;|get &#34;&name;&#34;' hint='Right mouse click to act on this item|Get &desc;|Examine &desc;|Look in &desc;' expire=get>\" ATT='name desc'>
 +
</syntaxhighlight>This creates a clickable link that will 'examine' an item. It also enables a right-click function wherein the player can select to either examine or get the item (in this case &name; is the item and &desc; is the item's description ).
 +
 
 +
===MXP Specification===
 +
MXP was originally developed and supported by the Zuggsoft team. For more insight into the syntax, reference the [https://www.zuggsoft.com/zmud/mxp.htm specification]. Mudlet has a partial implementation version 1.0 of the MXP spec - to see what is supported, ask Mudlet with the [https://www.zuggsoft.com/zmud/mxp.htm#Version%20Control <SUPPORT>] tag.
  
 
==Secure connection (TLS)==
 
==Secure connection (TLS)==
Line 792: Line 516:
 
Note that the game must support a secure (TLS) connection in order for this to work, and this feature is available in Mudlet 3.17+.
 
Note that the game must support a secure (TLS) connection in order for this to work, and this feature is available in Mudlet 3.17+.
  
If you are a games admin/developer, check out [https://wiki.mudlet.org/w/Sample_TLS_Configuration this] or [https://blog.oestrich.org/2018/11/nginx-tls-socket this] example on how to setup a secure connection to your game.
+
If you are a games admin/developer, check out [https://wiki.mudlet.org/w/Sample_TLS_Configuration this] or [https://blog.oestrich.org/2018/11/nginx-tls-socket this] example on how to setup a secure connection to your game, as well as [[Manual:Technical_Manual#Receiving_MSSP_Data|MSSP data]] in order to let Mudlet know that you do have a secure connection available.
 +
 
 +
=== Secure connection prompt ===
 +
{{MudletVersion|4.17}}
 +
To encourage enhanced data transfer protection and privacy, Mudlet will respond to the detection of the <code>TLS</code> (or <code>SSL</code> legacy) key of MSSP ([[MSSP|Mud Server Status Protocol]]) and prompt a user not on a TLS (Transport Layer Security) connection with a choice to reconnect with the advertised TLS port from MSSP.
 +
 
 +
[[File:200146744-9aa3305d-99b2-4e4b-ab48-99779d7e0f76.png|alt=Prompting for secure connection|frameless|928x928px]]
 +
 
 +
If the user selects <code>Yes</code>, Mudlet automatically updates the port with the <code>TLS</code> value gathered from MSSP, check-marks the <code>Secure</code> checkbox on the connection dialog, then reconnects.  If the user selects <code>No</code>, Mudlet automatically updates a profile preference so they are not asked again for the current profile, then reconnects.  This preference may be controlled on the Settings->Connection menu.  This preference is enabled by default.
 +
 
 +
[[File:Secure connection reminder.png|alt=Secure connection reminder|frameless|927x927px]]
  
==Adding support for a telnet protocol==
+
==Adding support for a telnet protocol ==
 
In addition to supporting ATCP, GMCP, Aardwolf's 102 and MXP, Mudlet has open telnet support - meaning that for any telnet protocol it doesn't support, it has the tools you can use to build the support for. This does not mean Mudlet supports other protocols "out of the box" - you will either have to get code that adds the support, or you could create it yourself.
 
In addition to supporting ATCP, GMCP, Aardwolf's 102 and MXP, Mudlet has open telnet support - meaning that for any telnet protocol it doesn't support, it has the tools you can use to build the support for. This does not mean Mudlet supports other protocols "out of the box" - you will either have to get code that adds the support, or you could create it yourself.
  
 
The basic tools that you need are [[Manual:Miscellaneous_Functions#addSupportedTelnetOption|addSupportedTelnetOption()]], [[Manual:Miscellaneous_Functions#sendSocket|sendSocket()]] and the [[Manual:Event_Engine#sysTelnetEvent|sysTelnetEvent]].
 
The basic tools that you need are [[Manual:Miscellaneous_Functions#addSupportedTelnetOption|addSupportedTelnetOption()]], [[Manual:Miscellaneous_Functions#sendSocket|sendSocket()]] and the [[Manual:Event_Engine#sysTelnetEvent|sysTelnetEvent]].
  
Create [[Manual:Event_Engine#Registering_an_event_from_a_script|an event handler]] that goes off on [[Manual:Event_Engine#sysTelnetEvent|sysTelnetEvent]] - which is raised whenever an unsupported telnet option is encountered. Your logic handling will start in this event handler. Once you decide what you'd like to send to the MUD, use [[Manual:Miscellaneous_Functions#sendSocket|sendSocket()]] to send raw data as-is. Finally, when your logic is done, use [[Manual:Miscellaneous_Functions#addSupportedTelnetOption|addSupportedTelnetOption()]] to register your telnet option with Mudlet, so it will respond with telnet DO on a query from the MUD server. See [http://www.mudbytes.net/forum/comment/63920/#c63920 this MSDP snippet] for a barebones example.
+
Create [[Manual:Event_Engine#Registering_an_event_from_a_script|an event handler]] that goes off on [[Manual:Event_Engine#sysTelnetEvent|sysTelnetEvent]] - which is raised whenever an unsupported telnet option is encountered. Your logic handling will start in this event handler. Once you decide what you'd like to send to the game, use [[Manual:Miscellaneous_Functions#sendSocket|sendSocket()]] to send raw data as-is. Finally, when your logic is done, use [[Manual:Miscellaneous_Functions#addSupportedTelnetOption|addSupportedTelnetOption()]] to register your telnet option with Mudlet, so it will respond with telnet DO on a query from the game server. See [http://www.mudbytes.net/forum/comment/63920/#c63920 this MSDP snippet] for a barebones example.
  
 
===API philosophy===
 
===API philosophy===
Line 808: Line 542:
 
Events have names, and optionally, any amount of data with them. For protocol support, Mudlet prefixes the relevant message received name with the protocol name in lowercase. For example, an ATCP Char.Vitals getting updated would raise an event titled "atcp.Char.Vitals". A GMCP Room.Info message would raise a "gmcp.Room.Info" message.  
 
Events have names, and optionally, any amount of data with them. For protocol support, Mudlet prefixes the relevant message received name with the protocol name in lowercase. For example, an ATCP Char.Vitals getting updated would raise an event titled "atcp.Char.Vitals". A GMCP Room.Info message would raise a "gmcp.Room.Info" message.  
  
Additionally, Mudlet also allows catch-all event - in case the user wants to use one event handler for a variety of sub-events (it's not uncommon for MUDs to use ''Main.Sub.Add'', ''Main.Sub.Remove'', ''Main.Sub.List'' to keep track of a list, for example, while conserving data). To accomplish this, it raises events for every relevant namespace - that is, a Main.Sub.Add event will raise ''protocol.Main.Sub'' and ''protocol.Main.Sub.Add events''. While it is entirely possible for one event handler to react to multiple events, this is provided for convenience.
+
Additionally, Mudlet also allows catch-all event - in case the user wants to use one event handler for a variety of sub-events (it's not uncommon for games to use ''Main.Sub.Add'', ''Main.Sub.Remove'', ''Main.Sub.List'' to keep track of a list, for example, while conserving data). To accomplish this, it raises events for every relevant namespace - that is, a Main.Sub.Add event will raise ''protocol.Main.Sub'' and ''protocol.Main.Sub.Add events''. While it is entirely possible for one event handler to react to multiple events, this is provided for convenience.
  
 
For storing protocol data, Mudlet uses an aptly named global table - '''gmcp''' for GMCP data, '''atcp''' for ATCP data. Data is stored in the same way it is received and the event is raised for - so a Char.Vitals message's contents will be stored in gmcp.Char.Vitals, a Room.Info's contents in gmcp.Room.Info. If there were was any nested data within the message, it is stored as a table within the proper namespace - ie, a "details" JSON array of a GMCP Room.Info message would be stored in gmcp.Room.Info.details. '''Use a global table with the protocol name in lowerspace for storing permanent data''' that your users will read from.
 
For storing protocol data, Mudlet uses an aptly named global table - '''gmcp''' for GMCP data, '''atcp''' for ATCP data. Data is stored in the same way it is received and the event is raised for - so a Char.Vitals message's contents will be stored in gmcp.Char.Vitals, a Room.Info's contents in gmcp.Room.Info. If there were was any nested data within the message, it is stored as a table within the proper namespace - ie, a "details" JSON array of a GMCP Room.Info message would be stored in gmcp.Room.Info.details. '''Use a global table with the protocol name in lowerspace for storing permanent data''' that your users will read from.

Latest revision as of 10:12, 22 December 2023

Supported Protocols

Mudlet supports CHARSET, GMCP, MSSP, MSP, ATCP, Aardwolfs 102, MSDP, and the MXP Protocol.

CHARSET, MXP, MSSP, MSP, GMCP and 102 are enabled by default, MSDP can be enabled in settings.

Game protocols toggle.png

GMCP

Generic Mud Communication Protocol, or GMCP, is a protocol for game servers to communicate information with game clients in a separate channel from the one which carries all of the text that makes up the game itself. Enabling the Debug window will show you GMCP events as they are coming in, and to get an idea of what information is currently stored, hit the Statistics button.

When working with GMCP on IRE games, this GMCP reference is a useful tool.

Using GMCP

Receiving GMCP data

To "trigger" on GMCP messages, you'll need to create an event handler - Mudlet will call it for you whenever relevant GMCP data is received.

As an example, create a new script and give it a name of the function you'd like to be called when the relevant GMCP message is received. Then, add the GMCP event you'd like the function to fire on under the registered event handlers left. Lastly, define the function - either in this or any other script - and you'll be done. The GMCP data received will be stored in the corresponding field of the gmcp table, which your function will read from.

Example:

Using gmcp.png

The test_gmcp() function will be called whenever Char.Vitals is received from the game, and it'll echo the latest data on the screen.

Sending GMCP data

Certain modules will only send data when a request is made by your client. In Mudlet, you can make such a request using the command sendGMCP("command"). Read your game's relevant documentation, such as the IRE document on GMCP, for information about specific modules.

See Also: sendGMCP

Managing GMCP modules

While some GMCP modules are enabled by Mudlet by default when you connect with a GMCP enabled game, others may not be 'standard' modules and are instead specific to the game itself. In order to provide a way to manage GMCP modules without scripts causing modules in use by other scripts to be disabled.

Registering user

While this step is no longer strictly required, you can register your 'user' with gmod using

gmod.registerUser("MyUser")

Where MyUser is your plugin/addon/whatever name. However, your user will be automatically registered if you enable or disable any modules using it. Which leads us to...

Enabling modules

Enabling a GMCP module is as easy as:

gmod.enableModule("MyUser", "Module.Name")

If MyUser has not been registered previously, then they will be automatically registered when you call this function. An example of a module which would need to be enabled this way is the IRE.Rift module provided by IRE MUDs.

-- add this to a login trigger, or anything that will get done just once per login
gmod.enableModule("<character name>", "IRE.Rift")

Another example would be the Combat module in Lithmeria, which isn't enabled by default:

-- add this to a login trigger, or anything that will get done just once per login
gmod.enableModule("<character name>", "Combat")

Disabling modules

Disabling a GMCP module is just as easy as enabling it:

gmod.disableModule("MyUser", "Module.Name")

The main difference being that the module will be turned on as soon as you enable it if it is not already enabled. If you disable it, it will not be disabled with the server until every user of that module has disabled it. This prevents script A from disabling modules that script B may still be using.

Thorough GMCP tutorial

A good GMCP tutorial that walks you through receiving and sending GMCP data is available here - take a read!

MSDP

MSDP (Mud Server Data Protocol) is a protocol for game servers to communicate information with game clients in a separate channel from the one which carries all of the text that makes up the game itself. Mudlet can be configured to use MSDP by clicking on the Settings button (or Options->Preferences in the menu, or <alt>p). The option is on the General tab.

Once MSDP is enabled, you will need to reconnect to the game so that Mudlet can inform the server it is ready to receive MSDP information. Please note that some servers don't both send MSDP and GMCP at the same time, so even if you enable both in Mudlet, the server will choose to send only one of them.

Enabling the Debug window will show you MSDP events as they are coming in, and to get an idea of what information is currently stored, hit the Statistics button. Also see MSDP reference for some of the commands and values your server might support.

Using MSDP

Receiving MSDP data

To "trigger" on MSDP messages, you'll need to create an event handler - Mudlet will call it for you whenever relevant MSDP data is received.

As an example, lets create a script that'll track whenever we move - that is, the room number changes. To begin with, we need to ask the game to be sending us updates whenever we move - so do:

lua sendMSDP("REPORT", "ROOM_VNUM")

in the command-line first to enable reporting of the room number and name. Then, create a new script and give it a name of the function you'd like to be called when the relevant MSDP message is received. Add the MSDP event you'd like the function to fire on under the registered event handlers - in our case, msdp.ROOM_VNUM. Lastly, define the function - either in this or any other script - and you'll be done. The MSDP data received will be stored in the corresponding field of the msdp table, which your function will read from.

Example:

Using msdp.png

The test_msdp() function will be called whenever ROOM_VNUM is received from the game, and it'll echo the latest data on the screen.

Sending MSDP data

You can use sendMSDP to send information via MSDP back to the game. The first parameter to the function is the MSDP variable, and all the subsequent ones are values. See the MSDP documentation for some examples of data that you can send:

-- ask the server to report your health changes to you. Result will be stored in msdp.HEALTH in Mudlet
sendMSDP("REPORT", "HEALTH")

-- client - IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "AREA NAME" MSDP_VAL "ROOM NAME" IAC SE in the documentation translates to the following in Mudlet:
sendMSDP("SEND", "AREA NAME", "ROOM NAME")
See Also: sendMSDP

Encoding

More and more game servers are looking beyond ASCII encoding to support extended character sets, like UTF-8 encoding, to meet demand for localization of language and the use of emoji characters.

Encoding in Mudlet

Reference our manual page on Unicode for more information on Unicode updating, scripting and trigger support in Mudlet.

Manual Encoding Updates

Mudlet supports manual selection of a server data encoding. Mudlet users may update the server data encoding for a profile by choosing Settings, General and selecting a server data encoding from the corresponding drop-down menu. The server data encoding defaults to ASCII. When the setting is changed, the selected encoding saves with the user's profile information.

Automated Encoding Updates

Negotiating the CHARSET telnet option provides game servers the capability to automatically request a preferred character set with Mudlet per RFC 2066. Game servers may send a telopt WILL CHARSET (42), Mudlet responds with a DO CHARSET (42), then the game server may send SB CHARSET (42) REQUEST (1) <separator_character> <charset>. Mudlet will respond with SB CHARSET (42) ACCEPTED (2) <charset> if it supports that character set. Mudlet will respond with SB CHARSET (42) REJECTED (3) if it refuses the requested character set(s). When Mudlet accepts a requested character set, it automatically updates the server data encoding viewable in the Settings menu. It is possible to send a list of requested character sets to Mudlet by appending additional "<separator_character> <charset>" byte groups to a SB CHARSET (42) REQUEST (1).

Success example:

Server Mudlet
IAC WILL CHARSET (42) IAC DO CHARSET (42)
IAC SB CHARSET (42) REQUEST (1) <space> UTF-8 IAC SE IAC SB CHARSET (42) ACCEPTED (2) UTF-8 IAC SE

The following is an example of an attempted negotiation where the encoding was not available with Mudlet:

Server Mudlet
IAC WILL CHARSET (42) IAC DO CHARSET (42)
IAC SB CHARSET (42) REQUEST (1) <space> DEEP-6 IAC SE IAC SB CHARSET (42) REJECTED (3) IAC SE

If a Mudlet user does not want to negotiate character set, they may choose the Settings, Special Options menu item in Mudlet and enable "Force CHARSET negotiation off". The following is an example of an attempted negotiation where "Force CHARSET negotiation off" is enabled.

Server Mudlet
IAC WILL CHARSET (42) IAC DONT CHARSET (42)

CHARSET negotiation is available in Mudlet 4.10+.

MSSP

Mud Server Status Protocol, or MSSP, provides a way for game crawlers (i.e. MSSP Mud Crawler) and game listing sites (search for Listings here) to gather detailed information about a game, including dynamic information like boot time and the current amount of online players. It also makes submitting a new game entry very simple on game listing sites. A player or administrator is only required to fill in the hostname and port and other information is gathered from behind the scenes.

MSSP in Mudlet

The MSSP data presented in Mudlet will enable MSSP standard data fields to be made accessible for scripting. Some useful fields include the game name, number of players, uptime, game hostname, game port, codebase, admin contact, Discord invite URL, year created, link to an icon, ip address, primary language, game location, website and several others may be available. It is up to the game in question to populate the data, so don't expect all fields to be filled in.

MSSP is available in Mudlet 4.1+.

Receiving MSSP Data

To receive MSSP data in Mudlet, these conditions must be met:

  1. The Enable MSSP box in the Settings window of Mudlet must be checked (default on).
  2. The game must negotiate MSSP with clients like Mudlet at its login screen. Details here.

To see whether your game supports MSSP, after connecting, type lua mssp. If the game does not support MSSP, you will see an empty table mssp = {}. If it does you will see information similar to the example below. The data may be accessed in a similar way to the instructions for GMCP listed above. Typically, MSSP data is only sent once per connection.

mssp = {
  HOSTNAME = "stickmud.com",
  VT100 = "1",
  UPTIME = "1565657220",
  MSDP = "0",
  MCP = "0",
  GMCP = "1",
  PORT = "7680",
  ["MINIMUM AGE"] = "13",
  PUEBLO = "0",
  INTERMUD = "-1",
  SKILLS = "100",
  ["HIRING BUILDERS"] = "0",
  PLAYERS = "6",
  CONTACT = "askstickmud@hotmail.com",
  CODEBASE = "LDMud 3.5.0 (3.5.1)",
  ["HIRING CODERS"] = "0",
  ["PAY FOR PERKS"] = "0",
  LOCATION = "Canada",
  GAMESYSTEM = "Custom",
  MCCP = "0",
  SUBGENRE = "Medieval Fantasy",
  ROOMS = "10000",
  STATUS = "Live",
  FAMILY = "LPMud",
  LEVELS = "150",
  CREATED = "1991",
  ["PAY TO PLAY"] = "0",
  IP = "24.138.28.11",
  MOBILES = "-1",
  GAMEPLAY = "Hack and Slash",
  CLASSES = "8",
  NAME = "StickMUD",
  SSL = "7670", -- legacy key, use TLS now please!
  TLS = "7670",
  ANSI = "1",
  ICON = "https://www.stickmud.com/favicon.ico",
  RACES = "12",
  UTF-8 = "0",
  AREAS = "-1",
  MXP = "0",
  HELPFILES = "-1",
  ["XTERM 256 COLORS"] = "0",
  MSP = "1",
  OBJECTS = "9780",
  WEBSITE = "https://www.stickmud.com",
  GENRE = "Fantasy",
  DISCORD = "https://discord.gg/erBBxt",
  LANGUAGE = "English"
}

MSP

Want to add accessibility and excitement into your game? How about implementing sound and music triggers?

Mud Sound Protocol, or MSP, provides a way for games to send sound and music triggers to clients. Clients have the option to implement a framework where the corresponding triggers play. MSP triggers are sent in one direction to game clients and not to game servers. Sounds may be downloaded manually or automatically if conditions are met.

Games could use telnet option negotiation to signal clients support for MSP (WILL, WONT), and toggling MSP processing on and off (DO, DONT). This is communicated using TELOPT 90, which is reserved (unofficially) for the MSP protocol by our community. Games that do not support telnet option negotiation for MSP should provide a means for their players to toggle this feature on and off.

The latest specification for MSP is located here.

MSP in Mudlet

Mudlet processes MSP sound and music triggers in three ways:

  1. MSP over OOB - Mudlet is capable of receiving hidden, out-of-band telnet sound and music triggers from game servers via messaging with TELOPT 90.
  2. MSP for Lua - Mudlet triggers may capture and invoke the receiveMSP function available through the Lua interpreter of Mudlet to process MSP.
  3. MSP over GMCP - Mudlet may receive GMCP events from game servers sent with the Client.Media package.

Sound or music triggers that contain a media file name will be searched for in the media folder of the corresponding Mudlet profile that matches the host for the game. If the media folder and the file are found by Mudlet, it will be played, given the host's operating system supports playing that type of media file. If the file is not found, Mudlet could initiate a download of the media file when provided a URL to find the file. Alternatively, game administrators may instruct players on other ways to transfer media files by 1) creating a media folder in their game's Mudlet profile and 2) copying files or extracting them from an archive (zip).

MSP is available in Mudlet 4.4+

Receiving MSP Data

Processing of MSP is enabled by default on new game profiles. Control whether the processing is on or off through the Settings menu in Mudlet.

MSP over OOB

Game administrators may send sound and music triggers over the out-of-bounds (hidden) telnet channel encoded with TELOPT 90 after performing telnet negotiation with Mudlet. The advantage to this is that all of the communication is behind the scenes with no additional trigger requirements for the player (see MSP over Lua). Games will send the bytes of out-of-band messages to Mudlet in a format like this:

IAC SB TELOPT_MSP !!SOUND(cow.wav L=2 V=100) IAC SE

Note Note: Game admins: This option does require a TELOPT 90 WILL message.

MSP for Lua

Check for MSP support with your game and enable any options that allow sound and music triggers to be sent to your screen.

You can download the package from Media:MSP.zip or follow the instructions below.

Create a sound trigger to invoke the Lua interpreter:

Name Text Type Script
Sound Trigger ^!!SOUND\((\S+?)(?: (.+))?\)$ perl regex

Create a music trigger to invoke the Lua interpreter:

Name Text Type Script
Music Trigger ^!!MUSIC\((\S+?)(?: (.+))?\)$ perl regex

Note Note: Game admins: Best practice is to implement a TELOPT 90 WILL message as a signal to the client that MSP is supported. This is not required.

If your game does not negotiate MSP, you can download Media:MSP-Alternate.zip or you can use this script in your trigger instead of receiveMSP for MSP Sound:

deleteLine()
local mspFile = nil
local mspVolume = 100
local mspLength = 1
local mspPriority = 50
local mspType = nil
local mspURL = nil
-- Strip !!SOUND() from the line
local line = matches[1]:sub(9, -2)
-- Break up the line into tokens
local tokens = line:split(" ")
-- Iterate through the tokens to discover MSP values
for index, value in ipairs(tokens) do
  if index == 1 then
    mspFile = value
  elseif value:find("V=", 1, true) == 1 or value:find("v=", 1, true) == 1 then
    mspVolume = tonumber(value:sub(3))
  elseif value:find("L=", 1, true) == 1 or value:find("l=", 1, true) == 1 then
    mspLength = tonumber(value:sub(3))
  elseif value:find("P=", 1, true) == 1 or value:find("p=", 1, true) == 1 then
    mspPriority = tonumber(value:sub(3))
  elseif value:find("T=", 1, true) == 1 or value:find("t=", 1, true) == 1 then
    mspType = value:sub(3)
  elseif value:find("U=", 1, true) == 1 or value:find("u=", 1, true) == 1 then
    mspURL = value:sub(3)
  end
end
if mspFile == "Off" and mspURL == nil then
  stopSounds()
else
  playSoundFile(
    {
      name = mspFile,
      volume = mspVolume,
      loops = mspLength,
      priority = mspPriority,
      tag = mspType,
      url = mspURL,
    }
  )
end

If your game does not negotiate MSP, you can use this script in your trigger instead of receiveMSP for MSP Music:

deleteLine()
local mspFile = nil
local mspVolume = 100
local mspLength = 1
local mspContinue = true
local mspType = nil
local mspURL = nil
-- Strip !!MUSIC() from the line
local line = matches[1]:sub(9, -2)
-- Break up the line into tokens
local tokens = line:split(" ")
-- Iterate through the tokens to discover MSP values
for index, value in ipairs(tokens) do
  if index == 1 then
    mspFile = value
  elseif value:find("V=", 1, true) == 1 or value:find("v=", 1, true) == 1 then
    mspVolume = tonumber(value:sub(3))
  elseif value:find("L=", 1, true) == 1 or value:find("l=", 1, true) == 1 then
    mspLength = tonumber(value:sub(3))
  elseif value:find("C=", 1, true) == 1 or value:find("c=", 1, true) == 1 then
    if tonumber(value:sub(3)) == 0 then
      mspContinue = false
    else
      mspContinue = true
    end
  elseif value:find("T=", 1, true) == 1 or value:find("t=", 1, true) == 1 then
    mspType = value:sub(3)
  elseif value:find("U=", 1, true) == 1 or value:find("u=", 1, true) == 1 then
    mspURL = value:sub(3)
  end
end
if mspFile == "Off" and mspURL == nil then
  stopMusic()
else
  playMusicFile(
    {
      name = mspFile,
      volume = mspVolume,
      loops = mspLength,
      continue = mspContinue,
      tag = mspType,
      url = mspURL,
    }
  )
end

MSP over GMCP

Reference Mudlet's documentation on the MUD Client Media Protocol specification for more information.

Note Note: Game admins: Do not implement a TELOPT 90 WILL message exchange when exclusively using this option.

MSP Troubleshooting

  • Wildcards ? or * within the file name do not trigger automatic sound or music downloads. Ensure the sound was downloaded previously prior to using a wildcard.
  • Mudlet < 4.11 would not play the MSP sound if it had unknown elements, Mudlet 4.12+ will ignore the unknown elements and do the best it can to play the sound.

MSP Specification

For more insight into the syntax of sound and music triggers, please reference the specification.

Sound packs

As most games have been around for a long time, they often use Mud Sound Protocol (MSP) to play sounds. We often find that the game administrators have documented a downloadable soundpack on their website, or that a 3rd party has made one. In Mudlet, a profile is created for each game, and you can manually create a media folder inside of it and drop in the media files (sound, music). For games using MSP, you can create simple triggers to play them which are documented above.

ATCP

Mudlet includes support for ATCP. This is primarily available on IRE-based MUDs, but Mudlet's implementation is generic enough such that any it should work on others.

Note Note: ATCP has been overtaken by GMCP, prefer to use that instead.

The latest ATCP data is stored in the atcp table. Whenever new data arrives, the previous is overwritten. An event is also raised for each ATCP message that arrives. To find out the available messages available in the atcp table and the event names, you can use display(atcp).

Note that while the typical message comes in the format of Module.Submodule, ie Char.Vitals or Room.Exits, in Mudlet the dot is removed - so it becomes CharVitals and RoomExits.

Example
room_number = tonumber(atcp.RoomNum)
echo(room_number)

Triggering on ATCP events

If you’d like to trigger on ATCP messages, then you need to create scripts to attach handlers to the ATCP messages. The ATCP handler names follow the same format as the atcp table - RoomNum, RoomExits, CharVitals and so on.

While the concept of handlers for events is to be explained elsewhere in the manual, the quick rundown is this - place the event name you’d like your script to listen to into the Add User Defined Event Handler: field and press the + button to register it. Next, because scripts in Mudlet can have multiple functions, you need to tell Mudlet which function should it call for you when your handler receives a message. You do that by setting the Script name: to the function name in the script you’d like to be called.

For example, if you’d like to listen to the RoomExits event and have it call the process_exits() function - register RoomExits as the event handler, make the script name be process_exits, and use this in the script:

function process_exits(event, args)
    echo("Called event: " .. event .. "\nWith args: " .. args)
end

Feel free to experiment with this to achieve the desired results. A ATCP demo package is also available on the forums for using event handlers and parsing its messages into Lua datastructures.

Mudlet-specific ATCP

See ATCP Extensions for ATCP extensions that have been added to Mudlet.

Aardwolf’s 102 subchannel

Similar to ATCP, Aardwolf includes a hidden channel of information that you can access in Mudlet. Mudlet deals with it in the same way as with ATCP, so for full usage instructions see the ATCP section. All data is stored in the channel102 table, such that you can do:

display(channel102)

... to see all the latest information that has been received. The event to create handlers on is titled channel102Message, and you can use the sendTelnetChannel102(msg) function to send text via the 102 channel back to Aardwolf.

-- Function for detecting AFK status on Aardwolf mud.
function amIafk()
   for k,v in pairs(channel102) do
      if k==100 and v==4 then
         return true
      end
   end
   return false
end

MXP

MXP is based loosely on the HTML and XML standards supported by modern web browsers. It is only "loosely" based upon these standards because games require dynamic, streaming text, rather than the page-oriented view of web browsers. Also, the existing standards are needlessly verbose for use on a game where text efficiency is important.

In addition, there are additional security concerns to worry about with MXP. While support for HTML tags within a line is desired, players on a game can exploit this power and cause problems. Certain HTML functions need to be restricted so that players cannot abuse them. For example, while it might be desirable to allow players to change the font or color of their chat messages, you would not want to allow them to display a large graphics image, or execute script commands on the client of other users. MXP handles this by grouping the various tags and commands into secure and open categories, and preventing the secure tags from being used by players.

Mudlet implements a subset of MXP features - the most popular ones that are actually in use. Mudlet supports MXP links (including send to prompt and open in browser in Mudlet 3.17+), pop-up menus, creation of custom elements, and line modes. As a game admin, you can ask what features are supported with the <SUPPORT> command.

MXP in Mudlet

Just like GMCP, MXP data is available in the mxp. namespace and events are raised. To see all MXP events, turn on Debug mode.

MXP data.png

function testmxpsend()
  print("Text for the link is: ".. mxp.send.href)
  print("Commands to do are: ")
  display(mxp.send.actions)
  print("\n")
end

registerAnonymousEventHandler("mxp.send", "testmxpsend")

Note Note: Available in Mudlet 4.8+

Receiving MXP Data

shows how MXP can be used to BUY an item at a shop, then within the inventory they can select what to do with their items. i.e. Drop, Eat, Wear, Drink...
MXP example in Mudlet

Processing of MXP is enabled by default on new game profiles. Control whether the processing is on or off through the Settings menu in Mudlet.

Simple example of receiving MXP Data (Server owners)

<SEND href=\"&text;\">  go north...  </SEND>"

This creates a clickable link that will enable the player to navigate without typing the directions into Mudlet. MXP sends the data immediately when clicked.

Advanced example of receiving MXP Data (Server owners)

<send href='examine &#34;&name;&#34;|get &#34;&name;&#34;' hint='Right mouse click to act on this item|Get &desc;|Examine &desc;|Look in &desc;' expire=get>\" ATT='name desc'>

This creates a clickable link that will 'examine' an item. It also enables a right-click function wherein the player can select to either examine or get the item (in this case &name; is the item and &desc; is the item's description ).

MXP Specification

MXP was originally developed and supported by the Zuggsoft team. For more insight into the syntax, reference the specification. Mudlet has a partial implementation version 1.0 of the MXP spec - to see what is supported, ask Mudlet with the <SUPPORT> tag.

Secure connection (TLS)

To connect to a game securely, tick the 'Secure' box in the profile connection settings:

Secure-connection.png

Note that the game must support a secure (TLS) connection in order for this to work, and this feature is available in Mudlet 3.17+.

If you are a games admin/developer, check out this or this example on how to setup a secure connection to your game, as well as MSSP data in order to let Mudlet know that you do have a secure connection available.

Secure connection prompt

Mudlet VersionAvailable in Mudlet4.17+

To encourage enhanced data transfer protection and privacy, Mudlet will respond to the detection of the TLS (or SSL legacy) key of MSSP (Mud Server Status Protocol) and prompt a user not on a TLS (Transport Layer Security) connection with a choice to reconnect with the advertised TLS port from MSSP.

Prompting for secure connection

If the user selects Yes, Mudlet automatically updates the port with the TLS value gathered from MSSP, check-marks the Secure checkbox on the connection dialog, then reconnects.  If the user selects No, Mudlet automatically updates a profile preference so they are not asked again for the current profile, then reconnects.  This preference may be controlled on the Settings->Connection menu.  This preference is enabled by default.

Secure connection reminder

Adding support for a telnet protocol

In addition to supporting ATCP, GMCP, Aardwolf's 102 and MXP, Mudlet has open telnet support - meaning that for any telnet protocol it doesn't support, it has the tools you can use to build the support for. This does not mean Mudlet supports other protocols "out of the box" - you will either have to get code that adds the support, or you could create it yourself.

The basic tools that you need are addSupportedTelnetOption(), sendSocket() and the sysTelnetEvent.

Create an event handler that goes off on sysTelnetEvent - which is raised whenever an unsupported telnet option is encountered. Your logic handling will start in this event handler. Once you decide what you'd like to send to the game, use sendSocket() to send raw data as-is. Finally, when your logic is done, use addSupportedTelnetOption() to register your telnet option with Mudlet, so it will respond with telnet DO on a query from the game server. See this MSDP snippet for a barebones example.

API philosophy

Adding a support for a new telnet protocol will involve adding the user-facing API. It best for users if it was in the same style as Mudlets handling of other protocols. To see how it's done exactly, check out GMCP, ATCP or Aardwolf 102 examples - but the gist of it is provided below.

Mudlet has a built-in event system, which is used to broadcast messages in an independent way. With it, people can "trigger" on 102, ATCP or GMCP events with Lua functions that get called whenever an event they're interested in is raised. Use the event system to provide your users with a way to react to new protocol data.

Events have names, and optionally, any amount of data with them. For protocol support, Mudlet prefixes the relevant message received name with the protocol name in lowercase. For example, an ATCP Char.Vitals getting updated would raise an event titled "atcp.Char.Vitals". A GMCP Room.Info message would raise a "gmcp.Room.Info" message.

Additionally, Mudlet also allows catch-all event - in case the user wants to use one event handler for a variety of sub-events (it's not uncommon for games to use Main.Sub.Add, Main.Sub.Remove, Main.Sub.List to keep track of a list, for example, while conserving data). To accomplish this, it raises events for every relevant namespace - that is, a Main.Sub.Add event will raise protocol.Main.Sub and protocol.Main.Sub.Add events. While it is entirely possible for one event handler to react to multiple events, this is provided for convenience.

For storing protocol data, Mudlet uses an aptly named global table - gmcp for GMCP data, atcp for ATCP data. Data is stored in the same way it is received and the event is raised for - so a Char.Vitals message's contents will be stored in gmcp.Char.Vitals, a Room.Info's contents in gmcp.Room.Info. If there were was any nested data within the message, it is stored as a table within the proper namespace - ie, a "details" JSON array of a GMCP Room.Info message would be stored in gmcp.Room.Info.details. Use a global table with the protocol name in lowerspace for storing permanent data that your users will read from.

That's it! If you'll need any Mudlet-related help, feel free to post on our forums. Once you're done, package your work for distribution which you can optionally post in the finished scripts section.