feat: add /bridge/stats endpoint, go/emote MUD commands
- /bridge/stats returns uptime, sessions, messages, rooms, WS connections - 'go <room>' moves user between rooms via HTTP (was WS-only) - 'emote <action>' broadcasts third-person action to room occupants - Both commands notify other room occupants via room_events
This commit is contained in:
@@ -275,6 +275,7 @@ class MultiUserBridge:
|
||||
self._app.router.add_get("/bridge/sessions", self.handle_sessions)
|
||||
self._app.router.add_get("/bridge/health", self.handle_health)
|
||||
self._app.router.add_get("/bridge/rooms", self.handle_rooms)
|
||||
self._app.router.add_get("/bridge/stats", self.handle_stats)
|
||||
self._app.router.add_get("/bridge/room_events/{user_id}", self.handle_room_events)
|
||||
self._app.router.add_get("/bridge/ws/{user_id}", self.handle_ws)
|
||||
return self._app
|
||||
@@ -319,6 +320,23 @@ class MultiUserBridge:
|
||||
"total_users": self.sessions.active_count,
|
||||
})
|
||||
|
||||
async def handle_stats(self, request: web.Request) -> web.Response:
|
||||
"""GET /bridge/stats — Aggregate bridge statistics."""
|
||||
uptime = time.time() - self._start_time
|
||||
total_messages = sum(len(s.message_history) for s in self.sessions._sessions.values())
|
||||
total_commands = sum(s.command_count for s in self.sessions._sessions.values())
|
||||
rooms = {r: len(users) for r, users in self.sessions._room_occupants.items() if users}
|
||||
ws_connections = sum(len(s.ws_connections) for s in self.sessions._sessions.values())
|
||||
return web.json_response({
|
||||
"uptime_seconds": round(uptime, 1),
|
||||
"active_sessions": self.sessions.active_count,
|
||||
"total_messages": total_messages,
|
||||
"total_commands": total_commands,
|
||||
"rooms": rooms,
|
||||
"room_count": len(rooms),
|
||||
"ws_connections": ws_connections,
|
||||
})
|
||||
|
||||
async def handle_room_events(self, request: web.Request) -> web.Response:
|
||||
"""GET /bridge/room_events/{user_id} — Drain pending room events for a user."""
|
||||
user_id = request.match_info["user_id"]
|
||||
@@ -512,7 +530,53 @@ class MultiUserBridge:
|
||||
other_session = self.sessions.get(other_id)
|
||||
if other_session:
|
||||
other_session.room_events.append(broadcast)
|
||||
return f'You say: "{speech}"'
|
||||
return f'You say: \"{speech}\"'
|
||||
|
||||
if msg_lower.startswith("go ") or msg_lower.startswith("move "):
|
||||
# Move to a new room (HTTP equivalent of WS move)
|
||||
parts = message.split(None, 1)
|
||||
if len(parts) < 2 or not parts[1].strip():
|
||||
return "Go where? Usage: go <room>"
|
||||
new_room = parts[1].strip()
|
||||
old_room = session.room
|
||||
if new_room == old_room:
|
||||
return f"You're already in {new_room}."
|
||||
# Update room tracking
|
||||
self.sessions._room_occupants[old_room].discard(session.user_id)
|
||||
session.room = new_room
|
||||
self.sessions._room_occupants[new_room].add(session.user_id)
|
||||
# Notify occupants in old room
|
||||
old_occupants = self.sessions.get_room_occupants(old_room)
|
||||
for other_id in old_occupants:
|
||||
other_session = self.sessions.get(other_id)
|
||||
if other_session:
|
||||
other_session.room_events.append({
|
||||
"type": "room_broadcast",
|
||||
"from_user": session.user_id,
|
||||
"from_username": session.username,
|
||||
"room": old_room,
|
||||
"message": f"{session.username} leaves for {new_room}.",
|
||||
})
|
||||
return f"You leave {old_room} and arrive in {new_room}."
|
||||
|
||||
if msg_lower.startswith("emote ") or msg_lower.startswith("/me "):
|
||||
# Emote — broadcast action to room
|
||||
action = message.split(None, 1)[1] if len(message.split(None, 1)) > 1 else ""
|
||||
if not action:
|
||||
return "Emote what? Usage: emote <action>"
|
||||
occupants = self.sessions.get_room_occupants(session.room)
|
||||
others = [o for o in occupants if o != session.user_id]
|
||||
for other_id in others:
|
||||
other_session = self.sessions.get(other_id)
|
||||
if other_session:
|
||||
other_session.room_events.append({
|
||||
"type": "room_broadcast",
|
||||
"from_user": session.user_id,
|
||||
"from_username": session.username,
|
||||
"room": session.room,
|
||||
"message": f"{session.username} {action}",
|
||||
})
|
||||
return f"You {action}"
|
||||
|
||||
if msg_lower == "who":
|
||||
all_sessions = self.sessions.list_sessions()
|
||||
|
||||
Reference in New Issue
Block a user