diff options
Diffstat (limited to 'xp/level.go')
| -rw-r--r-- | xp/level.go | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/xp/level.go b/xp/level.go index 671bf2e..4830298 100644 --- a/xp/level.go +++ b/xp/level.go @@ -5,6 +5,8 @@ import ( "github.com/anhgelus/les-copaings-bot/config" "github.com/bwmarrin/discordgo" "slices" + "sync" + "time" ) func onNewLevel(s *discordgo.Session, m *discordgo.Member, level uint) { @@ -42,3 +44,119 @@ func onNewLevel(s *discordgo.Session, m *discordgo.Member, level uint) { } } } + +func (c *Copaing) OnNewLevel(s *discordgo.Session, level uint) { + m, err := s.GuildMember(c.GuildID, c.DiscordID) + if err != nil { + utils.SendAlert( + "xp/level.go - Getting member for new level", + err.Error(), + "discord_id", + c.DiscordID, + "guild_id", + c.GuildID, + ) + return + } + onNewLevel(s, m, level) +} + +func LastEventUpdate(s *discordgo.Session, c *Copaing) { + h := c.HourSinceLastEvent() + l := Lose(h, c.XP) + xp := c.XPAlreadyRemoved() + oldXP := c.XP + if l-xp < 0 { + utils.SendWarn("lose - xp already removed is negative", "lose", l, "xp", xp) + c.XP = 0 + } else { + calc := int(c.XP) - int(l) + int(c.XPAlreadyRemoved()) + if calc < 0 { + c.XP = 0 + } else { + c.XP = uint(calc) + } + } + if oldXP != c.XP { + lvl := Level(c.XP) + if Level(oldXP) != lvl { + utils.SendDebug( + "Level changed", + "old", + Level(oldXP), + "new", + lvl, + "discord_id", + c.DiscordID, + "guild_id", + c.GuildID, + ) + c.OnNewLevel(s, lvl) + } + c.Save() + } + c.SetLastEvent() +} + +func XPUpdate(s *discordgo.Session, c *Copaing) { + oldXP := c.XP + if oldXP == 0 { + return + } + h := c.HourSinceLastEvent() + l := Lose(h, c.XP) + xp := c.XPAlreadyRemoved() + if l-xp < 0 { + utils.SendWarn("lose - xp_removed is negative", "lose", l, "xp removed", xp) + c.AddXPAlreadyRemoved(0) + } else { + calc := int(c.XP) - int(l) + int(xp) + if calc < 0 { + c.AddXPAlreadyRemoved(c.XP) + c.XP = 0 + } else { + c.XP = uint(calc) + c.AddXPAlreadyRemoved(l - xp) + } + } + if oldXP != c.XP { + lvl := Level(c.XP) + if Level(oldXP) != lvl { + utils.SendDebug( + "Level updated", + "old", + Level(oldXP), + "new", + lvl, + "discord_id", + c.DiscordID, + "guild_id", + c.GuildID, + ) + c.OnNewLevel(s, lvl) + } + utils.SendDebug("Save XP", "old", oldXP, "new", c.XP, "user", c.DiscordID) + c.Save() + } +} + +func PeriodicReducer(s *discordgo.Session) { + var wg sync.WaitGroup + for _, g := range s.State.Guilds { + for _, m := range utils.FetchGuildUser(s, g.ID) { + if m.User.Bot { + continue + } + wg.Add(1) + go func() { + c := GetCopaing(m.User.ID, g.ID) + XPUpdate(s, c) + wg.Done() + }() + } + wg.Wait() // finish the entire guild before starting another + utils.SendDebug("Periodic reduce, guild finished", "guild", g.Name) + time.Sleep(10 * time.Second) // sleep prevents from spamming the Discord API and the database + } + utils.SendDebug("Periodic reduce finished", "len(guilds)", len(s.State.Guilds)) +} |
