Chat and Messaging
Relevant source files
The following files were used as context for generating this wiki page:
The Chat and Messaging system in Athena is a core component responsible for handling real-time communication between users, including public channels, private messages (PMs), and automated system responses via BanchoBot. It is designed as a layered architecture within a modular monolith, utilizing hexagonal adapters to separate business logic from transport-specific protocols like the stable osu! Bancho binary protocol.
The system manages message delivery, authorization via role-based access control (RBAC), rate limiting, and persistence. It leverages a Command/Query Responsibility Segregation (CQRS) approach where state-changing workflows (e.g., sending a message) are handled by command services, while read-only views (e.g., resolving channel members) are handled by query services.
Sources: README.md, AGENTS.md:144-152, src/osu_server/domain/chat/init.py
Domain Models and Architecture
The chat domain is built upon standard Python dataclasses to ensure transport independence. Key entities include ChatSender, ChatDestination (specialized for channels or private messages), and ChatAuthorization.
Core Data Structures
| Class | Description | Fields |
|---|---|---|
ChatSender | Represents the originator of a message. | user_id: int, username: str |
ChannelChatDestination | Target for public channel messages. | name: str |
PrivateChatDestination | Target for user-to-user messages. | username: str |
ChatAuthorization | Encapsulates sender permissions for the action. | privileges: int, role_ids: tuple[int, ...] |
ChannelMessageResult | Outcome of a channel message delivery. | delivered_to: set[int] | None, content: str, command_responses: tuple |
PrivateMessageResult | Outcome of a PM delivery attempt. | target_id: int | None, is_online: bool, delivery_status |
Sources: src/osu_server/domain/chat/init.py:31-97
Entity Relationships
The following diagram illustrates the relationship between chat models and their persistence/delivery status.
Channel Management
Channels are defined by the Channel dataclass and categorized by ChannelType. The system supports standard public channels as well as reserved types for specific game states.
Channel Types
- PUBLIC: Standard chat rooms accessible by users.
- MULTIPLAYER: Reserved for multiplayer match rooms.
- SPECTATOR: Reserved for spectator-specific chat.
- TEMPORARY: Transient channels for specific events.
Sources: src/osu_server/domain/chat/channels.py:16-25
Access Control
Access to channels is governed by ChannelRoleOverride, which allows for fine-grained permissions (read/write) based on a user's role.
Message Processing Flow
The processing of a message involves several stages: validation, authorization, rate limiting, delivery resolution, and persistence publishing.
Channel Message Pipeline
- Input Validation: Checks for empty content or content exceeding
message_max_length. - State Check: Verifies the user is not silenced via
SessionData.silence_end. - Rate Limiting: Checks against configured
rate_limit_messagesandrate_limit_window. - Authorization: Resolves delivery targets and checks if the sender has
can_writepermissions orBYPASS_CHANNEL_ACLprivileges. - BanchoBot Interaction: Scans for commands (e.g.,
!roll) and generates automated responses. - Persistence: Publishes the message to a background worker for durable storage.
Sources: src/osu_server/services/commands/chat/send_channel_message.py:44-118, tests/integration/test_chat_pipeline.py:270-305
Flow Diagram: Sending a Channel Message
Private Messaging and Friend Policies
Private messages (PMs) include additional logic to respect user privacy settings and friend lists. The PrivateMessageDeliveryStatus enum tracks why a message might not reach its target.
PM Delivery Constraints
- Target Not Found: The destination username does not exist.
- Offline: The target user exists but has no active session.
- Friend Only: The target has enabled "PM from friends only," and the sender is not in their friend list.
Sources: src/osu_server/domain/chat/init.py:21-27, tests/integration/test_chat_pipeline.py:339-364
Sequence Diagram: PM Delivery with Friend Check
Persistence and Background Jobs
Athena follows a "Two-Process Model." Immediate chat delivery happens in the app process (uvicorn), while heavy processing and persistence are offloaded to a worker process via taskiq.
- Persistence Publisher: The
ChatPersistenceWorkPublisherinterface (implemented byTaskiqChatPersistenceWorkPublisher) sendsChannelMessagePersistenceWorkorPrivateMessagePersistenceWorkto the queue. - Persistence Failures: If the worker cannot write to the database, it reports a
ChatPersistenceFailureReasonsuch asCHANNEL_NOT_FOUNDorSTORAGE_ERROR.
Sources: AGENTS.md:275-278, src/osu_server/domain/chat/init.py:12-18, src/osu_server/services/commands/chat/send_channel_message.py:114-118
BanchoBot and Commands
BanchoBot is a system user (BANCHO_BOT_IDENTITY) that provides automated utility. It interacts with the chat system through a CommandService.
- Identity: BanchoBot always has
user_id=1. - Built-in Commands: Includes
!rolland!help. - Bypass Rules: BanchoBot responses often bypass "friend-only" DM restrictions to ensure system messages reach users.
Sources: tests/integration/test_chat_pipeline.py:399-425, tests/integration/test_chat_e2e.py:236-335
Conclusion
The Chat and Messaging module provides a robust foundation for osu! private server communication. By strictly separating domain logic from transport layers and utilizing asynchronous background persistence, Athena ensures that real-time chat remains performant even as external compatibility requirements evolve. The integration of role-based access control and privacy policies ensures a secure and user-centric messaging experience.