mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Add housing/pets/Thom Krooke, wordle overhaul, boost system, backup strategy
Part 3 (Housing, Thom Krooke & Pets): - Housing system with tiered upgrades, mortgage loans, FRED API rates - Thom Krooke realtor NPC with !thom commands and !thom pay extra principal - Pet system with arrival, naming, leveling, combat, morning defense - Pet ditch recovery scales with level, name validation Wordle overhaul: - Remove daily expiration — puzzles persist until solved/failed - Auto-start new puzzle after solve, fail, or skip - Sequential puzzle IDs instead of date-based - Auto-create puzzle on first guess if none active Adventure fixes: - Double XP/money boost toggle (!adv boost, admin only) - Fix ensureCharacter wiping existing data on query errors - Fix rival RPS format string bug - Fix daily summary empty data (load today+yesterday logs) - Fix holdem DM-to-room reply routing - Fix Robbie payout to 25% of item value - Add fishing to leaderboard and TwinBee calculations - Add Thom to morning menu - Persist mortgage rate across restarts via db.CacheGet/Set Infrastructure: - Daily database backup via VACUUM INTO with 7-day retention - Admin DM notification on backup failure (async) - Daily NPC house balance reset for holdem Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math/rand/v2"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gogobee/internal/db"
|
||||
@@ -102,6 +104,19 @@ func (p *AdventurePlugin) sendMorningDMs() {
|
||||
continue
|
||||
}
|
||||
|
||||
// Pet arrival check (fires before normal morning DM)
|
||||
if petShouldArrive(&char) {
|
||||
p.petArrivalDM(char.UserID)
|
||||
continue
|
||||
}
|
||||
|
||||
// Morning pet event
|
||||
petEvent := petMorningEvent(&char)
|
||||
if petEvent != "" {
|
||||
char.PetMorningDefense = true
|
||||
_ = saveAdvCharacter(&char)
|
||||
}
|
||||
|
||||
// Send morning DM with choices
|
||||
equip, err := loadAdvEquipment(char.UserID)
|
||||
if err != nil {
|
||||
@@ -119,6 +134,9 @@ func (p *AdventurePlugin) sendMorningDMs() {
|
||||
holidayLabel = holName
|
||||
}
|
||||
text := renderAdvMorningDM(&char, equip, balance, bonuses, holidayLabel)
|
||||
if petEvent != "" {
|
||||
text = fmt.Sprintf("🐾 *%s*\n\n%s", petEvent, text)
|
||||
}
|
||||
p.advMarkMenuSent(char.UserID)
|
||||
if err := p.SendDM(char.UserID, text); err != nil {
|
||||
slog.Error("adventure: failed to send morning DM", "user", char.UserID, "err", err)
|
||||
@@ -171,7 +189,11 @@ func (p *AdventurePlugin) postDailySummary() {
|
||||
return
|
||||
}
|
||||
|
||||
todayLogs, _ := loadAdvTodayLogs()
|
||||
// Load logs for today and yesterday — players may act across the UTC boundary
|
||||
now := time.Now().UTC()
|
||||
todayLogs, _ := loadAdvLogsForDate(now.Format("2006-01-02"))
|
||||
yesterdayLogs, _ := loadAdvLogsForDate(now.AddDate(0, 0, -1).Format("2006-01-02"))
|
||||
todayLogs = append(todayLogs, yesterdayLogs...)
|
||||
// Group logs per user — holiday days may produce 2 entries per user
|
||||
logsPerUser := make(map[id.UserID][]*AdvDayLog)
|
||||
for i := range todayLogs {
|
||||
@@ -394,9 +416,39 @@ func (p *AdventurePlugin) midnightReset() error {
|
||||
// Check babysitting service expirations
|
||||
p.checkBabysitExpiry(chars)
|
||||
|
||||
// Pet supply shop unlock check
|
||||
p.petMidnightCheck()
|
||||
|
||||
// Reset holdem NPC house balance
|
||||
resetNPCHouseBalance()
|
||||
|
||||
// Daily database backup (async to avoid blocking reset if DM sends are slow)
|
||||
go func() {
|
||||
if err := db.Backup(); err != nil {
|
||||
slog.Error("adventure: daily backup failed", "err", err)
|
||||
p.notifyAdmins(fmt.Sprintf("⚠️ **Daily backup failed:** %v", err))
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *AdventurePlugin) notifyAdmins(msg string) {
|
||||
admins := os.Getenv("ADMIN_USERS")
|
||||
if admins == "" {
|
||||
return
|
||||
}
|
||||
for _, a := range strings.Split(admins, ",") {
|
||||
uid := id.UserID(strings.TrimSpace(a))
|
||||
if uid == "" {
|
||||
continue
|
||||
}
|
||||
if err := p.SendDM(uid, msg); err != nil {
|
||||
slog.Error("adventure: failed to notify admin", "user", uid, "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Helper ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func (p *AdventurePlugin) registerDMRoom(userID id.UserID) {
|
||||
|
||||
Reference in New Issue
Block a user