diff options
Diffstat (limited to 'user/xp.go')
| -rw-r--r-- | user/xp.go | 99 |
1 files changed, 99 insertions, 0 deletions
@@ -1,11 +1,30 @@ package user import ( + "fmt" + "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/utils" + "github.com/anhgelus/les-copaings-bot/config" "github.com/anhgelus/les-copaings-bot/exp" "github.com/bwmarrin/discordgo" + "slices" + "sync" + "time" ) +type cXP struct { + Cxp uint + *Copaing +} + +func (c *cXP) ToCopaing() *Copaing { + return c.Copaing +} + +func (c *cXP) GetXP() uint { + return c.Cxp +} + func (c *Copaing) AddXP(s *discordgo.Session, m *discordgo.Member, xp uint, fn func(uint, uint)) { old, err := c.GetXP() pastLevel := exp.Level(old) @@ -29,3 +48,83 @@ func (c *Copaing) AddXP(s *discordgo.Session, m *discordgo.Member, xp uint, fn f onNewLevel(s, m, newLevel) } } + +func (c *Copaing) GetXP() (uint, error) { + cfg := config.GetGuildConfig(c.GuildID) + return c.GetXPForDays(cfg.DaysXPRemains) +} + +func (c *Copaing) GetXPForDays(n uint) (uint, error) { + xp := uint(0) + y, m, d := time.Unix(time.Now().Unix()-int64(n*24*60*60), 0).Date() + rows, err := gokord.DB. + Model(&CopaingXP{}). + Where(fmt.Sprintf("created_at >= '%d-%d-%d' and guild_id = ? and discord_id = ?", y, m, d), c.GuildID, c.DiscordID). + Rows() + defer rows.Close() + if err != nil { + return 0, err + } + for rows.Next() { + var cXP CopaingXP + err = gokord.DB.ScanRows(rows, &cXP) + if err != nil { + utils.SendAlert("user/xp.go - Scanning rows", err.Error(), "discord_id", c.DiscordID, "guild_id", c.GuildID) + continue + } + xp += cXP.XP + } + return xp, nil +} + +// GetBestXP returns n Copaing with the best XP within d days (d <= cfg.DaysXPRemain; d < 0 <=> d = cfg.DaysXPRemain) +// +// This function is slow +func GetBestXP(guildId string, n uint, d int) ([]CopaingAccess, error) { + if d < 0 { + cfg := config.GetGuildConfig(guildId) + d = int(cfg.DaysXPRemains) + } + rows, err := gokord.DB.Model(&Copaing{}).Where("guild_id = ?", guildId).Rows() + defer rows.Close() + if err != nil { + return nil, err + } + var l []*cXP + wg := sync.WaitGroup{} + for rows.Next() { + var c Copaing + err = gokord.DB.ScanRows(rows, &c) + if err != nil { + utils.SendAlert("user/xp.go - Scanning rows", err.Error(), "discord_id", c.DiscordID, "guild_id", guildId) + continue + } + wg.Add(1) + go func() { + defer wg.Done() + xp, err := c.GetXPForDays(uint(d)) + if err != nil { + utils.SendAlert("user/xp.go - Fetching xp", err.Error(), "discord_id", c.DiscordID, "guild_id", guildId) + return + } + l = append(l, &cXP{Cxp: xp, Copaing: &c}) + }() + } + wg.Wait() + slices.SortFunc(l, func(a, b *cXP) int { + // desc order + if a.Cxp < b.Cxp { + return 1 + } + if a.Cxp > b.Cxp { + return -1 + } + return 0 + }) + m := min(len(l), int(n)) + cs := make([]CopaingAccess, m) + for i, c := range l[:m] { + cs[i] = c + } + return cs, nil +} |
