Manual:Networking Functions

From Mudlet
Jump to navigation Jump to search

Networking Functions

A collection of functions for managing networking.

connectToServer

connectToServer(host, port, [save])
Connects to a given game.
Parameters
  • host:
Server domain or IP address.
  • port:
Servers port.
  • save:
(optional, boolean) if provided, saves the new connection parameters in the profile so they'll be used next time you open it.

Note Note: save is available in Mudlet 3.2+.

Example
connectToServer("midnightsun2.org", 3000)

-- save to disk so these parameters are used next time when opening the profile
connectToServer("midnightsun2.org", 3000, true)

disconnect

disconnect()
Disconnects you from the game right away. Note that this will not properly log you out of the game - use an ingame command for that. Such commands vary, but typically QUIT will work.
See also: reconnect()
Example
disconnect()

downloadFile

downloadFile(saveto, url)
Downloads the resource at the given url into the saveto location on disk. This does not pause the script until the file is downloaded - instead, it lets it continue right away and downloads in the background. When a download is finished, the sysDownloadDone event is raised (with the saveto location as the argument), or when a download fails, the sysDownloadError event is raised with the reason for failure. You may call downloadFile multiple times and have multiple downloads going on at once - but they aren’t guaranteed to be downloaded in the same order that you started them in.
See also: getHTTP(), postHTTP(), putHTTP(), deleteHTTP()
For privacy transparency, URLs accessed are logged in the Central Debug Console

Note Note: Since Mudlet 3.0, https downloads are supported and the actual url that was used for the download is returned - useful in case of redirects.

Example
-- just download a file and save it in our profile folder
local saveto = getMudletHomeDir().."/dark-theme-mudlet.zip"
local url = "http://www.mudlet.org/wp-content/files/dark-theme-mudlet.zip"
downloadFile(saveto, url)
cecho("<white>Downloading <green>"..url.."<white> to <green>"..saveto.."\n")



A more advanced example that downloads a webpage, reads it, and prints a result from it:

-- create a function to parse the downloaded webpage and display a result
function downloaded_file(_, filename)
  -- is the file that downloaded ours?
  if not filename:find("achaea-who-count.html", 1, true) then return end

  -- read the contents of the webpage in
  local f, s, webpage = io.open(filename)
  if f then webpage = f:read("*a"); io.close(f) end
  -- delete the file on disk, don't clutter
  os.remove(filename)

  -- parse our downloaded file for the player count
  local pc = webpage:match([[Total: (%d+) players online]])
  display("Achaea has "..tostring(pc).." players on right now.")
end

-- register our function to run on the event that something was downloaded
registerAnonymousEventHandler("sysDownloadDone", "downloaded_file")

-- download a list of fake users for a demo
downloadFile(getMudletHomeDir().."/achaea-who-count.html", "https://www.achaea.com/game/who")

Result should look like this:

.

getConnectionInfo

getConnectionInfo()
Returns the server address and port that you're currently connected to, and (in Mudlet 4.12+) true or false indicating if you're currently connected to a game.
See also: connectToServer()
Mudlet VersionAvailable in Mudlet4.2+
Example
local host, port, connected = getConnectionInfo()
cecho(string.format("<light_grey>Playing on <forest_green>%s:%s<light_grey>, currently connected? <forest_green>%s\n", host, port, tostring(connected)))
-- echo the new connection parameters whenever we connect to a different host with connectToServer()
function echoInfo()
    local host, port = getConnectionInfo()
    cecho(string.format("<light_grey>Now connected to <forest_green>%s:%s\n", host, port))
  end

registerAnonymousEventHandler("sysConnectionEvent", "echoInfo")

getIrcChannels

getIrcChannels()
Returns a list of channels the IRC client is joined to as a lua table. If the client is not yet started the value returned is loaded from disk and represents channels the client will auto-join when started.
See also: setIrcChannels()
Mudlet VersionAvailable in Mudlet3.3+
Example
display(getIrcChannels())
-- Prints: {"#mudlet", "#lua"}

getIrcConnectedHost

getIrcConnectedHost()
Returns true+host where host is a string containing the host name of the IRC server, as given to the client by the server while starting the IRC connection. If the client has not yet started or finished connecting this will return false and an empty string.
This function can be particularly useful for testing if the IRC client has connected to a server prior to sending data, and it will not auto-start the IRC client.
The hostname value this function returns can be used to test if sysIrcMessage events are sent from the server or a user on the network.
Example
local status, hostname = getIrcConnectedHost()

if status == true then
  -- do something with connected IRC, send IRC commands, store 'hostname' elsewhere.
  -- if sysIrcMessage sender = hostname from above, message is likely a status, command response, or an error from the Server.
else 
  -- print a status, change connection settings, or just continue waiting to send IRC data.
end
Mudlet VersionAvailable in Mudlet3.3+

getIrcNick

getIrcNick()
Returns a string containing the IRC client nickname. If the client is not yet started, your default nickname is loaded from IRC client configuration.
See also: setIrcNick()
Mudlet VersionAvailable in Mudlet3.3+
Example
local nick = getIrcNick()
echo(nick)
-- Prints: "Sheldor"

getIrcServer

getIrcServer()
Returns the IRC client server name and port as a string and a number respectively. If the client is not yet started your default server is loaded from IRC client configuration.
See also: setIrcServer()
Mudlet VersionAvailable in Mudlet3.3+
Example
local server, port = getIrcServer()
echo("server: "..server..", port: "..port.."\n")

getNetworkLatency

getNetworkLatency()
Returns the last measured response time between the sent command and the server reply in seconds - e.g. 0.058 (=58 milliseconds lag) or 0.309 (=309 milliseconds). This is the N: number you see bottom-right of Mudlet.

Also known as server lag.

Example
if getNetworkLatency() > 3 then
  send("say This game is soooo laggy!")
end

mmcp.allowSnoop

mmcp.allowSnoop(target)
Toggles permission for a chat peer to snoop you - that is, to receive a copy of the text your game sends you. Calling it once grants permission, calling it again withdraws it and stops any snoop already running. The peer is told either way.
Permission is given per peer and is not remembered between sessions.
See also: mmcp.snoop(), mmcp.getClientFlags()
Parameters
  • target:
Chat name or numeric id of a connected peer, as shown by mmcp.displayClientList().
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^allowsnoop (.+)$
if mmcp.allowSnoop(matches[2]) then
  cecho(f"<green>Snooping permission toggled for {matches[2]}.\n")
end

mmcp.call

mmcp.call(host[, port])
Calls another chat client and, if they accept, adds them to your peer list. This is a direct connection to that person's client and has nothing to do with the game you are playing.
The call is placed in the background, so this returns as soon as the attempt starts. Watch for the sysMMCPPeerUpdateEvent event to learn when the peer actually joins.
See also: mmcp.disconnect(), MMCP in Mudlet
Parameters
  • host:
IP address or domain name of the client to call.
  • port:
(optional) Port to call. Defaults to the Default Port in Settings, Chat, which is 4050 unless you change it.
Returns
  • true if the call was placed, or nil plus an error message if you are already connected to that address and port, or if the port is outside the range 1 to 65535.
Mudlet VersionAvailable in Mudlet4.21+
Example
mmcp.call("1.2.3.4", 4050)

You should see:

[ CHAT ]  - Connecting to 1.2.3.4:4050...
[ CHAT ]  - Waiting for response from 1.2.3.4:4050...
[ CHAT ]  - Connection to ChatClient at 1.2.3.4:4050 accepted.

mmcp.chatAll

mmcp.chatAll(message)
Sends a chat message to every connected peer.
They see Bob chats to everybody, 'hello', and you see <CHAT>You chat to everybody, 'hello'. Your own copy also arrives as a sysMMCPChatMessage event, attributed to System.
See also: mmcp.chatTo(), mmcp.chatGroup(), mmcp.emoteAll()
Parameters
  • message:
The message to send.
Returns
  • true on success, or nil plus an error message when nobody is connected.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatall (.+)$
mmcp.chatAll(matches[2])

mmcp.chatGroup

mmcp.chatGroup(group, message)
Sends a chat message to every connected peer you have put in the named group with mmcp.setGroup().
They see Bob chats to the group, 'hello', and you see <CHAT>You chat to <raiders>, 'hello'.
See also: mmcp.setGroup(), mmcp.chatAll()
Parameters
  • group:
The group to send to. Groups are yours alone - the peers in one are never told it exists.
  • message:
The message to send.
Returns
  • true on success, or nil plus an error message when nobody is connected, or when the group has no members. In the latter case you are still shown what you tried to say, so you know it went nowhere.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatgroup (\w+) (.+)$
mmcp.chatGroup(matches[2], matches[3])

mmcp.chatName

mmcp.chatName([name])
Reads or sets the chat name other clients see you under. Setting it announces the new name to everyone currently connected, so you do not need to reconnect.
The name is saved with the profile and can also be set in Settings, Chat under Chat Name. It starts out as MudletUser.
See also: mmcp.displayClientList()
Parameters
  • name:
(optional) The new chat name. Tildes (~) and commas (,) are not allowed, because the protocol uses them as separators.
Returns
  • With no argument, your current chat name as a string.
  • With a name, true on success, or nil plus an error message if the name contains a tilde or a comma.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatname (\S+)$
if mmcp.chatName(matches[2]) then
  cecho(f"<green>You are now known as {mmcp.chatName()} in chat.\n")
end

mmcp.chatTo

mmcp.chatTo(target, message)
Sends a private chat message to one peer.
They see Bob chats to you, 'hello', and you see <CHAT>You chat to Alice, 'hello'. Your own copy also arrives as a sysMMCPChatMessage event, attributed to the peer you addressed.
See also: mmcp.chatAll()
Parameters
  • target:
Chat name or numeric id of a connected peer, as shown by mmcp.displayClientList().
  • message:
The message to send.
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatto (\S+) (.+)$
mmcp.chatTo(matches[2], matches[3])

mmcp.disconnect

mmcp.disconnect(target)
Hangs up on a connected peer. sysMMCPPeerUpdateEvent is raised once they are gone.
See also: mmcp.call(), mmcp.ignore()
Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- hang up on everybody
for _, peer in ipairs(mmcp.getClientList() or {}) do
  mmcp.disconnect(peer.name)
end

mmcp.displayClientList

mmcp.displayClientList()
Prints a table of your chat peers to the main window. Use mmcp.getClientList() instead if you want the same information as data.
See also: mmcp.getClientFlags()
Returns
  • true.
Mudlet VersionAvailable in Mudlet4.21+
Example
mmcp.displayClientList()

You should see:

Id   Name                 Address              Port  Group           Flags    ChatClient
==== ==================== ==================== ===== =============== ======== ================
   1 ChatClient           1.2.3.4               4050                          Mudlet 5.0.0
==== ==================== ==================== ===== =============== ======== ================
Color Key: Connected  Pending
Flags:  F - Firewall,  I - Ignored,  P - Private,  S - Serving
        n - Allow Snooping,  N - Being Snooped

Connected peers are listed in green and peers who have not answered your call yet in yellow. Every other mmcp function accepts either the Id (1) or the Name (ChatClient) from this table.

mmcp.emoteAll

mmcp.emoteAll(message)
Sends an emote to every connected peer. Unlike mmcp.chatAll() the message is not quoted, so it reads as an action - peers see Bob waves at the room.
Your own copy reads the same way, unless you turn on Prefix emote messages in Settings, Chat, which shows it as <CHAT>You emote to everyone: 'Bob waves at the room' instead.
Parameters
  • message:
The emote text without your name - your chat name is put in front of it for you.
Returns
  • true on success, or nil plus an error message when nobody is connected.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^emoteall (.+)$
mmcp.emoteAll(matches[2])

-- everyone sees "Bob waves at the room" from:
mmcp.emoteAll("waves at the room")

mmcp.getClientFlags

mmcp.getClientFlags(target)
Returns a peer's flags as a fixed eight character string, so you can test one flag by position.
See also: mmcp.displayClientList()
Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • An eight character string, or nil plus an error message when nobody is connected or there is no peer by that name or id. Each position holds either its letter or a space:
    1. reserved, always a space
    2. reserved, always a space
    3. P if the peer is marked private
    4. I if you are ignoring the peer
    5. S if you are serving the peer
    6. F if the peer looks to be behind a firewall - the address they connected from is not the one they report
    7. N if the peer is snooping you right now, or n if they are merely allowed to
    8. reserved, always a space
Mudlet VersionAvailable in Mudlet4.21+
Example
local flags = mmcp.getClientFlags("ChatClient")
if flags and flags:sub(4, 4) == "I" then
  cecho("<orange>You are ignoring ChatClient.\n")
end

mmcp.getClientList

clients = mmcp.getClientList()
Returns a table of your chat peers.
See also: mmcp.displayClientList()
Returns
  • A table with one entry per peer, or nil when there are none. Each entry holds:
    • id: the peer's number in the list, which every other mmcp function accepts in place of a name. Ids are renumbered whenever a peer joins or leaves, so do not save them.
    • name: the peer's chat name.
    • host: the address the peer is connected from.
    • port: the port of the connection to that peer.
    • version: the chat client the peer runs, for example Mudlet 5.0.0. Empty until the peer announces itself, which happens moments after connecting.
Mudlet VersionAvailable in Mudlet4.21+
Example
for _, peer in ipairs(mmcp.getClientList() or {}) do
  cecho(f"<cyan>{peer.id}<white>: {peer.name} ({peer.host}:{peer.port}) running {peer.version}\n")
end

The table looks like this:

{
  {
    id = 1,
    name = "ChatClient",
    host = "1.2.3.4",
    port = 4050,
    version = "Mudlet 5.0.0"
  }
}

mmcp.ignore

mmcp.ignore(target)
Toggles ignoring a peer. Chat from an ignored peer is dropped before it reaches your screen or any event handler. Call it again to hear them once more.
See also: mmcp.disconnect()
Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatignore (.+)$
mmcp.ignore(matches[2])

mmcp.ping

mmcp.ping(target)
Sends a ping to a peer to measure the round trip to them. The answer is printed to the main window when it comes back.
Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • true once the ping is sent, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
mmcp.ping("ChatClient")

mmcp.sendSideChannel

mmcp.sendSideChannel(channel, message)
Sends data to your connected peers on a named channel, for your own scripts to pick up. Nothing is shown on anyone's screen - the receiving side gets a sysMMCPSideChannelMessage event and decides what to do with it.
This is how a group can share health bars, target information or anything else directly between clients, without the game being involved.

Note Note: Only peers running Mudlet are sent side channel data, since other chat clients have no way to act on it.

Parameters
  • channel:
A name for the channel, so a handler can tell your data apart from another script's. Use letters, digits and underscores only.
  • message:
The data to send, as a string. The channel is separated from the message by the first comma, so pick your own separator for anything you pack inside the message.
Returns
  • true on success, or nil plus an error message when nobody is connected.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- share your health with the group, from a prompt trigger
local payload = string.format("%s|%d|%d", mmcp.chatName(), gmcp.Char.Vitals.hp, gmcp.Char.Vitals.maxhp)
mmcp.sendSideChannel("stats", payload)

-- and on the receiving side
registerAnonymousEventHandler("sysMMCPSideChannelMessage", function(_, from, channel, message)
  if channel ~= "stats" then return end
  local name, hp, maxhp = message:match("([^|]+)|(%d+)|(%d+)")
  cecho(f"<cyan>{name}<white> is at {hp}/{maxhp} health.\n")
end)

mmcp.serve

mmcp.serve(target)
Toggles serving a peer. Chat you receive is passed on to a served peer, so people who cannot reach each other directly can still talk through you. Call it again to stop. The peer is told either way.
Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatserve (.+)$
mmcp.serve(matches[2])

mmcp.setGroup

mmcp.setGroup(target, group)
Puts a peer into one of your chat groups, so you can talk to several people at once with mmcp.chatGroup(). A peer belongs to at most one group.
Passing an empty string, "none" or "<none>" as the group takes the peer out of the group they are in.

Note Note: Groups are yours alone. The peer is never told which group you filed them under, and a group chat looks like any other chat to them.

Parameters
  • target:
Chat name or numeric id of a connected peer.
  • group:
The group name.
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
mmcp.setGroup("ChatClient", "raiders")
mmcp.chatGroup("raiders", "pulling in 10")

-- and to take them back out again
mmcp.setGroup("ChatClient", "none")

mmcp.setPrivate

mmcp.setPrivate(target)
Toggles the private flag on a peer. Private peers are left out of the connection lists your client would hand to other peers, so they are not passed around as someone to call. Call it again to clear the flag.

Note Note: Mudlet does not answer requests for your connection list, so for now the flag only shows up in mmcp.getClientFlags() and mmcp.displayClientList().

Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • true on success, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
mmcp.setPrivate("ChatClient")

mmcp.snoop

mmcp.snoop(target)
Asks a peer to send you what their game is sending them. Their client has to have allowed you first - with mmcp.allowSnoop() in Mudlet, or the equivalent elsewhere - otherwise they refuse and tell you so.
Snooped text arrives as a sysMMCPIncomingSnoopMessage event with its colour intact. It is also printed to your main window unless you turn off Show snoop data in main console in Settings, Chat.
See also: mmcp.allowSnoop()
Parameters
  • target:
Chat name or numeric id of a connected peer.
Returns
  • true once the request is sent, or nil plus an error message if there is no peer by that name or id.
Mudlet VersionAvailable in Mudlet4.21+
Example
-- Alias: ^chatsnoop (.+)$
mmcp.snoop(matches[2])

openIRC

openIRC()
Opens the IRC client window for the current profile. Creates the IRC client if it doesn't already exist.
Mudlet VersionAvailable in Mudlet4.20+
See also: sendIrc(), getIrcNick(), getIrcServer(), getIrcChannels()
Example
-- configure IRC and open the window
setConfig("ircHostName", "irc.libera.chat")
setConfig("ircHostPort", 6697)
setConfig("ircHostSecure", true)
setConfig("ircChannels", "#mudlet")
setConfig("ircNickName", "MyNickname")

openIRC()

Note Note: The IRC configuration UI has been removed from Settings. Use setConfig() to configure IRC settings.

openUrl

openUrl (url)
Opens the default OS browser for the given URL.
Example
openUrl("http://google.com")
openUrl("www.mudlet.org")

reconnect

reconnect()
Force-reconnects (so if you're connected, it'll disconnect) you to the game.
Example
-- you could trigger this on a log out message to reconnect, if you'd like
reconnect()

restartIrc

restartIrc()
Restarts the IRC client connection, reloading configurations from disk before reconnecting the IRC client.
Mudlet VersionAvailable in Mudlet3.3+

sendAll

sendAll([time delay], list of things to send, [echo back or not])
sends multiple things to the game with an optional delay between sends. If you'd like the commands not to be shown, include false at the end.
See also: send()
Example
-- instead of using many send() calls, you can use one sendAll
sendAll("outr paint", "outr canvas", "paint canvas")
-- can also have the commands not be echoed
sendAll("hi", "bye", false)
-- add an optional delay (in seconds, accepts decimals) which slows down the sent commands
-- 2 second delay, then sends "hi", 2 second delay then sends "bye", 2 second delay then sends "wave")
sendAll(2, "hi", "bye", "wave")

sendATCP

sendATCP(message, what)
Need description
See also: ATCP Protocol, ATCP Extensions, Achaea Telnet Client Protocol specification, Description by forum user KaVir (2013), Description by forum user Iocun (2009)
Parameters
  • message:
The message that you want to send.
  • what:
Need description
Example

Need example

sendGMCP

sendGMCP(command)
Sends a GMCP message to the server. The IRE document on GMCP has information about what can be sent, and what tables it will use, etcetera.
Note that this function is rarely used in practice. For most GMCP modules, the messages are automatically sent by the server when a relevant event happens in the game. For example, LOOKing in your room prompts the server to send the room description and contents, as well as the GMCP message gmcp.Room. A call to sendGMCP would not be required in this case.
When playing an IRE game, a call to send(" ") afterwards is necessary due to a bug in the game with compression (MCCP) is enabled.
See also: GMCP Scripting for Discord status
Example
--This would send "Core.KeepAlive" to the server, which resets the timeout
sendGMCP("Core.KeepAlive")

--This would send a request for the server to send an update to the gmcp.Char.Skills.Groups table.
sendGMCP("Char.Skills.Get {}")

--This would send a request for the server to send a list of the skills in the 
--vision group to the gmcp.Char.Skills.List table.

sendGMCP("Char.Skills.Get " .. yajl.to_string{group = "vision"})

--And finally, this would send a request for the server to send the info for 
--hide in the woodlore group to the gmcp.Char.Skills.Info table

sendGMCP("Char.Skills.Get " .. yajl.to_string{group="MWP", name="block"})

sendIrc

sendIrc(target, message)
Sends a message to an IRC channel or person. Returns true+status if message could be sent or was successfully processed by the client, or nil+error if the client is not ready for sending, and false+status if the client filtered the message or failed to send it for some reason. If the IRC client hasn't started yet, this function will initiate the IRC client and begin a connection.

To receive an IRC message, check out the sysIrcMessage event.

Note Note: Since Mudlet 3.3, auto-opens the IRC window and returns the success status.

Parameters
  • target:
nick or channel name and if omitted will default to the first available channel in the list of joined channels.
  • message:
The message to send, may contain IRC client commands which start with / and can use all commands which are available through the client window.
Example
-- this would send "hello from Mudlet!" to the channel #mudlet on freenode.net
sendIrc("#mudlet", "hello from Mudlet!")
-- this would send "identify password" in a private message to Nickserv on freenode.net
sendIrc("Nickserv", "identify password")

-- use an in-built IRC command
sendIrc("#mudlet", "/topic")

Note Note: The following IRC commands are available since Mudlet 3.3:

  • /ACTION <target> <message...>
  • /ADMIN (<server>)
  • /AWAY (<reason...>)
  • /CLEAR (<buffer>) -- Clears the text log for the given buffer name. Uses the current active buffer if none are given.
  • /CLOSE (<buffer>) -- Closes the buffer and removes it from the Buffer list. Uses the current active buffer if none are given.
  • /HELP (<command>) -- Displays some help information about a given command or lists all available commands.
  • /INFO (<server>)
  • /INVITE <user> (<#channel>)
  • /JOIN <#channel> (<key>)
  • /KICK (<#channel>) <user> (<reason...>)
  • /KNOCK <#channel> (<message...>)
  • /LIST (<channels>) (<server>)
  • /ME [target] <message...>
  • /MODE (<channel/user>) (<mode>) (<arg>)
  • /MOTD (<server>)
  • /MSG <target> <message...> -- Sends a message to target, can be used to send Private messages.
  • /NAMES (<#channel>)
  • /NICK <nick>
  • /NOTICE <#channel/user> <message...>
  • /PART (<#channel>) (<message...>)
  • /PING (<user>)
  • /RECONNECT -- Issues a Quit command to the IRC Server and closes the IRC connection then reconnects to the IRC server. The same as calling ircRestart() in Lua.
  • /QUIT (<message...>)
  • /QUOTE <command> (<parameters...>)
  • /STATS <query> (<server>)
  • /TIME (<user>)
  • /TOPIC (<#channel>) (<topic...>)
  • /TRACE (<target>)
  • /USERS (<server>)
  • /VERSION (<user>)
  • /WHO <mask>
  • /WHOIS <user>
  • /WHOWAS <user>

Note Note: The following IRC commands are available since Mudlet 3.15:

  • /MSGLIMIT <limit> (<buffer>) -- Sets the limit for messages to keep in the IRC client message buffers and saves this setting. If a specific buffer/channel name is given the limit is not saved and applies to the given buffer until the application is closed or the limit is changed again. For this reason, global settings should be applied first, before settings for specific channels/PM buffers.

sendMSDP

sendMSDP(variable[, value][, value...])
Sends a MSDP message to the server.
Parameters
  • variable:
The variable, in MSDP terms, that you want to request from the server.
  • value:
The variables value that you want to request. You can request more than one value at a time.
See Also: MSDP support in Mudlet, Mud Server Data Protocol specification

Note Note: sysProtocolEnabled is the moment to call this: it tells you the game has offered MSDP. Sending earlier - from sysConnectionEvent, which is raised before telnet negotiation - does reach the game, but it arrives before Mudlet has accepted MSDP, and a strict server is free to ignore it.

Example
-- ask for a list of commands, lists, and reportable variables that the server supports
sendMSDP("LIST", "COMMANDS", "LISTS", "REPORTABLE_VARIABLES")

-- ask the server to start keeping you up to date on your health
sendMSDP("REPORT", "HEALTH")

-- or on your health and location
sendMSDP("REPORT", "HEALTH", "ROOM_VNUM", "ROOM_NAME")

-- in a package, ask once the game has told us MSDP is available
registerNamedEventHandler("mypackage", "msdp subscribe", "sysProtocolEnabled", function(_, protocol)
  if protocol == "MSDP" then
    sendMSDP("REPORT", "HEALTH")
  end
end)

sendTelnetChannel102

sendTelnetChannel102(msg)
Sends a message via the 102 subchannel back to the game (that's used in Aardwolf). The msg is in a two byte format; see the link below to the Aardwolf Wiki for how that works.
Example
-- turn prompt flags on:
sendTelnetChannel102("\52\1")

-- turn prompt flags off:
sendTelnetChannel102("\52\2")

To see the list of options that Aardwolf supports go to: Using Telnet negotiation to control MUD client interaction.

sendSocket

sendSocket(data)
Sends given binary data as-is (or with some predefined special tokens converted to byte values) to the game. You can use this to implement support for a new telnet protocol, simultronics login etc.
success = sendSocket("data")
See also
feedTelnet(), feedTriggers()

Note Note: Modified in Mudlet 4.19.0 to accept some tokens like "<NUL>" to include byte values that are not possible to insert with the standard Lua string escape "\###" form where ### is a three digit number between 000 and 255 inclusive or where the value is more easily provided via a mnemonic. For the table of the tokens that are known about, see the one in feedTelnet().

Note Note: The data (as bytes) once the tokens have been converted to their byte values is sent as is to the Game Server; any encoding to, say, a UTF-8 representation or to duplicate 0xff byte values so they are not considered to be Telnet <IAC> (Interpret As Command) bytes must be done to the data prior to calling this function.

Parameters
  • data:
String containing the bytes to send to the Game Server possibly containing some tokens that are to be converted to bytes as well.
Returns
  • (Only since Mudlet 4.19.0) Boolean true if the whole data string (after token replacement) was sent to the Server, false if that failed for any reason (including if the Server has not been connected or is now disconnected). nil and an error message for any other defect.
Example
-- Tell the Server that we are now willing and able to process  to process Ask the Server to a comment explaining what is going on, if there is multiple functionalities (or optional parameters) the examples should start simple and progress in complexity if needed!
-- the examples should be small, but self-contained so new users can copy & paste immediately without going diving in lots other function examples first.
-- comments up top should introduce / explain what it does

local something = function(exampleValue)
if something then
  -- do something with something (assuming there is a meaningful return value)
end

-- maybe another example for the optional second case
local somethingElse = function(exampleValue, anotherValue)

-- lastly, include an example with error handling to give an idea of good practice
local ok, err = function()
if not ok then
  debugc(f"Error: unable to do <particular thing> because {err}\n")
  return
end
Additional development notes

-- This function is still being written up.

setIrcChannels

setIrcChannels(channels)
Saves the given channels to disk as the new IRC client channel auto-join configuration. This value is not applied to the current active IRC client until it is restarted with restartIrc()
See also: getIrcChannels(), restartIrc()
Parameters
  • channels:
A table containing strings which are valid channel names. Any channels in the list which aren't valid are removed from the list.
Mudlet VersionAvailable in Mudlet3.3+
Example
setIrcChannels( {"#mudlet", "#lua", "irc"} )
-- Only the first two will be accepted, as "irc" is not a valid channel name.

setIrcNick

setIrcNick(nickname)
Saves the given nickname to disk as the new IRC client configuration. This value is not applied to the current active IRC client until it is restarted with restartIrc()
See also: getIrcNick(), restartIrc()
Parameters
  • nickname:
A string with your new desired name in IRC.
Mudlet VersionAvailable in Mudlet3.3+
Example
setIrcNick( "Sheldor" )

setIrcServer

setIrcServer(hostname, port[, secure])
Saves the given server's address to disk as the new IRC client connection configuration. These values are not applied to the current active IRC client until it is restarted with restartIrc()
See also: getIrcServer(), restartIrc()
Parameters
  • hostname:
A string containing the hostname of the IRC server.
  • port:
(optional) A number indicating the port of the IRC server. Defaults to 6667, if not provided.
  • secure:
(optional) Boolean, true if server uses Transport Layer Security. Defaults to false.
Mudlet VersionAvailable in Mudlet3.3+
Example
setIrcServer("irc.libera.chat", 6667)

getHTTP

getHTTP(url, headersTable)
Sends an HTTP GET request to the given URL. Raises sysGetHttpDone on success or sysGetHttpError on failure.
See also: downloadFile().
For privacy transparency, URLs accessed are logged in the Central Debug Console
Parameters
  • url:
Location to send the request to.
  • headersTable:
(optional) table of headers to send with your request.
Mudlet VersionAvailable in Mudlet4.10+
Examples
function onHttpGetDone(_, url, body)
  cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end

registerAnonymousEventHandler("sysGetHttpDone", onHttpGetDone)

getHTTP("https://httpbin.org/info")
getHTTP("https://httpbin.org/are_you_awesome", {["X-am-I-awesome"] = "yep I am"})
-- Status requests typically use GET requests
local url = "https://postman-echo.com/status"
local header = {["Content-Type"] = "application/json"}

-- first we create something to handle the success, and tell us what we got
registerAnonymousEventHandler('sysGetHttpDone', function(event, rurl, response)
  if rurl == url then display(r) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires
-- then we create something to handle the error message, and tell us what went wrong
registerAnonymousEventHandler('sysGetHttpError', function(event, response, rurl)
  if rurl == url then display(r) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires

-- Lastly, we make the request:
getHTTP(url, header)

-- Pop this into an alias and try it yourself!

postHTTP

postHTTP(dataToSend, url, headersTable, file)
Sends an HTTP POST request to the given URL, either as text or with a specific file you'd like to upload. Raises sysPostHttpDone on success or sysPostHttpError on failure.
See also: downloadFile(), getHTTP(), putHTTP(), deleteHTTP().
For privacy transparency, URLs accessed are logged in the Central Debug Console
Parameters
  • dataToSend:
Text to send in the request (unless you provide a file to upload).
  • url:
Location to send the request to.
  • headersTable:
(optional) table of headers to send with your request.
  • file:
(optional) file to upload as part of the POST request. If provided, this will replace 'dataToSend'.
If you use a scripting language (ex. PHP) to handle this post, remember that the file is sent as raw data. Expecially no field name is provided, dispite it works in common html post.
Mudlet VersionAvailable in Mudlet4.1+
Examples
function onHttpPostDone(_, url, body)
  cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end

registerAnonymousEventHandler("sysPostHttpDone", onHttpPostDone)

postHTTP("why hello there!", "https://httpbin.org/post")
postHTTP("this us a request with custom headers", "https://httpbin.org/post", {["X-am-I-awesome"] = "yep I am"})
postHTTP(nil, "https://httpbin.org/post", {}, "<fill in file location to upload here, maybe get from invokeFileDialog>")
-- This will create a JSON message body. Many modern REST APIs expect a JSON body. 
local url = "https://postman-echo.com/post"
local data = {message = "I am the banana", user = "admin"}
local header = {["Content-Type"] = "application/json"}

-- first we create something to handle the success, and tell us what we got
registerAnonymousEventHandler('sysPostHttpDone', function(event, rurl, response)
  if rurl == url then display(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires

-- then we create something to handle the error message, and tell us what went wrong
registerAnonymousEventHandler('sysPostHttpError', function(event, response, rurl)
  if rurl == url then display(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
end, true) -- this sets it to delete itself after it fires

-- Lastly, we make the request:
postHTTP(yajl.to_string(data), url, header) -- yajl.to_string converts our Lua table into a JSON-like string so the server can understand it

-- Pop this into an alias and try it yourself!
HTTP Basic Authentication Example

If your HTTP endpoint requires authentication to post data, HTTP Basic Authentication is a common method for doing so. There are two ways to do so.

OPTION 1: URL encoding: Many HTTP servers allow you to enter a HTTP Basic Authentication username and password at the beginning of the URL itself, in format: https://username:[email protected]/path/to/endpoint

OPTION 2: Authorization Header: Some HTTP servers may require you to put your Basic Authentication into the 'Authorization' HTTP header value.

This requires encoding the username:password into base64. For example, if your username is 'user' and your password is '12345', you'd need to run the string "user:12345" through a base64 encoder, which would result in the string: dXNlcjoxMjM0NQ==

Then, you'd need to set the HTTP header 'Authorization' field value to indicate it is using Basic auth and inserting the base64 string as: ['Authorization'] = "Basic dXNlcjoxMjM0NQ=="

As you're encoding your username and password, you probably want to do this encoding locally for security reasons. You also probably want to only use https:// and not http:// when sending usernames and passwords over the internet.

In the HTTP Basic Authentication example below, there is an inline base64Encode() function included:

function base64Encode(data)
  -- Lua 5.1+ base64 v3.0 (c) 2009 by Alex Kloss <[email protected]>
  -- licensed under the terms of the LGPL2
  local b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    return ((data:gsub('.', function(x) 
        local r,b='',x:byte()
        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
        return r;
    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
        if (#x < 6) then return '' end
        local c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
        return b:sub(c+1,c+1)
    end)..({ '', '==', '=' })[#data%3+1])
end
-- Example: base64Encode("user:12345") -> dXNlcjoxMjM0NQ== 

function postJSON(url,dataTable,headerTable)
  -- This will create a JSON message body. Many modern REST APIs expect a JSON body. 
  local data = dataTable or {text = "hello world"}
  local header = headerTable or {["Content-Type"] = "application/json"}
  -- first we create something to handle the success, and tell us what we got
  registerAnonymousEventHandler('sysPostHttpDone', function(event, rurl, response)
    if rurl == url then sL("HTTP response success"); echo(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
  end, true) -- this sets it to delete itself after it fires
  -- then we create something to handle the error message, and tell us what went wrong
  registerAnonymousEventHandler('sysPostHttpError', function(event, response, rurl)
    if rurl == url then sL("HTTP response error",3); echo(response) else return true end -- this will show us the response body, or if it's not the right url, then do not delete the handler
  end, true) -- this sets it to delete itself after it fires
  -- Lastly, we make the request:
  postHTTP(yajl.to_string(data), url, header) -- yajl.to_string converts our Lua table into a JSON-like string so the server can understand it
end

data = {
    message = "I am the banana",
    user = "admin"
}
header = {
    ["Content-Type"] = "application/json",
    ["Authorization"] = "Basic " .. base64Encode("user:12345")
}
postJSON("https://postman-echo.com/post",data,header)
URL Encoding vs JSON encoding

Some HTTP endpoints may not support JSON encoding, and instead may require URL encoding. Here's an example function to convert your lua data table into a URL encoded string::

-- Example: URLEncodeTable({message="hello",person="world"}) -> "message=hello&person=world"

function URLEncodeTable(Args)
  -- From: https://help.interfaceware.com/code/details/urlcode-lua
  ----------------------------------------------------------------------------
  -- URL-encode the elements of a table creating a string to be used in a
  -- URL for passing data/parameters to another script
  -- @param args Table where to extract the pairs (name=value).
  -- @return String with the resulting encoding.
  ----------------------------------------------------------------------------
  --
  local ipairs, next, pairs, tonumber, type = ipairs, next, pairs, tonumber, type
  local string = string
  local table = table
  
  --helper functions: 
  ----------------------------------------------------------------------------
  -- Decode an URL-encoded string (see RFC 2396)
  ----------------------------------------------------------------------------
  local unescape = function (str)
     str = string.gsub (str, "+", " ")
     str = string.gsub (str, "%%(%x%x)", function(h) return string.char(tonumber(h,16)) end)
     return str
  end
   
  ----------------------------------------------------------------------------
  -- URL-encode a string (see RFC 2396)
  ----------------------------------------------------------------------------
  local escape = function (str)
     str = string.gsub (str, "([^0-9a-zA-Z !'()*._~-])", -- locale independent
        function (c) return string.format ("%%%02X", string.byte(c)) end)
     str = string.gsub (str, " ", "+")
     return str
  end
   
  ----------------------------------------------------------------------------
  -- Insert a (name=value) pair into table [[args]]
  -- @param args Table to receive the result.
  -- @param name Key for the table.
  -- @param value Value for the key.
  -- Multi-valued names will be represented as tables with numerical indexes
  -- (in the order they came).
  ----------------------------------------------------------------------------
  local insertfield = function (args, name, value)
     if not args[name] then
        args[name] = value
     else
        local t = type (args[name])
        if t == "string" then
           args[name] = {args[name],value,}
        elseif t == "table" then
           table.insert (args[name], value)
        else
           error ("CGILua fatal error (invalid args table)!")
        end
     end
  end
  -- end helper functions 
    
  if Args == nil or next(Args) == nil then -- no args or empty args?
    return ""
  end
  local strp = ""
  for key, vals in pairs(Args) do
    if type(vals) ~= "table" then
       vals = {vals}
    end
    for i,val in ipairs(vals) do
       strp = strp.."&"..key.."="..escape(val)
    end
  end
  -- remove first &
  return string.sub(strp,2)
end

putHTTP

putHTTP(dataToSend, url, [headersTable], [file])
Sends an HTTP PUT request to the given URL, either as text or with a specific file you'd like to upload. Raises sysPutHttpDone on success or sysPutHttpError on failure.
See also: downloadFile(), getHTTP(), postHTTP(), deleteHTTP().
For privacy transparency, URLs accessed are logged in the Central Debug Console
Parameters
  • dataToSend:
Text to send in the request (unless you provide a file to upload).
  • url:
Location to send the request to.
  • headersTable:
(optional) table of headers to send with your request.
  • file:
(optional) file to upload as part of the PUT request. If provided, this will replace 'dataToSend'.
Mudlet VersionAvailable in Mudlet4.1+
Example
function onHttpPutDone(_, url, body)
  cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end

registerAnonymousEventHandler("sysPutHttpDone", onHttpPutDone)
putHTTP("this us a request with custom headers", "https://httpbin.org/put", {["X-am-I-awesome"] = "yep I am"})
putHTTP("https://httpbin.org/put", "<fill in file location to upload here>")

deleteHTTP

deleteHTTP(url, headersTable)
Sends an HTTP DELETE request to the given URL. Raises sysDeleteHttpDone on success or sysDeleteHttpError on failure.
See also: downloadFile(), getHTTP(), postHTTP(), putHTTP().
For privacy transparency, URLs accessed are logged in the Central Debug Console
Parameters
  • url:
Location to send the request to.
  • headersTable:
(optional) table of headers to send with your request.
Mudlet VersionAvailable in Mudlet4.1+
Example
function onHttpDeleteDone(_, url, body)
  cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s", url, body))
end

registerAnonymousEventHandler("sysDeleteHttpDone", onHttpDeleteDone)

deleteHTTP("https://httpbin.org/delete")
deleteHTTP("https://httpbin.org/delete", {["X-am-I-awesome"] = "yep I am"})

customHTTP

customHTTP(method, url, headersTable)
Sends an custom method request to the given URL. Raises sysCustomHttpDone on success or sysCustomHttpError on failure.
See also: downloadFile(), getHTTP(), postHTTP(), putHTTP(), deleteHTTP().
Parameters
  • method:
Http method to use (eg. PATCH, HEAD etc.)
  • dataToSend:
Text to send in the request (unless you provide a file to upload).
  • url:
Location to send the request to.
  • headersTable:
(optional) table of headers to send with your request.
  • file:
(optional) file to upload as part of the PUT request. If provided, this will replace 'dataToSend'.
Mudlet VersionAvailable in Mudlet4.11+
Example
function onCustomHttpDone(_, url, body, method)
  cecho(string.format("<white>url: <dark_green>%s<white>, body: <dark_green>%s<white>, method: <dark_green>%s", url, body, method))
end

registerAnonymousEventHandler("sysCustomHttpDone", sysCustomHttpDone)

customHTTP("PATCH", "this us a request with custom headers", "https://httpbin.org/put", {["X-am-I-awesome"] = "yep I am"})
customHTTP("PATCH", "https://httpbin.org/put", "<fill in file location to upload here>")

feedTelnet

feedTelnet(data)
Sends given binary data with some predefined special tokens converted to byte values, to the internal telnet engine, as if it had been received from the game. This is primarily to enable testing when new Telnet sub-options/protocols are being developed. The data has to be injected into the system nearer to the point where the Game Server's data starts out than feedTriggers() and unlike the latter the data is not subject to any encoding so as to match the current profile's setting (which normally happens with feedTriggers()). Furthermore - to prevent this function from putting the telnet engine into a state which could damage the processing of real game data it will refuse to work unless the Profile is completely disconnected from the game server.
See also
feedTriggers(), sendSocket()
Mudlet VersionAvailable in Mudlet4.18.0+

Note Note: This is not really intended for end-user's but might be useful in some circumstances.

Parameters
  • data
String containing the bytes to send to the internal telnet engine as if it had come from the Game Server, it can containing some tokens listed below that are to be converted to bytes as well.
Returns
  • Boolean true if the data string was sent to the internal telnet engine. nil and an error message otherwise, specifically the case when there is some traces of a connection or a complete connection to the socket that passes the data to and from the game server. Additionally, if the data is an empty string "" a second return value will be provided as an integer number representing a version for the table of tokens - which will be incremented each time a change is made to that table so that which tokens are valid can be determined. Note that unrecognised tokens should be passed through as is and not get replaced.
Token value table
Token Byte Version Notes
<00> \0x00 1 0 dec.
<O_BINARY> \0x00 1 Telnet option: Binary
<NUL> \0x00 1 ASCII control character: NULL
<01> \x01 1 1 dec.
<O_ECHO> \x01 1 Telnet option: Echo
<SOH> \x01 1 ASCII control character: Start of Heading
<02> \x02 1 2 dec. Telnet option: Reconnect
<STX> \x02 1 ASCII control character: Start of Text
<03> \x03 1 3 dec.
<O_SGA> \x03 1 Telnet option: Suppress Go Ahead
<ETX> \x03 1 ASCII control character: End of Text
<04> \x04 1 Telnet option: Approx Message Size Negotiation
<EOT> \x04 1 ASCII control character: End of Transmission
<05> \x05 1
<O_STATUS> \x05 1 Telnet option: Status
<ENQ> \x05 1 ASCII control character: Enquiry
<06> \x06 1 Telnet option: Timing Mark
<ACK> \x06 1 ASCII control character: Acknowledge
<07> \x07 1 Telnet option: Remote Controlled Trans and Echo
<BELL> \x07 1 ASCII control character: Bell
<08> \x08 1 Telnet option: Output Line Width
<BS> \x08 1 ASCII control character: Backspace
<09> \x09 1 Telnet option: Output Page Size
<HTAB> \x09 1 ASCII control character: Horizontal Tab
<0A> \x0a 1 Telnet option: Output Carriage-Return Disposition
<LF> \x0a 1 ASCII control character: Line-Feed
<0B> \x0b 1 Telnet option: Output Horizontal Tab Stops
<VTAB> \x0b 1 ASCII control character: Vertical Tab
<0C> \x0c 1 Telnet option: Output Horizontal Tab Disposition
<FF> \x0c 1 ASCII control character: Form-Feed
<0D> \x0d 1 Telnet option: Output Form-feed Disposition
<CR> \x0d 1 ASCII control character: Carriage-Return
<0E> \x0e 1 Telnet option: Output Vertical Tab Stops
<SO> \x0e 1 ASCII control character: Shift-Out
<0F> \x0f 1 Telnet option: Output Vertical Tab Disposition
<SI> \x0f 1 ASCII control character: Shift-In
<10> \x10 1 Telnet option: Output Linefeed Disposition
<DLE> \x10 1 ASCII control character: Data Link Escape
<11> \x11 1 Telnet option: Extended ASCII
<DC1> \x11 1 ASCII control character: Device Control 1
<12> \x12 1 Telnet option: Logout
<DC2" \x12 1 ASCII control character: Device Control 2
<13> \x13 1 Telnet option: Byte Macro
<DC3> \x13 1 ASCII control character: Device Control 3
<14> \x14 1 Telnet option: Data Entry Terminal
<DC4> \x14 1 ASCII control character: Device Control 4
<15> \x15 1 Telnet option: SUPDUP
<NAK> \x15 1 ASCII control character: Negative Acknowledge
<16> \x16 1 Telnet option: SUPDUP Output
<SYN> \x16 1 ASCII control character: Synchronous Idle
<17> \x17 1 Telnet option: Send location
<ETB> \x17 1 ASCII control character: End of Transmission Block
<18> \x18 1
<O_TERM> \x18 1 Telnet option: Terminal Type
<CAN> \x18 1 ASCII control character: Cancel
<19> \x19 1
<O_EOR> \x19 1 Telnet option: End-of-Record
<EM> \x19 1 ASCII control character: End of Medium
<1A> \x1a 1 Telnet option: TACACS User Identification
<SUB> \x1a 1 ASCII control character: Substitute
<1B> \x1b 1 Telnet option: Output Marking
<ESC> \x1b 1 ASCII control character: Escape
<1C> \x1c 1 Telnet option: Terminal Location Number
<FS> \x1c 1 ASCII control character: File Separator
<1D> \x1d 1 Telnet option: Telnet 3270 Regime
<GS> \x1d 1 ASCII control character: Group Separator
<1E> \x1e 1 Telnet option: X.3 PAD
<RS> \x1e 1 ASCII control character: Record Separator
<1F> \x1f 1
<O_NAWS> \x1f 1 Telnet option: Negotiate About Window Size
<US> \x1f 1 ASCII control character: Unit Separator
<SP> \x20 1 32 dec. ASCII character: Space
<O_NENV> \x27 1 39 dec. Telnet option: New Environment (also MNES)
<O_CHARS> \x2a 1 42 dec. Telnet option: Character Set
<O_KERMIT> \x2f 1 47 dec. Telnet option: Kermit
<O_MSDP> \x45 1 69 dec. Telnet option: Mud Server Data Protocol
<O_MSSP> \x46 1 70 dec. Telnet option: Mud Server Status Protocol
<O_MCCP> \x55 1 85 dec. Telnet option: Mud Client Compression Protocol
<O_MCCP2> \x56 1 86 dec. Telnet option: Mud Client Compression Protocol 2
<O_MSP> \x5a 1 90 dec. Telnet option: Mud Sound Protocol
<O_MXP> \x5b 1 91 dec. Telnet option: Mud eXtension Protocol
<O_ZENITH> \x5d 1 93 dec. Telnet option: Zenith Mud Protocol
<O_AARDWULF> \x66 1 102 dec. Telnet option: Aardwuld Data Protocol
<DEL> \x7f 1 127 dec. ASCII control character: Delete
<O_ATCP> \xc8 1 200 dec. Telnet option: Achaea Telnet Client Protocol
<O_GMCP> \xc9 1 201 dec. Telnet option: Generic Mud Communication Protocol
<T_EOR> \xef 1 239 dec. Telnet protocol: End Of Record
<F0> \xf0 1
<T_SE> \xf0 1 240 dec. Telnet protocol: End Of Sub Option
<F1> \xf1 1
<T_NOP> \xf1 1 241 dec. Telnet protocol: No Operation
<F2> \xf2 1
<T_DM> \xf2 1 242 dec. Telnet protocol: Data Mark
<F3> \xf3 1
<T_BRK> \xf3 1 243 dec. Telnet protocol: Break
<F4> \xf4 1
<T_IP> \xf4 1 244 dec. Telnet protocol: Interrupt Process
<F5> \xf5 1
<T_ABOP> \xf5 1 245 dec. Telnet protocol: Abort Output
<F6> \xf6 1
<T_AYT> \xf6 1 246 dec. Telnet protocol: Are You There?
<F7> \xf7 1
<T_EC> \xf7 1 247 dec. Telnet protocol: Erase Character
<F8> \xf8 1
<T_EL> \xf8 1 248 dec. Telnet protocol: Erase Line
<F9> \xf9 1
<T_GA> \xf9 1 249 dec. Telnet protocol: Go Ahead
<FA> \xfa 1
<T_SB> \xfa 1 250 dec. Telnet protocol: Start Of Sub Option
<FB> \xfb 1
<T_WILL> \xfb 1 251 dec. Telnet protocol: Sender Will Option
<FC> \xfc 1
<T_WONT> \xfc 1 252 dec. Telnet protocol: Sender Will Not Option
<FD> \xfd 1
<T_DO> \xfd 1 253 dec. Telnet protocol: Receiver To Do Option
<FE> \xfe 1
<T_DONT> \xfe 1 254 dec. Telnet protocol: Receiver Not To Do Option
<FF> \xff 1 Telnet option: Extended Option
<T_IAC> \xff 1 255 dec. Telnet protocol: Interpret (Next Byte) As (A Protocol) Command
Example
-- a comment explaining what is going on, if there is multiple functionalities (or optional parameters) the examples should start simple and progress in complexity if needed!
-- the examples should be small, but self-contained so new users can copy & paste immediately without going diving in lots other function examples first.
-- comments up top should introduce / explain what it does

local something = feedTelnet(exampleValue)
if something then
  -- do something with something (assuming there is a meaningful return value)
end

-- maybe another example for the optional second case
local somethingElse = function(exampleValue, anotherValue)

-- lastly, include an example with error handling to give an idea of good practice
local ok, err = function()
if not ok then
  debugc(f"Error: unable to do <particular thing> because {err}\n")
  return
end
Additional development notes

-- This function is still being written up.