From 7f6eda4be7a78b508def7cbd23353103e592aba6 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Sat, 14 Feb 2026 22:23:37 -0500 Subject: [PATCH] Add help zones guide topic --- src/mudlib/commands/help.py | 48 +++++++++++++++++++++++++++++++++++++ tests/test_help_command.py | 41 +++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/mudlib/commands/help.py b/src/mudlib/commands/help.py index f1d834f..e425dbe 100644 --- a/src/mudlib/commands/help.py +++ b/src/mudlib/commands/help.py @@ -354,6 +354,30 @@ async def cmd_client(player: Player, args: str) -> None: await player.send("\r\n".join(lines) + "\r\n") +async def cmd_zones_help(player: Player, args: str) -> None: + """Show the zones guide.""" + lines = [ + "zones", + " zones are spatial containers - rooms, dungeons, overworld areas.", + " each zone has a terrain grid, spawn point, and optional portals.", + "", + " listing zones", + " @zones list all registered zones", + "", + " navigating", + " @goto teleport to a zone's spawn point", + " enter step through a portal to another zone", + "", + " building", + " @dig create a new blank zone", + " @paint toggle paint mode for terrain editing", + " @save save current zone to file", + "", + " see: @zones, @goto, @dig, @paint, @save", + ] + await player.send("\r\n".join(lines) + "\r\n") + + # Register the commands command register( CommandDefinition( @@ -387,6 +411,18 @@ register( ) ) +# Register the zones help topic +register( + CommandDefinition( + "zones", + cmd_zones_help, + mode="*", + hidden=True, + admin=True, + help="zone building guide", + ) +) + async def cmd_help(player: Player, args: str) -> None: """Show help for a command or skill. @@ -401,6 +437,18 @@ async def cmd_help(player: Player, args: str) -> None: "type help for details. see also: commands, skills, client\r\n" ) return + + # Check if this is a help topic (hidden command) + defn = _registry.get(args) + if defn is not None and defn.hidden: + # Check admin permission for admin-only topics + if defn.admin and not player.is_admin: + await player.send(f"Unknown command: {args}\r\n") + return + # Execute the help topic directly + await defn.handler(player, "") + return + await _show_command_detail(player, args) diff --git a/tests/test_help_command.py b/tests/test_help_command.py index 2d7fad7..2dd3119 100644 --- a/tests/test_help_command.py +++ b/tests/test_help_command.py @@ -34,6 +34,15 @@ def player(mock_reader, mock_writer): return Player(name="TestPlayer", x=5, y=5, reader=mock_reader, writer=mock_writer) +@pytest.fixture +def admin_player(mock_reader, mock_writer): + from mudlib.player import Player + + p = Player(name="AdminPlayer", x=5, y=5, reader=mock_reader, writer=mock_writer) + p.is_admin = True + return p + + @pytest.mark.asyncio async def test_help_command_is_registered(): """The help command should be registered in the command registry.""" @@ -82,3 +91,35 @@ async def test_help_and_commands_both_exist(): assert "commands" in commands._registry # They should be different functions assert commands._registry["help"].handler != commands._registry["commands"].handler + + +@pytest.mark.asyncio +async def test_help_zones_shows_guide(admin_player): + """help zones shows zone guide text with command references.""" + await commands.dispatch(admin_player, "help zones") + output = "".join([call[0][0] for call in admin_player.writer.write.call_args_list]) + assert "zones" in output + assert "@zones" in output + assert "@goto" in output + assert "@dig" in output + assert "@paint" in output + assert "@save" in output + + +@pytest.mark.asyncio +async def test_help_zones_shows_see_also(admin_player): + """help zones output contains see also cross-references.""" + await commands.dispatch(admin_player, "help zones") + output = "".join([call[0][0] for call in admin_player.writer.write.call_args_list]) + assert "see:" in output + + +@pytest.mark.asyncio +async def test_help_zones_requires_admin(player): + """Non-admin players cannot see admin help topics.""" + # Import build to ensure @zones help topic is registered + from mudlib.commands import build # noqa: F401 + + await commands.dispatch(player, "help zones") + output = "".join([call[0][0] for call in player.writer.write.call_args_list]) + assert "unknown" in output.lower()