diff options
| -rw-r--r-- | commands/config.go | 6 | ||||
| -rw-r--r-- | commands/credits.go | 2 | ||||
| -rw-r--r-- | commands/rank.go | 14 | ||||
| -rw-r--r-- | commands/reset.go | 12 | ||||
| -rw-r--r-- | commands/stats.go | 31 | ||||
| -rw-r--r-- | commands/top.go | 8 | ||||
| -rw-r--r-- | config/channel.go | 4 | ||||
| -rw-r--r-- | config/guild.go | 6 | ||||
| -rw-r--r-- | config/xp_reduce.go | 8 | ||||
| -rw-r--r-- | config/xp_role.go | 40 | ||||
| -rw-r--r-- | events.go | 31 | ||||
| -rw-r--r-- | go.mod | 6 | ||||
| -rw-r--r-- | go.sum | 6 | ||||
| -rw-r--r-- | main.go | 8 | ||||
| -rw-r--r-- | updates.json | 2 | ||||
| -rw-r--r-- | user/level.go | 40 | ||||
| -rw-r--r-- | user/xp.go | 26 |
17 files changed, 133 insertions, 117 deletions
diff --git a/commands/config.go b/commands/config.go index 7ffd4af..336e66a 100644 --- a/commands/config.go +++ b/commands/config.go @@ -130,7 +130,7 @@ func ConfigCommand( err := s.InteractionAPI().Respond(i.Interaction, ConfigResponse(i)) if err != nil { - s.LogError(err, "config/guild.go - Sending config") + s.Logger().Error("sending config", "error", err) } } @@ -145,7 +145,7 @@ func ConfigMessageComponent( err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - s.LogError(err, "sending config") + s.Logger().Error("sending config", "error", err) } } @@ -160,6 +160,6 @@ func ConfigModal( err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - s.LogError(err, "sending config") + s.Logger().Error("sending config", "error", err) } } diff --git a/commands/credits.go b/commands/credits.go index b303834..340ea57 100644 --- a/commands/credits.go +++ b/commands/credits.go @@ -15,6 +15,6 @@ func Credits(s bot.Session, _ *event.InteractionCreate, _ cmd.OptionMap, resp *c msg += "- [Inter](<https://github.com/rsms/inter>)" err := resp.SetMessage(msg).Send() if err != nil { - s.LogError(err, "sending credits") + s.Logger().Error("sending credits", "error", err) } } diff --git a/commands/rank.go b/commands/rank.go index 8f3090f..4080864 100644 --- a/commands/rank.go +++ b/commands/rank.go @@ -20,28 +20,28 @@ func Rank(s bot.Session, i *event.InteractionCreate, optMap cmd.OptionMap, resp if u.Bot { err = resp.SetMessage("Imagine si les bots avaient un niveau :rolling_eyes:").IsEphemeral().Send() if err != nil { - s.LogError(err, "reply error user is a bot") + s.Logger().Error("reply error user is a bot", "error", err) } return } m, err = s.GuildAPI().Member(i.GuildID, u.ID) if err != nil { - s.LogError(err, "Fetching guild member %s in %s", u.Username, i.GuildID) + s.Logger().Error("fetching guild member", "error", err, "user", u.Username, "guild", i.GuildID) err = resp.SetMessage("Erreur : impossible de récupérer le membre").IsEphemeral().Send() if err != nil { - s.LogError(err, "reply error fetching guild member") + s.Logger().Error("reply error fetching guild member", "error", err) } return } c = user.GetCopaing(u.ID, i.GuildID) // current user = member targeted by member who wrote /rank msg = fmt.Sprintf("Le niveau de %s", m.DisplayName()) } - xp, err := c.GetXP() + xp, err := c.GetXP(s.Logger()) if err != nil { - s.LogError(err, "fetching xp for copaing %s in %s", c.ID, i.GuildID) + s.Logger().Error("fetching xp", "error", err, "copaing", c.ID, "guild", i.GuildID) err = resp.SetMessage("Erreur : impossible de récupérer l'XP").IsEphemeral().Send() if err != nil { - s.LogError(err, "reply error fetching xp") + s.Logger().Error("reply error fetching xp", "error", err) } return } @@ -55,6 +55,6 @@ func Rank(s bot.Session, i *event.InteractionCreate, optMap cmd.OptionMap, resp nxtLvlXP-xp, )).Send() if err != nil { - s.LogError(err, "sending rank") + s.Logger().Error("sending rank", "error", err) } } diff --git a/commands/reset.go b/commands/reset.go index 7caa238..21bfeb7 100644 --- a/commands/reset.go +++ b/commands/reset.go @@ -12,7 +12,7 @@ func Reset(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd var copaings []*user.Copaing gokord.DB.Where("guild_id = ?", i.GuildID).Delete(&copaings) if err := resp.IsEphemeral().SetMessage("L'XP a été reset.").Send(); err != nil { - s.LogError(err, "sending reset success") + s.Logger().Error("sending reset success", "error", err) } } @@ -21,26 +21,26 @@ func ResetUser(s bot.Session, i *event.InteractionCreate, optMap cmd.OptionMap, v, ok := optMap["user"] if !ok { if err := resp.SetMessage("Le user n'a pas été renseigné.").Send(); err != nil { - s.LogError(err, "sending error copaing not set") + s.Logger().Error("sending error copaing not set", "error", err) } return } m := v.UserValue(s.UserAPI()) if m.Bot { if err := resp.SetMessage("Les bots n'ont pas de niveau :upside_down:").Send(); err != nil { - s.LogError(err, "sending error bot does not have xp") + s.Logger().Error("sending error bot does not have xp", "error", err) } return } err := user.GetCopaing(m.ID, i.GuildID).Delete() if err != nil { - s.LogError(err, "deleting copaings %s in %s", m.Username, i.GuildID) + s.Logger().Error("deleting copaing", "error", err, "user", m.Username, "guild", i.GuildID) err = resp.SetMessage("Erreur : impossible de reset l'utilisateur").Send() if err != nil { - s.LogError(err, "sending error while deleting") + s.Logger().Error("sending error while deleting", "error", err) } } if err = resp.SetMessage("Le user bien été reset.").Send(); err != nil { - s.LogError(err, "sending reset success") + s.Logger().Error("sending reset success", "error", err) } } diff --git a/commands/stats.go b/commands/stats.go index 2c22f0d..4fc35ae 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -57,7 +57,7 @@ func Stats(s bot.Session, i *event.InteractionCreate, opt cmd.OptionMap, resp *c if in < 1 || uint(in) > cfg.DaysXPRemains { msg := fmt.Sprintf("Nombre de jours invalide. Il doit être strictement positif et inférieur à %d", cfg.DaysXPRemains) if err := resp.SetMessage(msg).IsEphemeral().Send(); err != nil { - s.LogError(err, "sending error invalid days") + s.Logger().Error("sending error invalid days", "error", err) } return } @@ -65,7 +65,7 @@ func Stats(s bot.Session, i *event.InteractionCreate, opt cmd.OptionMap, resp *c } err := resp.IsDeferred().Send() if err != nil { - s.LogError(err, "sending deferred") + s.Logger().Error("sending deferred", "error", err) return } go func() { @@ -76,16 +76,16 @@ func Stats(s bot.Session, i *event.InteractionCreate, opt cmd.OptionMap, resp *c w, err = statsAll(s, i, days) } if err != nil { - s.LogError(err, "generating stats in %s", i.GuildID) + s.Logger().Error("generating stats", "error", err, "guild", i.GuildID) if err = resp.IsEphemeral().SetMessage("Il y a eu une erreur...").Send(); err != nil { - s.LogError(err, "sending error occurred") + s.Logger().Error("sending error occurred", "error", err) } return } b := new(bytes.Buffer) _, err = w.WriteTo(b) if err != nil { - s.LogError(err, "writing png") + s.Logger().Error("writing png", "error", err) } err = resp.AddFile(&channel.File{ Name: "plot.png", @@ -93,7 +93,7 @@ func Stats(s bot.Session, i *event.InteractionCreate, opt cmd.OptionMap, resp *c Reader: b, }).Send() if err != nil { - s.LogError(err, "sending stats") + s.Logger().Error("sending stats", "error", err) } }() } @@ -122,7 +122,7 @@ func stats(s bot.Session, i *event.InteractionCreate, days int, execSql func(bef if gokord.Debug { var rawCopaingData []*user.CopaingXP if err := execSql("SELECT * FROM copaing_xps ", "").Scan(&rawCopaingData).Error; err != nil { - s.LogError(err, "fetching result") + s.Logger().Error("fetching result", "error", err) return nil, err } rawData = make([]*data, len(rawCopaingData)) @@ -138,7 +138,7 @@ func stats(s bot.Session, i *event.InteractionCreate, days int, execSql func(bef if err := execSql( `SELECT "created_at"::date::text, sum("xp") as xp, "copaing_id" FROM copaing_xps `, ` GROUP BY "created_at"::date, "copaing_id"`, ).Scan(&rawDbData).Error; err != nil { - s.LogError(err, "fetching result") + s.Logger().Error("fetching result", "error", err) return nil, err } rawData = make([]*data, len(rawDbData)) @@ -160,10 +160,10 @@ func stats(s bot.Session, i *event.InteractionCreate, days int, execSql func(bef var cp user.Copaing if err := gokord.DB.First(&cp, raw.CopaingID).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - s.LogError(err, "finding copaing %d", raw.CopaingID) + s.Logger().Error("finding copaing", "error", err, "copaing", raw.CopaingID) return nil, err } - s.LogWarn("Copaing %d not found, skipping", raw.CopaingID) + s.Logger().Warn("copaing not found, skipping", "copaing", raw.CopaingID) continue } copaings[raw.CopaingID] = &cp @@ -222,7 +222,7 @@ func generatePlot(s bot.Session, i *event.InteractionCreate, copaings map[int]*u for in, c := range copaings { m, err := s.GuildAPI().Member(i.GuildID, c.DiscordID) if err != nil { - s.LogError(err, "fetching guild member") + s.Logger().Error("fetching guild member", "error", err) return nil, err } slices.SortFunc(stats[in], func(a, b plotter.XY) int { @@ -236,7 +236,6 @@ func generatePlot(s bot.Session, i *event.InteractionCreate, copaings map[int]*u }) l, _, err := plotter.NewLinePoints(plotter.XYs(stats[in])) if err != nil { - s.LogError(err, "adding line points") return nil, err } l.Color = colors[cnt%len(colors)] @@ -251,11 +250,5 @@ func generatePlot(s bot.Session, i *event.InteractionCreate, copaings map[int]*u p.Legend.Add(m.DisplayName(), l) cnt++ } - w, err := p.WriterTo(12*vg.Inch, 8*vg.Inch, "png") - - if err != nil { - s.LogError(err, "generating png") - return nil, err - } - return w, nil + return p.WriterTo(12*vg.Inch, 8*vg.Inch, "png") } diff --git a/commands/top.go b/commands/top.go index 751f7fa..bb08144 100644 --- a/commands/top.go +++ b/commands/top.go @@ -16,7 +16,7 @@ import ( func Top(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { err := resp.IsDeferred().Send() if err != nil { - s.LogError(err, "sending deferred") + s.Logger().Error("sending deferred", "error", err) return } embeds := make([]*channel.MessageEmbed, 3) @@ -24,9 +24,9 @@ func Top(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.R fn := func(str string, n uint, d int, id int) { defer wg.Done() - tops, err := user.GetBestXP(i.GuildID, n, d) + tops, err := user.GetBestXP(s.Logger(), i.GuildID, n, d) if err != nil { - s.LogError(err, "fetching best xp, n: %d, d: %d, id: %d, guild: %s", n, d, id, i.GuildID) + s.Logger().Error("fetching best xp", "error", err, "n", n, "d", d, "id", id, "guild", i.GuildID) embeds[id] = &channel.MessageEmbed{ Title: str, Description: "Erreur : impossible de récupérer la liste", @@ -60,7 +60,7 @@ func Top(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.R } err = resp.Send() if err != nil { - s.LogError(err, "sending response top") + s.Logger().Error("sending response top", "error", err) } }() } diff --git a/config/channel.go b/config/channel.go index 1ee6974..0c25b25 100644 --- a/config/channel.go +++ b/config/channel.go @@ -29,7 +29,7 @@ func HandleModifyFallbackChannel(s bot.Session, i *event.InteractionCreate, data cfg.FallbackChannel = channelID err := cfg.Save() if err != nil { - s.LogError(err, "Saving fallback channel") + s.Logger().Error("saving fallback channel", "error", err) return false } return true @@ -40,7 +40,7 @@ func HandleModifyDisChannel(s bot.Session, i *event.InteractionCreate, data *int cfg.DisabledChannels = strings.Join(data.Values, ";") err := cfg.Save() if err != nil { - s.LogError(err, "Unable to save disabled channel") + s.Logger().Error("unable to save disabled channel", "error", err) return false } return true diff --git a/config/guild.go b/config/guild.go index 10c64fd..e046ca7 100644 --- a/config/guild.go +++ b/config/guild.go @@ -38,15 +38,15 @@ func (cfg *GuildConfig) IsDisabled(s bot.Session, channelID string) bool { ok = !strings.Contains(cfg.DisabledChannels, channelID) c, err := s.ChannelAPI().State.Channel(channelID) if err != nil { - s.LogError(err, "unable to find channel %s in state", c) + s.Logger().Error("unable to find channel %s in state", "error", err, "channel", c) c, err = s.ChannelAPI().Channel(channelID) if err == nil { err = s.ChannelAPI().State.ChannelAdd(c) if err != nil { - s.LogError(err, "unable to add channel %s to state", c) + s.Logger().Error("unable to add channel to state", "error", err, "channel", c) } } else { - s.LogError(err, "unable to fetch channel %s", s) + s.Logger().Error("unable to fetch channel", "error", err, "channel", c) return false } } diff --git a/config/xp_reduce.go b/config/xp_reduce.go index c3a3e10..389043d 100644 --- a/config/xp_reduce.go +++ b/config/xp_reduce.go @@ -45,7 +45,7 @@ func HandleModifyPeriodicReduceCommand(s bot.Session, i *event.InteractionCreate } err := s.InteractionAPI().Respond(i.Interaction, &response) if err != nil { - s.LogError(err, "Sending xp reduce modal") + s.Logger().Error("sending xp reduce modal", "error", err) } } @@ -55,14 +55,14 @@ func HandleTimeReduceSet(s bot.Session, i *event.InteractionCreate, data *intera if err != nil { err = resp.IsEphemeral().SetMessage(fmt.Sprintf("La valeur indiquée, `%s`, c'est pas un entier.", v)).Send() if err != nil { - s.LogError(err, "Sending bad input message") + s.Logger().Error("sending bad input message", "error", err) } return false } if days < 30 { err = resp.IsEphemeral().SetMessage("Le nombre de jours doit être suppérieur à 30.").Send() if err != nil { - s.LogError(err, "Sending less than 30 days message") + s.Logger().Error("sending less than 30 days message", "error", err) } return false } @@ -70,7 +70,7 @@ func HandleTimeReduceSet(s bot.Session, i *event.InteractionCreate, data *intera cfg.DaysXPRemains = uint(days) err = cfg.Save() if err != nil { - s.LogError(err, "Saving DaysXPRemains configuration") + s.Logger().Error("saving DaysXPRemains configuration", "error", err) return false } return true diff --git a/config/xp_role.go b/config/xp_role.go index 42fe9f4..f857289 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -92,7 +92,7 @@ func HandleXpRole( } err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - s.LogError(err, "Sending config") + s.Logger().Error("sending config", "error", err) } } @@ -134,7 +134,7 @@ func HandleXpRoleNew( } err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - s.LogError(err, "Sending modal to add") + s.Logger().Error("sending modal to add", "error", err) } } @@ -147,7 +147,7 @@ func HandleXpRoleEdit( config := GetGuildConfig(i.GuildID) id, err := getRoleLevelID(parameters) if err != nil { - s.LogError(err, "Reading dynamic CustomID") + s.Logger().Error("reading dynamic CustomID", "error", err) return } _, role := config.FindXpRoleID(id) @@ -199,7 +199,7 @@ func HandleXpRoleEdit( err = s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - s.LogError(err, "Sending xp_role config") + s.Logger().Error("sending xp_role config", "error", err) } } @@ -211,7 +211,7 @@ func HandleXpRoleEditRole( ) { id, err := getRoleLevelID(parameters) if err != nil { - s.LogError(err, "Reading dynamic CustomID") + s.Logger().Error("reading dynamic CustomID", "error", err) return } role := data.Values[0] @@ -226,14 +226,14 @@ func HandleXpRoleEditRole( }, }) if err != nil { - s.LogError(err, "Sending unable to get role message") + s.Logger().Error("sending unable to get role message", "error", err) } return } xpRole.RoleID = role err = gokord.DB.Save(xpRole).Error if err != nil { - s.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) + s.Logger().Error("saving config", "error", err, "guild", i.GuildID, "id", id, "type", "add") } HandleXpRoleEdit(s, i, &interaction.MessageComponentData{}, parameters, resp) } @@ -247,7 +247,7 @@ func HandleXpRoleEditLevelStart( ) { id, err := getRoleLevelID(parameters) if err != nil { - s.LogError(err, "Reading dynamic CustomID") + s.Logger().Error("reading dynamic CustomID", "error", err) return } cfg := GetGuildConfig(i.GuildID) @@ -261,7 +261,7 @@ func HandleXpRoleEditLevelStart( }, }) if err != nil { - s.LogError(err, "Sending Unable to get role message") + s.Logger().Error("sending unable to get role message", "error", err) } return } @@ -288,7 +288,7 @@ func HandleXpRoleEditLevelStart( } err = s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - s.LogError(err, "Sending Edit level modal") + s.Logger().Error("sending edit level modal", "error", err) } } @@ -301,7 +301,7 @@ func HandleXpRoleEditLevel( ) { id, err := getRoleLevelID(parameters) if err != nil { - s.LogError(err, "Reading dynamic CustomID") + s.Logger().Error("reading dynamic CustomID", "error", err) return } @@ -315,7 +315,7 @@ func HandleXpRoleEditLevel( ). Send() if err != nil { - s.LogError(err, "Sending bad number warning message") + s.Logger().Error("sending bad number warning message", "error", err) } return } @@ -332,14 +332,14 @@ func HandleXpRoleEditLevel( }, }) if err != nil { - s.LogError(err, "Sending unable to modify role message") + s.Logger().Error("sending unable to modify role message", "error", err) } return } xpRole.XP = xp err = gokord.DB.Save(xpRole).Error if err != nil { - s.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) + s.Logger().Error("saving config", "guild", i.GuildID, "id", id, "type", "edit") } HandleXpRoleEdit(s, i, &interaction.MessageComponentData{}, parameters, resp) } @@ -353,13 +353,13 @@ func HandleXpRoleDel( ) { id, err := getRoleLevelID(dynamicValues) if err != nil { - s.LogError(err, "reading dynamic CustomID") + s.Logger().Error("reading dynamic CustomID", "error", err) return } cfg := GetGuildConfig(i.GuildID) _, role := cfg.FindXpRoleID(id) if role == nil { - err := s.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + err = s.InteractionAPI().Respond(i.Interaction, &interaction.Response{ Type: types.InteractionResponseChannelMessageWithSource, Data: &interaction.ResponseData{ Content: "Rôle introuvable. Peut-être a-t-il déjà été supprimé ?", @@ -367,13 +367,13 @@ func HandleXpRoleDel( }, }) if err != nil { - s.LogError(err, "Sending role not found message") + s.Logger().Error("sending role not found message", "error", err) } return } err = gokord.DB.Delete(role).Error if err != nil { - s.LogError(err, "Deleting entry guild_id %s, id %d, type del", i.GuildID, id) + s.Logger().Error("deleting entry", "error", err, "guild", i.GuildID, "id", id, "type", "del") } HandleXpRole(s, i, &interaction.MessageComponentData{}, resp) @@ -395,7 +395,7 @@ func HandleXpRoleAdd( ). Send() if err != nil { - s.LogError(err, "sending bad number warning message") + s.Logger().Error("sending bad number warning message", "error", err) } return } @@ -410,7 +410,7 @@ func HandleXpRoleAdd( }) err = cfg.Save() if err != nil { - s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + s.Logger().Error("saving config", "error", err, "role", roleId, "guild", i.GuildID) return } @@ -39,7 +39,12 @@ func OnMessage(s bot.Session, m *event.MessageCreate) { xp := min(exp.MessageXP(uint(len(trimmed)), exp.CalcDiversity(trimmed)), MaxXpPerMessage) c.AddXP(s, m.Member, xp, func(_ uint, _ uint) { if err := s.ChannelAPI().MessageReactionAdd(m.ChannelID, m.Message.ID, "⬆"); err != nil { - s.LogError(err, "add reaction for new level channel id %s, message id %s", m.ChannelID, m.Message.ID) + s.Logger().Error( + "add reaction for new level", + "error", err, + "channel", m.ChannelID, + "message", m.Message.ID, + ) } }) } @@ -67,7 +72,7 @@ func genMapKey(guildID string, userID string) string { } func onConnection(s bot.Session, e *event.VoiceStateUpdate) { - s.LogDebug("User connected username %s", e.Member.DisplayName()) + s.Logger().Debug("user connected", "user", e.Member.DisplayName()) connectedSince[genMapKey(e.GuildID, e.UserID)] = time.Now().Unix() } @@ -77,21 +82,21 @@ func onDisconnect(s bot.Session, e *event.VoiceStateUpdate) { // check the validity of user con, ok := connectedSince[genMapKey(e.GuildID, e.UserID)] if !ok || con == NotConnected { - s.LogWarn("User %s disconnect from a vocal but was registered as not connected", e.Member.DisplayName()) + s.Logger().Warn( + "user disconnect from a vocal but was registered as not connected", + "user", e.Member.DisplayName(), + ) return } timeInVocal := now - con - s.LogDebug("User disconnected username %s, time in vocal %d", e.Member.DisplayName(), timeInVocal) + s.Logger().Debug("user disconnected", "user", e.Member.DisplayName(), "time in vocal", timeInVocal) connectedSince[genMapKey(e.GuildID, e.UserID)] = NotConnected // add exp if timeInVocal < 0 { - s.LogWarn("Time spent in vocal negative discord_id %s, guild_id %s", e.UserID, e.GuildID) + s.Logger().Warn("time spent in vocal is negative", "user", e.Member.DisplayName(), "guild", e.GuildID) return } - if timeInVocal > MaxTimeInVocal { - s.LogWarn("User %s spent more than 6 hours in vocal", e.Member.DisplayName()) - timeInVocal = MaxTimeInVocal - } + timeInVocal = min(timeInVocal, MaxTimeInVocal) e.Member.GuildID = e.GuildID c.AddXP(s, e.Member, exp.VocalXP(uint(timeInVocal)), func(_ uint, newLevel uint) { cfg := config.GetGuildConfig(e.GuildID) @@ -102,13 +107,13 @@ func onDisconnect(s bot.Session, e *event.VoiceStateUpdate) { "%s est maintenant niveau %d", e.Member.Mention(), newLevel, )) if err != nil { - s.LogError(err, "Sending new level in fallback channel") + s.Logger().Error("sending new level in fallback channel", "error", err) } }) } func OnLeave(s bot.Session, e *event.GuildMemberRemove) { - s.LogDebug("Leave event user_id %s", e.User.ID) + s.Logger().Debug("leave event", "user", e.User.Username) if e.User.Bot { return } @@ -118,9 +123,9 @@ func OnLeave(s bot.Session, e *event.GuildMemberRemove) { Delete(&user.CopaingXP{}). Error if err != nil { - s.LogError(err, "Deleting user xp from db user_id %s, guild_id %s", e.User.ID, e.GuildID) + s.Logger().Error("deleting user xp from DB", "user", e.User.Username, "guild", e.GuildID) } if err = c.Delete(); err != nil { - s.LogError(err, "Deleting user from DB user_id %s, guild_id %s", e.User.ID, e.GuildID) + s.Logger().Error("deleting user from DB", "user", e.User.Username, "guild", e.GuildID) } } @@ -5,10 +5,10 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.12.1-0.20250926161635-21b1b138fd90 + github.com/anhgelus/gokord v0.12.1-0.20250927153335-e73ec7a067f2 github.com/jackc/pgx/v5 v5.7.5 github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.31.1-0.20250926154959-93603cbc1df5 + github.com/nyttikord/gokord v0.31.1-0.20250927153129-9bed7a4b26bf github.com/pelletier/go-toml/v2 v2.2.4 golang.org/x/image v0.30.0 gonum.org/v1/plot v0.16.0 @@ -33,7 +33,7 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/redis/go-redis/v9 v9.14.0 // indirect + github.com/redis/go-redis/v9 v9.15.0 // indirect golang.org/x/crypto v0.42.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.36.0 // indirect @@ -21,6 +21,8 @@ github.com/anhgelus/gokord v0.12.0 h1:6315krG631amMYRBXkp0Uz7voBtbgEHJZKsNgulu+1 github.com/anhgelus/gokord v0.12.0/go.mod h1:AUguJsHtnNOozqQY8SCRDfXfoFX6c+LWL7lXNoeIRCk= github.com/anhgelus/gokord v0.12.1-0.20250926161635-21b1b138fd90 h1:SNWUcYRXE5lgs9ujd+sLxpZKQFw6X2AfkievuyfzpAg= github.com/anhgelus/gokord v0.12.1-0.20250926161635-21b1b138fd90/go.mod h1:pcu6meTQQZRpDPhWuaJuDqa2NJ7iUPuVRD7+ffPmcmg= +github.com/anhgelus/gokord v0.12.1-0.20250927153335-e73ec7a067f2 h1:ousL4ksXhHtIhAiBvzu4yH1whXe+m3quo86ON8X8M/E= +github.com/anhgelus/gokord v0.12.1-0.20250927153335-e73ec7a067f2/go.mod h1:Mk9EPnkl8xlYV+nTxO1peU+206vI4biguUGp4/4U/AU= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -57,12 +59,16 @@ github.com/nyttikord/gokord v0.31.0 h1:64DeVCTQpSWj8/RtBm0GtHeh0Gqo3arJGtrSIn5/U github.com/nyttikord/gokord v0.31.0/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= github.com/nyttikord/gokord v0.31.1-0.20250926154959-93603cbc1df5 h1:cXvcOHc7C57EFK8fLK5XWb+JJN2k/akpRklDqHsP0zg= github.com/nyttikord/gokord v0.31.1-0.20250926154959-93603cbc1df5/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= +github.com/nyttikord/gokord v0.31.1-0.20250927153129-9bed7a4b26bf h1:d7saDF/eDtu95IgE4sfVoHdBQmqdvyJrc73mG4HoTJU= +github.com/nyttikord/gokord v0.31.1-0.20250927153129-9bed7a4b26bf/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/redis/go-redis/v9 v9.15.0 h1:2jdes0xJxer4h3NUZrZ4OGSntGlXp4WbXju2nOTRXto= +github.com/redis/go-redis/v9 v9.15.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "flag" + "log/slog" "os" "regexp" "time" @@ -22,7 +23,6 @@ import ( "github.com/nyttikord/gokord/discord/types" "github.com/nyttikord/gokord/event" "github.com/nyttikord/gokord/interaction" - "github.com/nyttikord/gokord/logger" "golang.org/x/image/font/opentype" "gonum.org/v1/plot" "gonum.org/v1/plot/font" @@ -47,7 +47,7 @@ var interTTF []byte func init() { err := godotenv.Load() if err != nil && !errors.Is(err, os.ErrNotExist) { - logger.Log(logger.LevelError, 0, "Error while loading .env file: %v", err.Error()) + slog.Error("error while loading .env file", "error", err) } flag.StringVar(&token, "token", os.Getenv("TOKEN"), "token of the bot") @@ -113,7 +113,7 @@ func handleDynamicModalComponent( data := i.ModalSubmitData() content, _ := json.Marshal(data) - s.LogDebug("%s", content) + s.Logger().Debug(string(content)) parameters := compiledPattern.FindStringSubmatch(data.CustomID) if parameters == nil { return @@ -225,7 +225,7 @@ func main() { user.PeriodicReducer(dg) stopPeriodicReducer = gokord.NewTimer(d, func(stop chan<- interface{}) { - dg.LogDebug("Periodic reducer") + dg.Logger().Debug("periodic reducer") user.PeriodicReducer(dg) }) }, diff --git a/updates.json b/updates.json index 173aff0..81e8917 100644 --- a/updates.json +++ b/updates.json @@ -48,6 +48,6 @@ "removed": [], "updated": [] }, - "changelog": "Nouvelle config très stylée par @ascpial (merci à lui) !\nAjout du role react (enfin), toujours par @ascpial (encore merci à lui) !\nAmélioration de la commande stats, par @anhgelus et @ascpial.\nRéécriture d'une bonne partie du bot pour remplacer discordgo par [gokord](<https://github.com/nyttikord/gokord>).\n\nLa prochaine version devrait arrivée prochainement, elle touchera surtout des modifications en interne, peut visible par les utilisateurs et les administrateurs." + "changelog": "Nouvelle config très stylée par @ascpial (merci à lui) !\nAjout du role react (enfin), toujours par @ascpial (encore merci à lui) !\nAmélioration de la commande stats, par @anhgelus et @ascpial.\nRéécriture d'une bonne partie du bot pour remplacer discordgo par [gokord](<https://github.com/nyttikord/gokord>).\n\nLa prochaine version devrait arriver prochainement. Elle touchera surtout à du code en interne peu visible par les utilisateurs et les administrateurs." } ] diff --git a/user/level.go b/user/level.go index 88971e6..4303b47 100644 --- a/user/level.go +++ b/user/level.go @@ -18,16 +18,28 @@ func onNewLevel(s bot.Session, m *user.Member, level uint) { xpForLevel := exp.LevelXP(level) for _, role := range cfg.XpRoles { if role.XP <= xpForLevel && !slices.Contains(m.Roles, role.RoleID) { - s.LogDebug("add role %s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) + s.Logger().Debug("add role", "role", role.RoleID, "user", m.DisplayName(), "guild", m.GuildID) err := s.GuildAPI().MemberRoleAdd(m.GuildID, m.User.ID, role.RoleID) if err != nil { - s.LogError(err, "adding role %s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) + s.Logger().Error( + "adding role", + "error", err, + "role", role.RoleID, + "user", m.DisplayName(), + "guild", m.GuildID, + ) } } else if role.XP > xpForLevel && slices.Contains(m.Roles, role.RoleID) { - s.LogDebug("remove role %s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) + s.Logger().Debug("remove role", "role", role.RoleID, "user", m.DisplayName(), "guild", m.GuildID) err := s.GuildAPI().MemberRoleRemove(m.GuildID, m.User.ID, role.RoleID) if err != nil { - s.LogError(err, "removing role s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) + s.Logger().Error( + "removing role", + "error", err, + "role", role.RoleID, + "user", m.DisplayName(), + "guild", m.GuildID, + ) } } } @@ -36,7 +48,7 @@ func onNewLevel(s bot.Session, m *user.Member, level uint) { func (c *Copaing) OnNewLevel(s *discordgo.Session, level uint) { m, err := s.GuildAPI().Member(c.GuildID, c.DiscordID) if err != nil { - s.LogError(err, "getting member %s in %s for new level", c.DiscordID, c.GuildID) + s.Logger().Error("getting member for new level", "error", err, "user", c.DiscordID, "guild", c.GuildID) return } onNewLevel(s, m, level) @@ -46,7 +58,7 @@ func PeriodicReducer(s *discordgo.Session) { wg := &sync.WaitGroup{} var cs []*Copaing if err := gokord.DB.Find(&cs).Error; err != nil { - s.LogError(err, "fetching all copaings") + s.Logger().Error("fetching all copaings", "error", err) return } cxps := make([]*cXP, len(cs)) @@ -57,9 +69,9 @@ func PeriodicReducer(s *discordgo.Session) { wg.Add(1) go func() { defer wg.Done() - xp, err := c.GetXP() + xp, err := c.GetXP(s.Logger()) if err != nil { - s.LogError(err, "getting xp of copaing %d in %s", c.ID, c.GuildID) + s.Logger().Error("getting xp", "error", err, "copaing", c.ID, "guild", c.GuildID) xp = 0 } cxps[i] = &cXP{ @@ -81,26 +93,26 @@ func PeriodicReducer(s *discordgo.Session) { Where("guild_id = ? and created_at < ?", g.ID, exp.TimeStampNDaysBefore(cfg.DaysXPRemains)). Delete(&CopaingXP{}) if res.Error != nil { - s.LogError(res.Error, "removing old xp in %s", g.ID) + s.Logger().Error("removing old xp", "error", res.Error, "guild", g.ID) } - s.LogDebug("Guild cleaned %s, rows affected: %d", g.Name, res.RowsAffected) + s.Logger().Debug("guild cleaned", "guild", g.Name, "rows affected", res.RowsAffected) }() } wg.Wait() for i, c := range cxps { if i%50 == 49 { - s.LogDebug("Sleeping...") + s.Logger().Debug("sleeping...") time.Sleep(15 * time.Second) // prevents spamming the API } oldXp := c.GetXP() - xp, err := c.ToCopaing().GetXP() + xp, err := c.ToCopaing().GetXP(s.Logger()) if err != nil { - s.LogError(err, "getting xp of copaing %s in %s", c.ID, c.GuildID) + s.Logger().Error("getting xp of copaing", "error", err, "copaing", c.ID, "guild", c.GuildID) continue } if exp.Level(oldXp) != exp.Level(xp) { c.OnNewLevel(s, exp.Level(xp)) } } - s.LogDebug("Periodic reduce finished for %d guilds", i) + s.Logger().Debug("periodic reduce finished", "guilds affected", i) } @@ -1,6 +1,7 @@ package user import ( + "log/slog" "slices" "sync" @@ -8,7 +9,6 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" "github.com/nyttikord/gokord/bot" - "github.com/nyttikord/gokord/logger" "github.com/nyttikord/gokord/user" ) @@ -26,16 +26,16 @@ func (c *cXP) GetXP() uint { } func (c *Copaing) AddXP(s bot.Session, m *user.Member, xp uint, fn func(uint, uint)) { - old, err := c.GetXP() + old, err := c.GetXP(s.Logger()) if err != nil { - s.LogError(err, "getting xp for %s in %s", m.DisplayName(), c.GuildID) + s.Logger().Error("getting xp", "error", err, "user", m.DisplayName(), "guild", c.GuildID) return } pastLevel := exp.Level(old) - s.LogDebug("Adding xp to %s, old: %d, to add: %d", m.DisplayName(), old, xp) + s.Logger().Debug("adding xp", "user", m.DisplayName(), "old", old, "to add", xp) c.CopaingXPs = append(c.CopaingXPs, CopaingXP{CopaingID: c.ID, XP: xp, GuildID: c.GuildID}) if err = c.Save(); err != nil { - s.LogError(err, "saving user %s with xp %d in %s", m.DisplayName(), xp, c.GuildID) + s.Logger().Error("saving user", "error", err, "user", m.DisplayName(), "xp", xp, "guild", c.GuildID) return } newLevel := exp.Level(old + xp) @@ -45,12 +45,12 @@ func (c *Copaing) AddXP(s bot.Session, m *user.Member, xp uint, fn func(uint, ui } } -func (c *Copaing) GetXP() (uint, error) { +func (c *Copaing) GetXP(logger *slog.Logger) (uint, error) { cfg := config.GetGuildConfig(c.GuildID) - return c.GetXPForDays(cfg.DaysXPRemains) + return c.GetXPForDays(logger, cfg.DaysXPRemains) } -func (c *Copaing) GetXPForDays(n uint) (uint, error) { +func (c *Copaing) GetXPForDays(logger *slog.Logger, n uint) (uint, error) { xp := uint(0) rows, err := gokord.DB. Model(&CopaingXP{}). @@ -69,7 +69,7 @@ func (c *Copaing) GetXPForDays(n uint) (uint, error) { var cxp CopaingXP err = gokord.DB.ScanRows(rows, &cxp) if err != nil { - logger.Log(logger.LevelError, 0, "scanning rows of copaing %d in %s: %#v", c.ID, c.GuildID, err.Error()) + logger.Error("scanning rows", "error", err, "copaing", c.ID, "guild", c.GuildID) continue } xp += cxp.XP @@ -80,7 +80,7 @@ func (c *Copaing) GetXPForDays(n uint) (uint, error) { // 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) { +func GetBestXP(logger *slog.Logger, guildId string, n uint, d int) ([]CopaingAccess, error) { if d < 0 { cfg := config.GetGuildConfig(guildId) d = int(cfg.DaysXPRemains) @@ -96,15 +96,15 @@ func GetBestXP(guildId string, n uint, d int) ([]CopaingAccess, error) { var c Copaing err = gokord.DB.ScanRows(rows, &c) if err != nil { - logger.Log(logger.LevelError, 0, "scanning rows of copaing %d in %s: %#v", c.ID, c.GuildID, err.Error()) + logger.Error("scanning rows", "error", err, "copaing", c.ID, "guild", c.GuildID) continue } wg.Add(1) go func() { defer wg.Done() - xp, err := c.GetXPForDays(uint(d)) + xp, err := c.GetXPForDays(logger, uint(d)) if err != nil { - logger.Log(logger.LevelError, 0, "fetching xp of copaing %d in %s: %#v", c.ID, c.GuildID, err.Error()) + logger.Error("fetching xp", "error", err, "copaing", c.ID, "guild", c.GuildID) return } l = append(l, &cXP{Cxp: xp, Copaing: &c}) |
