Parses MTTS bitfield values from telnetlib3 ttype3 into a ClientCaps dataclass. Includes color_depth property that returns the best available color mode (truecolor, 256, or 16) based on client capabilities.
90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
"""MTTS (Mud Terminal Type Standard) capability parsing.
|
|
|
|
Parses MTTS bitfield values from telnetlib3's ttype3 into a structured dataclass.
|
|
MTTS is advertised via TTYPE round 3 as "MTTS <number>" where the number is a
|
|
bitfield of client capabilities.
|
|
|
|
See docs/lessons/charset-vs-mtts.txt for protocol details.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Literal
|
|
|
|
|
|
@dataclass
|
|
class ClientCaps:
|
|
"""Parsed client capabilities from MTTS bitfield."""
|
|
|
|
ansi: bool = False
|
|
vt100: bool = False
|
|
utf8: bool = False
|
|
colors_256: bool = False
|
|
mouse_tracking: bool = False
|
|
osc_color_palette: bool = False
|
|
screen_reader: bool = False
|
|
proxy: bool = False
|
|
truecolor: bool = False
|
|
mnes: bool = False
|
|
mslp: bool = False
|
|
ssl: bool = False
|
|
|
|
@property
|
|
def color_depth(self) -> Literal["truecolor", "256", "16"]:
|
|
"""Return best available color mode: truecolor, 256, or 16."""
|
|
if self.truecolor:
|
|
return "truecolor"
|
|
if self.colors_256:
|
|
return "256"
|
|
return "16"
|
|
|
|
|
|
def parse_mtts(ttype3: str | None) -> ClientCaps:
|
|
"""Parse MTTS capability string into ClientCaps dataclass.
|
|
|
|
Args:
|
|
ttype3: String from writer.get_extra_info("ttype3"), e.g., "MTTS 2825"
|
|
|
|
Returns:
|
|
ClientCaps with parsed capabilities. Returns defaults for
|
|
None/empty/invalid input.
|
|
|
|
Bit values from MTTS spec (tintin.mudhalla.net/protocols/mtts/):
|
|
Bit 0 (1) = ANSI
|
|
Bit 1 (2) = VT100
|
|
Bit 2 (4) = UTF-8
|
|
Bit 3 (8) = 256 COLORS
|
|
Bit 4 (16) = MOUSE TRACKING
|
|
Bit 5 (32) = OSC COLOR PALETTE
|
|
Bit 6 (64) = SCREEN READER
|
|
Bit 7 (128) = PROXY
|
|
Bit 8 (256) = TRUECOLOR
|
|
Bit 9 (512) = MNES
|
|
Bit 10 (1024) = MSLP
|
|
Bit 11 (2048) = SSL
|
|
"""
|
|
if not ttype3:
|
|
return ClientCaps()
|
|
|
|
parts = ttype3.split()
|
|
if len(parts) != 2 or parts[0] != "MTTS":
|
|
return ClientCaps()
|
|
|
|
try:
|
|
value = int(parts[1])
|
|
except ValueError:
|
|
return ClientCaps()
|
|
|
|
return ClientCaps(
|
|
ansi=bool(value & 1),
|
|
vt100=bool(value & 2),
|
|
utf8=bool(value & 4),
|
|
colors_256=bool(value & 8),
|
|
mouse_tracking=bool(value & 16),
|
|
osc_color_palette=bool(value & 32),
|
|
screen_reader=bool(value & 64),
|
|
proxy=bool(value & 128),
|
|
truecolor=bool(value & 256),
|
|
mnes=bool(value & 512),
|
|
mslp=bool(value & 1024),
|
|
ssl=bool(value & 2048),
|
|
)
|