diff --git a/user/level.go b/user/level.go index 5f847b6..6d9b674 100644 --- a/user/level.go +++ b/user/level.go @@ -8,6 +8,7 @@ import ( "github.com/bwmarrin/discordgo" "slices" "sync" + "time" ) func onNewLevel(dg *discordgo.Session, m *discordgo.Member, level uint) { @@ -55,6 +56,31 @@ func (c *Copaing) OnNewLevel(dg *discordgo.Session, level uint) { func PeriodicReducer(dg *discordgo.Session) { wg := &sync.WaitGroup{} + var cs []*Copaing + if err := gokord.DB.Find(&cs).Error; err != nil { + utils.SendAlert("user/level.go - Fetching all copaings", err.Error()) + return + } + cxps := make([]*cXP, len(cs)) + for i, c := range cs { + if i%10 == 9 { + wg.Wait() // prevents spamming the DB + } + wg.Add(1) + go func() { + defer wg.Done() + xp, err := c.GetXP() + if err != nil { + utils.SendAlert("user/level.go - Getting XP", err.Error(), "copaing_id", c.ID, "guild_id", c.GuildID) + xp = 0 + } + cxps[i] = &cXP{ + Cxp: xp, + Copaing: c, + } + }() + } + wg.Wait() for _, g := range dg.State.Guilds { wg.Add(1) go func() { @@ -71,5 +97,20 @@ func PeriodicReducer(dg *discordgo.Session) { }() } wg.Wait() + for i, c := range cxps { + if i%50 == 49 { + utils.SendDebug("Sleeping...") + time.Sleep(15 * time.Second) // prevents spamming the API + } + oldXp := c.GetXP() + xp, err := c.ToCopaing().GetXP() + if err != nil { + utils.SendAlert("user/level.go - Getting XP", err.Error(), "guild_id", c.ID, "discord_id", c.DiscordID) + continue + } + if exp.Level(oldXp) != exp.Level(xp) { + c.OnNewLevel(dg, exp.Level(xp)) + } + } utils.SendDebug("Periodic reduce finished", "len(guilds)", len(dg.State.Guilds)) } diff --git a/user/xp.go b/user/xp.go index d88e3ce..71a1ced 100644 --- a/user/xp.go +++ b/user/xp.go @@ -62,7 +62,7 @@ func (c *Copaing) GetXPForDays(n uint) (uint, error) { rows, err := gokord.DB. Model(&CopaingXP{}). Where( - "created_at >= '?' and guild_id = ? and copaing_id = ?", + "created_at >= ? and guild_id = ? and copaing_id = ?", exp.TimeStampNDaysBefore(n), c.GuildID, c.ID, @@ -73,13 +73,13 @@ func (c *Copaing) GetXPForDays(n uint) (uint, error) { return 0, err } for rows.Next() { - var cXP CopaingXP - err = gokord.DB.ScanRows(rows, &cXP) + var cxp CopaingXP + err = gokord.DB.ScanRows(rows, &cxp) if err != nil { utils.SendAlert("user/xp.go - Scanning rows", err.Error(), "copaing_id", c.ID, "guild_id", c.GuildID) continue } - xp += cXP.XP + xp += cxp.XP } return xp, nil }