aboutsummaryrefslogtreecommitdiff
path: root/xp/level.go
diff options
context:
space:
mode:
Diffstat (limited to 'xp/level.go')
-rw-r--r--xp/level.go118
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))
+}