Fix IF session cleanup on failure and player disconnect
This commit is contained in:
parent
8a8e3dd6e8
commit
6308248d14
4 changed files with 11 additions and 2 deletions
|
|
@ -39,9 +39,11 @@ async def cmd_play(player: Player, args: str) -> None:
|
||||||
try:
|
try:
|
||||||
intro = await session.start()
|
intro = await session.start()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
await session.stop()
|
||||||
await player.send("error: dfrotz not found. cannot play IF games.\r\n")
|
await player.send("error: dfrotz not found. cannot play IF games.\r\n")
|
||||||
return
|
return
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
await session.stop()
|
||||||
await player.send(f"error starting game: {e}\r\n")
|
await player.send(f"error starting game: {e}\r\n")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,10 @@ class IFSession:
|
||||||
async def handle_input(self, text: str) -> IFResponse:
|
async def handle_input(self, text: str) -> IFResponse:
|
||||||
"""Handle player input. Route to dfrotz or handle escape commands."""
|
"""Handle player input. Route to dfrotz or handle escape commands."""
|
||||||
# Check for escape commands (:: prefix)
|
# Check for escape commands (:: prefix)
|
||||||
if text == "::quit":
|
if text.lower() == "::quit":
|
||||||
return IFResponse(output="", done=True)
|
return IFResponse(output="", done=True)
|
||||||
|
|
||||||
if text == "::help":
|
if text.lower() == "::help":
|
||||||
help_text = """escape commands:
|
help_text = """escape commands:
|
||||||
::quit - exit the game
|
::quit - exit the game
|
||||||
::help - show this help"""
|
::help - show this help"""
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,9 @@ async def shell(
|
||||||
if _writer.is_closing():
|
if _writer.is_closing():
|
||||||
break
|
break
|
||||||
finally:
|
finally:
|
||||||
|
# Clean up IF session if player was playing
|
||||||
|
if player.if_session:
|
||||||
|
await player.if_session.stop()
|
||||||
# Save player state on disconnect (if not already saved by quit command)
|
# Save player state on disconnect (if not already saved by quit command)
|
||||||
if player_name in players:
|
if player_name in players:
|
||||||
save_player(player)
|
save_player(player)
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ async def test_play_handles_dfrotz_missing(player):
|
||||||
# Mock IFSession to raise FileNotFoundError on start
|
# Mock IFSession to raise FileNotFoundError on start
|
||||||
mock_session = Mock()
|
mock_session = Mock()
|
||||||
mock_session.start = AsyncMock(side_effect=FileNotFoundError())
|
mock_session.start = AsyncMock(side_effect=FileNotFoundError())
|
||||||
|
mock_session.stop = AsyncMock()
|
||||||
|
|
||||||
with patch("mudlib.commands.play.IFSession") as MockIFSession:
|
with patch("mudlib.commands.play.IFSession") as MockIFSession:
|
||||||
MockIFSession.return_value = mock_session
|
MockIFSession.return_value = mock_session
|
||||||
|
|
@ -114,3 +115,6 @@ async def test_play_handles_dfrotz_missing(player):
|
||||||
|
|
||||||
# Verify session was NOT attached
|
# Verify session was NOT attached
|
||||||
assert player.if_session is None
|
assert player.if_session is None
|
||||||
|
|
||||||
|
# Verify session.stop() was called
|
||||||
|
mock_session.stop.assert_called_once()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue