/* Package babble is the active record implementation for global chat messages in the game. Babble represents the global chat system where players can communicate with each other in real-time. The package provides comprehensive chat message management with features like mentions, search, time-based queries, and moderation utilities. # Basic Usage To retrieve a babble message by ID: message, err := babble.Find(db, 1) if err != nil { log.Fatal(err) } fmt.Printf("<%s> %s\n", message.Author, message.Babble) To get all babble messages: allMessages, err := babble.All(db) if err != nil { log.Fatal(err) } for _, message := range allMessages { fmt.Printf("[%s] <%s> %s\n", message.PostedTime().Format("15:04"), message.Author, message.Babble) } To get recent chat messages: recentChat, err := babble.Recent(db, 50) if err != nil { log.Fatal(err) } To filter messages by author: userMessages, err := babble.ByAuthor(db, "PlayerName") if err != nil { log.Fatal(err) } # Creating Messages with Builder Pattern The package provides a fluent builder interface for creating new chat messages: message, err := babble.NewBuilder(db). WithAuthor("PlayerName"). WithBabble("Hello everyone! Ready for some adventure?"). WithPostedTime(time.Now()). Create() if err != nil { log.Fatal(err) } fmt.Printf("Posted message with ID: %d\n", message.ID) The builder automatically sets the current time if no posted time is specified: message, err := babble.NewBuilder(db). WithAuthor("Admin"). WithMessage("Server restart in 5 minutes!"). Create() // Uses current timestamp You can use either `WithBabble()` or `WithMessage()` - they are aliases for the same functionality. # Updating Messages Chat messages can be modified and saved back to the database: message, _ := babble.Find(db, 1) message.Babble = "[EDITED] Original message was inappropriate" err := message.Save() if err != nil { log.Fatal(err) } # Deleting Messages Messages can be removed from the database (for moderation): message, _ := babble.Find(db, 1) err := message.Delete() if err != nil { log.Fatal(err) } # Database Schema The babble table has the following structure: CREATE TABLE babble ( id INTEGER PRIMARY KEY AUTOINCREMENT, posted INTEGER NOT NULL DEFAULT (unixepoch()), author TEXT NOT NULL DEFAULT '', babble TEXT NOT NULL DEFAULT '' ) Where: - id: Unique identifier for the chat message - posted: Unix timestamp when the message was posted - author: Username of the player who posted the message - babble: The text content of the chat message # Time-Based Queries ## Recent Messages Get the most recent chat messages: // Get 100 most recent messages for chat display chatHistory, err := babble.Recent(db, 100) if err != nil { log.Fatal(err) } fmt.Println("=== Recent Chat ===") for _, msg := range chatHistory { age := msg.Age() timeStr := "" if age < time.Minute { timeStr = "just now" } else if age < time.Hour { timeStr = fmt.Sprintf("%dm ago", int(age.Minutes())) } else { timeStr = msg.PostedTime().Format("15:04") } fmt.Printf("[%s] <%s> %s\n", timeStr, msg.Author, msg.Babble) } ## Messages Since Timestamp Get messages posted since a specific time: // Get messages since user's last login lastLogin := getUserLastLogin(userID) newMessages, err := babble.Since(db, lastLogin) if err != nil { log.Fatal(err) } if len(newMessages) > 0 { fmt.Printf("You missed %d messages while you were away\n", len(newMessages)) } ## Messages Between Timestamps Get messages within a time range: // Get today's chat history startOfDay := time.Now().Truncate(24 * time.Hour).Unix() endOfDay := time.Now().Unix() todaysChat, err := babble.Between(db, startOfDay, endOfDay) if err != nil { log.Fatal(err) } # Search and Filtering ## Text Search Search for messages containing specific terms: // Search for messages about "boss fight" bossMessages, err := babble.Search(db, "boss fight") if err != nil { log.Fatal(err) } for _, msg := range bossMessages { fmt.Printf("<%s> %s\n", msg.Author, msg.Preview(60)) } Search is case-insensitive and matches partial words. ## Author-Based Queries Get messages from specific players: // Get recent messages from a player playerRecent, err := babble.RecentByAuthor(db, "PlayerName", 10) if err != nil { log.Fatal(err) } // Get all messages from a player (for moderation) allPlayerMessages, err := babble.ByAuthor(db, "ReportedPlayer") if err != nil { log.Fatal(err) } All author searches are case-insensitive. # Mention System ## Finding Mentions The package includes a comprehensive mention system using @username syntax: message, _ := babble.Find(db, someID) // Get all mentioned usernames mentions := message.GetMentions() for _, username := range mentions { fmt.Printf("Message mentions: @%s\n", username) } // Check if specific user is mentioned if message.HasMention("PlayerName") { fmt.Println("You were mentioned in this message!") } ## Mention Parsing The mention system handles various formats: - `@username` - Basic mention - `@username!` - With punctuation - `@username,` - In lists - `@username?` - In questions Mentions are extracted without the punctuation and are case-insensitive. ## Notification Integration Use mentions for player notifications: // Process new messages for mentions recentMessages, _ := babble.Recent(db, 50) for _, msg := range recentMessages { mentions := msg.GetMentions() for _, mentionedUser := range mentions { // Send notification to mentioned user notifyUser(mentionedUser, fmt.Sprintf("%s mentioned you: %s", msg.Author, msg.Preview(50))) } } # Message Analysis ## Content Analysis Analyze message content for moderation or statistics: message, _ := babble.Find(db, someID) // Basic content metrics fmt.Printf("Length: %d characters\n", message.Length()) fmt.Printf("Words: %d\n", message.WordCount()) // Content checks if message.IsEmpty() { fmt.Println("Empty message detected") } if message.IsLongMessage(200) { fmt.Println("Very long message - possible spam") } // Search within message if message.Contains("inappropriate_term") { fmt.Println("Message flagged for review") } ## Time Analysis Analyze posting patterns: message, _ := babble.Find(db, someID) age := message.Age() fmt.Printf("Message posted %v ago\n", age) if message.IsRecent() { fmt.Println("This is a recent message (within 1 hour)") } // Format for display postedTime := message.PostedTime() if age < 24*time.Hour { fmt.Printf("Posted at %s\n", postedTime.Format("15:04")) } else { fmt.Printf("Posted on %s\n", postedTime.Format("Jan 2 15:04")) } # Chat Display Patterns ## Live Chat Feed Display real-time chat messages: func displayChatFeed(db *database.DB) { messages, _ := babble.Recent(db, 50) fmt.Println("=== Global Chat ===") for i := len(messages) - 1; i >= 0; i-- { // Reverse for chronological order msg := messages[i] // Format timestamp age := msg.Age() var timeStr string if age < time.Minute { timeStr = "now" } else if age < time.Hour { timeStr = fmt.Sprintf("%dm", int(age.Minutes())) } else { timeStr = msg.PostedTime().Format("15:04") } // Handle mentions highlighting content := msg.Babble if msg.HasMention(currentUser) { content = fmt.Sprintf("🔔 %s", content) // Highlight mentions } fmt.Printf("[%s] <%s> %s\n", timeStr, msg.Author, content) } } ## Chat History Browser Browse historical messages: func browseChatHistory(db *database.DB, page int, pageSize int) { offset := page * pageSize // Get paginated results (implement with LIMIT/OFFSET) allMessages, _ := babble.All(db) start := offset end := offset + pageSize if end > len(allMessages) { end = len(allMessages) } if start >= len(allMessages) { fmt.Println("No more messages") return } pageMessages := allMessages[start:end] fmt.Printf("=== Chat History (Page %d) ===\n", page+1) for _, msg := range pageMessages { fmt.Printf("%s <%s> %s\n", msg.PostedTime().Format("Jan 2 15:04"), msg.Author, msg.Babble) } } # Moderation Features ## Content Moderation Tools for chat moderation: // Flag inappropriate messages func moderateMessage(db *database.DB, messageID int) { msg, err := babble.Find(db, messageID) if err != nil { return } // Check for spam (very short or very long) if msg.WordCount() < 2 { fmt.Printf("Possible spam: %s\n", msg.Preview(30)) } if msg.IsLongMessage(500) { fmt.Printf("Very long message from %s\n", msg.Author) } // Check for excessive mentions mentions := msg.GetMentions() if len(mentions) > 5 { fmt.Printf("Message with %d mentions from %s\n", len(mentions), msg.Author) } } ## User Activity Analysis Analyze user posting patterns: // Check user activity func analyzeUserActivity(db *database.DB, username string) { // Recent activity recentMessages, _ := babble.RecentByAuthor(db, username, 10) fmt.Printf("User %s recent activity:\n", username) fmt.Printf("- Recent messages: %d\n", len(recentMessages)) if len(recentMessages) > 0 { totalWords := 0 for _, msg := range recentMessages { totalWords += msg.WordCount() } avgWords := totalWords / len(recentMessages) fmt.Printf("- Average words per message: %d\n", avgWords) latest := recentMessages[0] fmt.Printf("- Last message: %s (%s ago)\n", latest.Preview(40), latest.Age()) } // Check for mention patterns allUserMessages, _ := babble.ByAuthor(db, username) mentionCount := 0 for _, msg := range allUserMessages { mentionCount += len(msg.GetMentions()) } if len(allUserMessages) > 0 { avgMentions := float64(mentionCount) / float64(len(allUserMessages)) fmt.Printf("- Average mentions per message: %.2f\n", avgMentions) } } # Performance Considerations ## Efficient Queries All time-based queries are optimized: // Recent messages are efficiently ordered recent, _ := babble.Recent(db, 100) // Uses LIMIT for efficiency // Time-based queries use indexed timestamp since, _ := babble.Since(db, timestamp) // Efficient with proper index // Author queries support case-insensitive search authorMessages, _ := babble.ByAuthor(db, "username") // Uses LOWER() function ## Memory Management For large chat histories, process in batches: // Process messages in batches func processAllMessages(db *database.DB, batchSize int) { allMessages, _ := babble.All(db) for i := 0; i < len(allMessages); i += batchSize { end := i + batchSize if end > len(allMessages) { end = len(allMessages) } batch := allMessages[i:end] processBatch(batch) } } # Integration Examples ## Real-Time Chat Implement live chat updates: func pollForNewMessages(db *database.DB, lastMessageID int) []*babble.Babble { // Get messages newer than last seen allMessages, _ := babble.All(db) newMessages := make([]*babble.Babble, 0) for _, msg := range allMessages { if msg.ID > lastMessageID { newMessages = append(newMessages, msg) } } return newMessages } ## Chat Commands Process special chat commands: func processMessage(db *database.DB, author, content string) { // Check for commands if strings.HasPrefix(content, "/") { handleCommand(author, content) return } // Regular chat message msg, err := babble.NewBuilder(db). WithAuthor(author). WithBabble(content). Create() if err != nil { log.Printf("Failed to save message: %v", err) return } // Process mentions for notifications mentions := msg.GetMentions() for _, username := range mentions { sendMentionNotification(username, msg) } } # Error Handling All functions return appropriate errors for common failure cases: - Message not found (Find returns error for non-existent IDs) - Database connection issues - Invalid operations (e.g., saving/deleting messages without IDs) - Search query errors - Time range validation errors */ package babble