mud/src/mudlib/commands/__init__.py

71 lines
1.8 KiB
Python

"""Command registry and dispatcher."""
from collections.abc import Awaitable, Callable
from dataclasses import dataclass, field
from mudlib.player import Player
# Type alias for command handlers
CommandHandler = Callable[[Player, str], Awaitable[None]]
@dataclass
class CommandDefinition:
"""Metadata wrapper for a registered command."""
name: str
handler: CommandHandler
aliases: list[str] = field(default_factory=list)
mode: str = "normal"
help: str = ""
hidden: bool = False
# Registry maps command names to definitions
_registry: dict[str, CommandDefinition] = {}
def register(defn: CommandDefinition) -> None:
"""Register a command definition with its aliases.
Args:
defn: The command definition to register
"""
_registry[defn.name] = defn
for alias in defn.aliases:
_registry[alias] = defn
async def dispatch(player: Player, raw_input: str) -> None:
"""Parse input, find command, call handler.
Args:
player: The player executing the command
raw_input: The raw input string from the player
"""
raw_input = raw_input.strip()
if not raw_input:
return
# Split into command and arguments
parts = raw_input.split(maxsplit=1)
command = parts[0].lower()
args = parts[1] if len(parts) > 1 else ""
# Look up the definition
defn = _registry.get(command)
if defn is None:
player.writer.write(f"Unknown command: {command}\r\n")
await player.writer.drain()
return
# Check mode restriction
if defn.mode != "*" and defn.mode != player.mode:
player.writer.write("You can't do that right now.\r\n")
await player.writer.drain()
return
# Execute the handler
await defn.handler(player, args)