6.9 KiB
Chat System
The chat system provides comprehensive channel-based communication for EverQuest II server emulation, converted from the original C++ EQ2EMu implementation.
Overview
The chat system manages multiple chat channels with membership, access control, and message routing capabilities. It supports both persistent world channels (loaded from database) and temporary custom channels (created by players).
Architecture
Core Components
ChatManager - Main chat system coordinator managing multiple channels
Channel - Individual channel implementation with membership and messaging
ChatService - High-level service interface for chat operations
DatabaseChannelManager - Database persistence layer for world channels
Key Features
- Channel Types: World (persistent) and Custom (temporary) channels
- Access Control: Level, race, and class restrictions with bitmask filtering
- Password Protection: Optional password protection for channels
- Language Integration: Multilingual chat processing with language comprehension
- Discord Integration: Optional Discord webhook bridge for specific channels
- Thread Safety: All operations use proper Go concurrency patterns
Channel Types
World Channels
- Persistent channels loaded from database at server startup
- Cannot be deleted by players
- Configured with access restrictions (level, race, class)
- Examples: "Auction", "Level_1-9", "Trade"
Custom Channels
- Created dynamically by players
- Automatically deleted when empty for 5+ minutes
- Support optional password protection
- Player-controlled membership
Database Schema
CREATE TABLE channels (
name TEXT PRIMARY KEY,
password TEXT,
level_restriction INTEGER NOT NULL DEFAULT 0,
classes INTEGER NOT NULL DEFAULT 0,
races INTEGER NOT NULL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Access Control
Level Restrictions
- Minimum level required to join channel
- 0 = no level restriction
Race Restrictions (Bitmask)
- Bit position corresponds to race ID
- 0 = all races allowed
- Example:
(1 << raceID) & raceMask
checks if race is allowed
Class Restrictions (Bitmask)
- Bit position corresponds to class ID
- 0 = all classes allowed
- Example:
(1 << classID) & classMask
checks if class is allowed
Usage Examples
Basic Operations
// Initialize chat service
service := NewChatService(database, clientManager, playerManager, languageProcessor)
err := service.Initialize(ctx)
// Create custom channel
err := service.CreateChannel("MyChannel", "password123")
// Join channel
err := service.JoinChannel(characterID, "MyChannel", "password123")
// Send message
err := service.SendChannelMessage(characterID, "MyChannel", "Hello everyone!")
// Leave channel
err := service.LeaveChannel(characterID, "MyChannel")
Channel Commands
// Process channel command from client
err := service.ProcessChannelCommand(characterID, "join", "Auction")
err := service.ProcessChannelCommand(characterID, "tell", "Auction", "WTS", "Epic", "Sword")
err := service.ProcessChannelCommand(characterID, "who", "Auction")
err := service.ProcessChannelCommand(characterID, "leave", "Auction")
Admin Operations
// Get channel statistics
stats := service.GetStatistics()
fmt.Printf("Total channels: %d, Active: %d\n", stats.TotalChannels, stats.ActiveChannels)
// Broadcast system message
err := service.BroadcastSystemMessage("Auction", "Server restart in 10 minutes", "System")
// Cleanup empty channels
removed := service.CleanupEmptyChannels()
Integration Interfaces
ClientManager
Handles client communication for channel lists, messages, and updates.
PlayerManager
Provides player information for access control and message routing.
LanguageProcessor
Processes multilingual messages with language comprehension checks.
ChannelDatabase
Manages persistent storage of world channels and configuration.
Protocol Integration
Packet Types
WS_AvailWorldChannels
- Channel list for clientWS_ChatChannelUpdate
- Join/leave notificationsWS_HearChat
- Channel message deliveryWS_WhoChannelQueryReply
- User list responses
Channel Actions
CHAT_CHANNEL_JOIN
(0) - Player joins channelCHAT_CHANNEL_LEAVE
(1) - Player leaves channelCHAT_CHANNEL_OTHER_JOIN
(2) - Another player joinsCHAT_CHANNEL_OTHER_LEAVE
(3) - Another player leaves
Language Support
The chat system integrates with the language system for multilingual communication:
- Messages are processed based on sender's default language
- Recipients receive scrambled text for unknown languages
- Language comprehension is checked per message
- Proper language ID tracking for all communications
Discord Integration (Optional)
Channels can be configured for Discord webhook integration:
- Bidirectional chat bridge (EQ2 ↔ Discord)
- Configurable per channel via rules system
- Webhook-based implementation for simplicity
- Server name and character name formatting
Thread Safety
All operations are thread-safe using:
sync.RWMutex
for read/write operations- Atomic operations where appropriate
- Proper locking hierarchies to prevent deadlocks
- Channel-level and manager-level synchronization
Performance Considerations
- Channel lookups use case-insensitive maps
- Member lists use slices with efficient removal
- Read operations use read locks for concurrency
- Database operations are context-aware with timeouts
Error Handling
The system provides comprehensive error handling:
- Channel not found errors
- Access denied errors (level/race/class restrictions)
- Password validation errors
- Database connection errors
- Language processing errors
Future Enhancements
Areas marked for future implementation:
- Advanced Discord bot integration
- Channel moderation features
- Message history and logging
- Channel-specific emote support
- Advanced filtering and search
- Cross-server channel support
File Structure
internal/chat/
├── README.md # This documentation
├── constants.go # Channel constants and limits
├── types.go # Core data structures
├── interfaces.go # Integration interfaces
├── chat.go # Main ChatManager implementation
├── channel.go # Channel implementation
├── database.go # Database operations
├── manager.go # High-level ChatService
└── channel/
└── channel.go # Standalone channel package
Dependencies
eq2emu/internal/database
- Database wrappereq2emu/internal/languages
- Language processing- Standard library:
context
,sync
,strings
,time
Testing
The chat system is designed for comprehensive testing:
- Mock interfaces for all dependencies
- Isolated channel testing
- Concurrent operation testing
- Database integration testing
- Error condition testing