Add @zones command to list registered zones

This commit is contained in:
Jared Miller 2026-02-14 22:23:51 -05:00
parent 7f6eda4be7
commit 938dd613d4
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
2 changed files with 149 additions and 1 deletions

View file

@ -8,7 +8,7 @@ from mudlib.player import Player, players
from mudlib.store import account_exists, load_player_data, set_admin
from mudlib.things import spawn_thing, thing_templates
from mudlib.zone import Zone
from mudlib.zones import get_zone, register_zone
from mudlib.zones import get_zone, register_zone, zone_registry
# Content directory, set during server startup
_content_dir: Path | None = None
@ -180,6 +180,24 @@ async def cmd_demote(player: Player, args: str) -> None:
await player.send(f"{target_name} is no longer an admin.\r\n")
async def cmd_zones(player: Player, args: str) -> None:
"""List all registered zones."""
if not zone_registry:
await player.send("No zones registered.\r\n")
return
await player.send("zones:\r\n")
current_zone_name = (
player.location.name if isinstance(player.location, Zone) else None
)
for name in sorted(zone_registry.keys()):
zone = zone_registry[name]
dimensions = f"{zone.width}x{zone.height}"
marker = " [here]" if name == current_zone_name else ""
await player.send(f" {name:<15} {dimensions:>6}{marker}\r\n")
register(CommandDefinition("@goto", cmd_goto, admin=True, help="Teleport to a zone"))
register(CommandDefinition("@dig", cmd_dig, admin=True, help="Create a new zone"))
register(CommandDefinition("@save", cmd_save, admin=True, help="Save current zone"))
@ -190,3 +208,4 @@ register(
register(
CommandDefinition("@demote", cmd_demote, admin=True, help="Revoke admin status")
)
register(CommandDefinition("@zones", cmd_zones, admin=True, help="List all zones"))

View file

@ -325,3 +325,132 @@ async def test_builder_commands_require_admin(zone, mock_writer, mock_reader):
mock_writer.write.assert_called()
written = mock_writer.write.call_args_list[-1][0][0]
assert "permission" in written.lower()
# --- @zones ---
@pytest.mark.asyncio
async def test_zones_lists_registered_zones(player):
"""@zones lists all registered zones."""
from mudlib.commands.build import cmd_zones
# Register additional zones
forest = Zone(
name="forest",
width=15,
height=12,
terrain=[["." for _ in range(15)] for _ in range(12)],
)
register_zone("forest", forest)
tavern = Zone(
name="tavern",
width=8,
height=6,
terrain=[["." for _ in range(8)] for _ in range(6)],
)
register_zone("tavern", tavern)
await cmd_zones(player, "")
# Check all zones are listed
all_output = "".join(call[0][0] for call in player.writer.write.call_args_list)
assert "hub" in all_output
assert "forest" in all_output
assert "tavern" in all_output
@pytest.mark.asyncio
async def test_zones_shows_dimensions(player):
"""@zones shows width x height for each zone."""
from mudlib.commands.build import cmd_zones
forest = Zone(
name="forest",
width=20,
height=15,
terrain=[["." for _ in range(20)] for _ in range(15)],
)
register_zone("forest", forest)
await cmd_zones(player, "")
all_output = "".join(call[0][0] for call in player.writer.write.call_args_list)
assert "10x10" in all_output # hub from fixture
assert "20x15" in all_output # forest
@pytest.mark.asyncio
async def test_zones_highlights_current_zone(player):
"""@zones marks the player's current zone."""
from mudlib.commands.build import cmd_zones
forest = Zone(
name="forest",
width=15,
height=12,
terrain=[["." for _ in range(15)] for _ in range(12)],
)
register_zone("forest", forest)
await cmd_zones(player, "")
all_output = "".join(call[0][0] for call in player.writer.write.call_args_list)
# hub should be marked as current (player is in hub via fixture)
assert "[here]" in all_output
# [here] should be on the same line as hub
hub_line_idx = all_output.find("hub")
here_idx = all_output.find("[here]")
assert hub_line_idx < here_idx < hub_line_idx + 50
@pytest.mark.asyncio
async def test_zones_empty_registry(zone, mock_writer, mock_reader):
"""@zones with no zones shows appropriate message."""
from mudlib.commands.build import cmd_zones
# Create player not in a zone fixture
zone_registry.clear()
temp_zone = Zone(
name="temp",
width=5,
height=5,
terrain=[["." for _ in range(5)] for _ in range(5)],
)
p = Player(
name="builder",
x=0,
y=0,
writer=mock_writer,
reader=mock_reader,
location=temp_zone,
is_admin=True,
)
await cmd_zones(p, "")
mock_writer.write.assert_called()
written = mock_writer.write.call_args_list[0][0][0]
assert "no zones" in written.lower()
@pytest.mark.asyncio
async def test_zones_requires_admin(zone, mock_writer, mock_reader):
"""Non-admin players cannot use @zones."""
from mudlib.commands import dispatch
non_admin = Player(
name="player",
x=5,
y=5,
writer=mock_writer,
reader=mock_reader,
location=zone,
is_admin=False,
)
await dispatch(non_admin, "@zones")
mock_writer.write.assert_called()
written = mock_writer.write.call_args_list[-1][0][0]
assert "permission" in written.lower()