evennia.server.portal.gmcp_utils

Shared GMCP (Generic MUD Communication Protocol) utilities.

This module provides encoding and decoding functions for GMCP messages, shared between telnet OOB and WebSocket wire format implementations.

GMCP messages follow the format: “Package.Subpackage json_payload”

The mapping dictionaries translate between Evennia’s internal command names and standard GMCP package names.

evennia.server.portal.gmcp_utils.encode_gmcp(cmdname, *args, **kwargs)[source]

Encode an Evennia command into a GMCP message string.

Parameters:
  • cmdname (str) – Evennia OOB command name.

  • *args – Command arguments.

  • **kwargs – Command keyword arguments.

Returns:

str – A GMCP-formatted string like “Package.Name json_data”

Notes

GMCP messages are formatted as:

[cmdname, [], {}] -> Cmd.Name [cmdname, [arg], {}] -> Cmd.Name arg [cmdname, [args], {}] -> Cmd.Name [args] [cmdname, [], {kwargs}] -> Cmd.Name {kwargs} [cmdname, [arg], {kwargs}] -> Cmd.Name [arg, {kwargs}] [cmdname, [args], {kwargs}] -> Cmd.Name [[args], {kwargs}]

Note: When there is exactly one positional argument, it is collapsed (encoded directly rather than wrapped in a list). This applies both with and without keyword arguments. This is inherited behavior from the original telnet_oob.py.

If cmdname has a direct mapping in EVENNIA_TO_GMCP, that mapped name is used. Otherwise, underscores are converted to dots with initial capitalization. Names without underscores are placed in the Core package.

evennia.server.portal.gmcp_utils.decode_gmcp(data)[source]

Decode a GMCP message string into Evennia command format.

Parameters:

data (str or bytes) – GMCP data in the form “Module.Submodule.Cmdname structure”. Bytes input is decoded as UTF-8.

Returns:

dict

A dict suitable for data_in(), e.g. **{“cmdname”: [[args], {kwargs}]}**.

Returns empty dict if data is empty or cannot be parsed.

Notes

Incoming GMCP is parsed as:

Core.Name                         -> {"name": [[], {}]}
Core.Name "string"                -> {"name": [["string"], {}]}
Core.Name [arg, arg, ...]         -> {"name": [[args], {}]}
Core.Name {key:val, ...}          -> {"name": [[], {kwargs}]}
Core.Name [[args], {kwargs}]      -> {"name": [[args], {kwargs}]}

Non-JSON payloads (plain strings that aren’t valid JSON) are wrapped as a single-element list: **{“name”: [[“the string”], {}]}**. This differs from the previous **telnet_oob.py** implementation which would split plain strings into individual characters due to **list(“string”)** being iterable.