From d869fa2fa47e71a4c0fea40f468d654d03aa6211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Thu, 11 Sep 2025 12:54:02 +0200 Subject: feat(commands): static colors for stats --- commands/stats.go | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/commands/stats.go b/commands/stats.go index f93f6a0..15fb556 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -3,11 +3,10 @@ package commands import ( "bytes" "errors" - "gorm.io/gorm" + "fmt" "image/color" "io" "math" - "math/rand/v2" "slices" "time" @@ -22,6 +21,7 @@ import ( "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" + "gorm.io/gorm" ) type data struct { @@ -36,18 +36,27 @@ type dbData struct { CopaingID int } +var colors = []color.RGBA{ + {38, 70, 83, 255}, + {42, 157, 143, 255}, + {244, 162, 97, 255}, + {231, 111, 81, 255}, + {193, 18, 31, 255}, +} + func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionMap, resp *cmd.ResponseBuilder) { cfg := config.GetGuildConfig(i.GuildID) - days := cfg.DaysXPRemains + days := 15 if v, ok := opt["days"]; ok { in := v.IntValue() - if in < 0 || uint(in) > days { - if err := resp.SetMessage("Nombre de jours invalide").IsEphemeral().Send(); err != nil { + 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 { logger.Alert("commands/stats.go - Sending invalid days", err.Error()) } return } - days = uint(in) + days = int(in) } err := resp.IsDeferred().Send() if err != nil { @@ -83,13 +92,13 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM }() } -func statsAll(s *discordgo.Session, i *discordgo.InteractionCreate, days uint) (io.WriterTo, error) { +func statsAll(s *discordgo.Session, i *discordgo.InteractionCreate, days int) (io.WriterTo, error) { return stats(s, i, days, func(before, after string) *gorm.DB { - return gokord.DB.Raw(before+"WHERE guild_id = ? and created_at > ?"+after, i.GuildID, exp.TimeStampNDaysBefore(days)) + return gokord.DB.Raw(before+"WHERE guild_id = ? and created_at > ?"+after, i.GuildID, exp.TimeStampNDaysBefore(uint(days))) }) } -func statsMember(s *discordgo.Session, i *discordgo.InteractionCreate, days uint, discordID string) (io.WriterTo, error) { +func statsMember(s *discordgo.Session, i *discordgo.InteractionCreate, days int, discordID string) (io.WriterTo, error) { _, err := s.GuildMember(i.GuildID, discordID) if err != nil { return nil, err @@ -97,12 +106,12 @@ func statsMember(s *discordgo.Session, i *discordgo.InteractionCreate, days uint return stats(s, i, days, func(before, after string) *gorm.DB { return gokord.DB.Raw( before+"WHERE guild_id = ? and created_at > ? and copaing_id = ?"+after, - i.GuildID, exp.TimeStampNDaysBefore(days), user.GetCopaing(discordID, i.GuildID).ID, + i.GuildID, exp.TimeStampNDaysBefore(uint(days)), user.GetCopaing(discordID, i.GuildID).ID, ) }) } -func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days uint, execSql func(before, after string) *gorm.DB) (io.WriterTo, error) { +func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execSql func(before, after string) *gorm.DB) (io.WriterTo, error) { var rawData []*data if gokord.Debug { var rawCopaingData []*user.CopaingXP @@ -188,7 +197,7 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings p.Add(plotter.NewGrid()) - r := rand.New(rand.NewPCG(uint64(time.Now().Unix()), uint64(time.Now().Unix()))) + cnt := 0 for in, c := range copaings { m, err := s.GuildMember(i.GuildID, c.DiscordID) if err != nil { @@ -204,16 +213,15 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings } return 0 }) - l, err := plotter.NewLine(plotter.XYs(stats[in])) + l, _, err := plotter.NewLinePoints(plotter.XYs(stats[in])) if err != nil { logger.Alert("commands/stats.go - Adding line points", err.Error()) return nil, err } - l.LineStyle.Width = vg.Points(1) - l.LineStyle.Dashes = []vg.Length{vg.Points(5), vg.Points(5)} - l.LineStyle.Color = color.RGBA{R: uint8(r.UintN(255)), G: uint8(r.UintN(255)), B: uint8(r.UintN(255)), A: 255} + l.Color = colors[cnt%len(colors)] p.Add(l) p.Legend.Add(m.DisplayName(), l) + cnt++ } w, err := p.WriterTo(8*vg.Inch, 6*vg.Inch, "png") if err != nil { -- cgit v1.2.3 From ad8f65fec5c7e1e0ec0b3d4e992ffc67a0357661 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Thu, 11 Sep 2025 12:58:03 +0200 Subject: feat(db): remove xp when copaing leaves --- events.go | 14 +++++++++++++- user/level.go | 2 +- user/member.go | 5 ----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/events.go b/events.go index 6f15fd8..abf9d03 100644 --- a/events.go +++ b/events.go @@ -8,6 +8,7 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" + "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) @@ -122,7 +123,18 @@ func OnLeave(_ *discordgo.Session, e *discordgo.GuildMemberRemove) { return } c := user.GetCopaing(e.User.ID, e.GuildID) - if err := c.Delete(); err != nil { + err := gokord.DB. + Where("copaing_id = ? and guild_id = ?", c.ID, e.GuildID). + Delete(&user.CopaingXP{}). + Error + if err != nil { + logger.Alert( + "events.go - deleting user xp from db", err.Error(), + "user_id", e.User.ID, + "guild_id", e.GuildID, + ) + } + if err = c.Delete(); err != nil { logger.Alert( "events.go - deleting user from db", err.Error(), "user_id", e.User.ID, diff --git a/user/level.go b/user/level.go index be7d212..cf4d99b 100644 --- a/user/level.go +++ b/user/level.go @@ -64,7 +64,7 @@ func PeriodicReducer(dg *discordgo.Session) { } cxps := make([]*cXP, len(cs)) for i, c := range cs { - if i%10 == 9 { + if i%25 == 24 { wg.Wait() // prevents spamming the DB } wg.Add(1) diff --git a/user/member.go b/user/member.go index ad8762f..9068a6f 100644 --- a/user/member.go +++ b/user/member.go @@ -26,11 +26,6 @@ type CopaingAccess interface { GetXP() uint } -const ( - LastEvent = "last_event" - AlreadyRemoved = "already_removed" -) - func GetCopaing(discordID string, guildID string) *Copaing { c := Copaing{DiscordID: discordID, GuildID: guildID} if err := c.Load(); err != nil { -- cgit v1.2.3 From 83d07520ac4a3e2a82d11435ca5af4e24fea1a7c Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Thu, 11 Sep 2025 13:43:07 +0200 Subject: build(gokord): upgrade to latest nightly --- go.mod | 20 +++++++++++--------- go.sum | 14 ++++++++++++++ main.go | 8 ++++---- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 5a9a1fb..c46a307 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,16 @@ module git.anhgelus.world/anhgelus/les-copaings-bot -go 1.24 +go 1.24.0 + +toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3 - github.com/nyttikord/gokord v0.30.0 + github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae github.com/joho/godotenv v1.5.1 + github.com/nyttikord/gokord v0.30.0 github.com/pelletier/go-toml/v2 v2.2.4 gorm.io/driver/postgres v1.6.0 - gorm.io/gorm v1.30.3 + gorm.io/gorm v1.30.5 ) require ( @@ -29,11 +31,11 @@ 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.13.0 // indirect - golang.org/x/crypto v0.41.0 // indirect + github.com/redis/go-redis/v9 v9.14.0 // indirect + golang.org/x/crypto v0.42.0 // indirect golang.org/x/image v0.30.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect gonum.org/v1/plot v0.16.0 // indirect ) diff --git a/go.sum b/go.sum index ea40119..2c43204 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/anhgelus/gokord v0.11.1-0.20250821122244-0aee6c37eef6 h1:4eO/9UqTPfrK github.com/anhgelus/gokord v0.11.1-0.20250821122244-0aee6c37eef6/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3 h1:j7Im8+Vd7BIhBPQKsK5Hs2BsyO71Q3/XVxgZntNJa5M= github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= +github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae h1:7UFLx1EybWFZ5wW+x2PLZyJqwSjiO7kLMIaisX4pUxk= +github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= 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= @@ -78,6 +80,8 @@ github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgv github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= github.com/redis/go-redis/v9 v9.13.0 h1:PpmlVykE0ODh8P43U0HqC+2NXHXwG+GUtQyz+MPKGRg= github.com/redis/go-redis/v9 v9.13.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +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/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= @@ -92,6 +96,8 @@ golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/image v0.30.0 h1:jD5RhkmVAnjqaCUXfbGBrn3lpxbknfN9w2UhHHU+5B4= golang.org/x/image v0.30.0/go.mod h1:SAEUTxCCMWSrJcCy/4HwavEsfZZJlYxeHLc6tTiAe/c= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -103,6 +109,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -112,6 +120,8 @@ golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -119,6 +129,8 @@ golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -139,4 +151,6 @@ gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= gorm.io/gorm v1.30.3 h1:QiG8upl0Sg9ba2Zatfjy0fy4It2iNBL2/eMdvEkdXNs= gorm.io/gorm v1.30.3/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/gorm v1.30.5 h1:dvEfYwxL+i+xgCNSGGBT1lDjCzfELK8fHZxL3Ee9X0s= +gorm.io/gorm v1.30.5/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= diff --git a/main.go b/main.go index facf243..71f31b5 100644 --- a/main.go +++ b/main.go @@ -68,7 +68,7 @@ func main() { topCmd := cmd.New("top", "Copaings les plus actifs"). SetHandler(commands.Top) - resetCmd := cmd.New("reset", "Reset l'xp"). + /*resetCmd := cmd.New("reset", "Reset l'xp"). SetHandler(commands.Reset). SetPermission(&adm) @@ -82,7 +82,7 @@ func main() { SetPermission(&adm) creditsCmd := cmd.New("credits", "Crédits"). - SetHandler(commands.Credits) + SetHandler(commands.Credits)*/ statsCmd := cmd.New("stats", "Affiche des stats :D"). AddOption(cmd.NewOption( @@ -126,9 +126,9 @@ func main() { rankCmd, configCmd, topCmd, - resetCmd, + /*resetCmd, resetUserCmd, - creditsCmd, + creditsCmd,*/ statsCmd, }, AfterInit: func(dg *discordgo.Session) { -- cgit v1.2.3 From f9b2367fe3e75b9d26a0c7c87bbfb85e9606a2c8 Mon Sep 17 00:00:00 2001 From: ascpial Date: Thu, 11 Sep 2025 14:21:26 +0200 Subject: feat(stats): nicer font in stats graph --- assets/inter-variable.ttf | Bin 0 -> 874708 bytes main.go | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 assets/inter-variable.ttf diff --git a/assets/inter-variable.ttf b/assets/inter-variable.ttf new file mode 100644 index 0000000..e31b51e Binary files /dev/null and b/assets/inter-variable.ttf differ diff --git a/main.go b/main.go index 71f31b5..b529193 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,9 @@ import ( "github.com/anhgelus/gokord/logger" "github.com/joho/godotenv" discordgo "github.com/nyttikord/gokord" + "golang.org/x/image/font/opentype" + "gonum.org/v1/plot" + "gonum.org/v1/plot/font" ) var ( @@ -30,12 +33,31 @@ var ( stopPeriodicReducer chan<- interface{} ) +//go:embed assets/inter-variable.ttf +var interTTF []byte + func init() { err := godotenv.Load() if err != nil && !errors.Is(err, os.ErrNotExist) { logger.Warn("Error while loading .env file", "error", err.Error()) } flag.StringVar(&token, "token", os.Getenv("TOKEN"), "token of the bot") + + // Use a nicer font + fontTTF, parseErr := opentype.Parse(interTTF) + if parseErr != nil { + panic(err) + } + inter := font.Font{Typeface: "Inter"} + font.DefaultCache.Add( + []font.Face{ + { + Font: inter, + Face: fontTTF, + }, + }) + plot.DefaultFont = inter + } func main() { -- cgit v1.2.3 From 8cec1c5a30f9bf679f3b4704b27684b4c4bf531b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Thu, 11 Sep 2025 14:35:32 +0200 Subject: docs(info): add inter as deps in readme and credits --- README.md | 5 +++++ commands/credits.go | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fea1593..6355f32 100644 --- a/README.md +++ b/README.md @@ -87,3 +87,8 @@ in `.env`) - Go 1.24 - anhgelus/gokord + +## License + +This project uses [Inter](https://github.com/rsms/inter), an open font. +Check its license [here](https://github.com/rsms/inter/blob/master/LICENSE.txt) (SIL OPEN FONT LICENSE Version 1.1). diff --git a/commands/credits.go b/commands/credits.go index f0a8c46..d58547e 100644 --- a/commands/credits.go +++ b/commands/credits.go @@ -11,7 +11,8 @@ func Credits(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionM msg := "**Les Copaings**, le bot gérant les serveurs privés de [anhgelus]().\n" msg += "Code source : \n\n" msg += "Host du bot : " + gokord.BaseCfg.GetAuthor() + ".\n\n" - msg += "Utilise :\n- [anhgelus/gokord]()" + msg += "Utilise :\n- [anhgelus/gokord]()\n" + msg += "- [Inter]()" err := resp.SetMessage(msg).Send() if err != nil { logger.Alert("commands/credits.go - Sending credits", err.Error(), "guild_id", i.GuildID) -- cgit v1.2.3 From a7d95c1248631058754445e8b487bd6b17c003e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Thu, 11 Sep 2025 23:36:35 +0200 Subject: fix(commands): some were wrongly disabled --- main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index b529193..3d32389 100644 --- a/main.go +++ b/main.go @@ -90,7 +90,7 @@ func main() { topCmd := cmd.New("top", "Copaings les plus actifs"). SetHandler(commands.Top) - /*resetCmd := cmd.New("reset", "Reset l'xp"). + resetCmd := cmd.New("reset", "Reset l'xp"). SetHandler(commands.Reset). SetPermission(&adm) @@ -104,7 +104,7 @@ func main() { SetPermission(&adm) creditsCmd := cmd.New("credits", "Crédits"). - SetHandler(commands.Credits)*/ + SetHandler(commands.Credits) statsCmd := cmd.New("stats", "Affiche des stats :D"). AddOption(cmd.NewOption( @@ -148,9 +148,9 @@ func main() { rankCmd, configCmd, topCmd, - /*resetCmd, + resetCmd, resetUserCmd, - creditsCmd,*/ + creditsCmd, statsCmd, }, AfterInit: func(dg *discordgo.Session) { -- cgit v1.2.3 From 8885566932c965926ee64fad6404e6f26bc13220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 13 Sep 2025 13:32:01 +0200 Subject: build(gokord): upgrade to latest version --- commands/config.go | 36 +---------- commands/rank.go | 4 +- commands/reset.go | 2 +- commands/stats.go | 9 +-- commands/top.go | 7 ++- config/channel.go | 116 +++++++++++++++++------------------ config/xp_reduce.go | 87 +++++++++++++------------- config/xp_role.go | 171 ++++++++++++++++++++++++++-------------------------- events.go | 4 +- go.mod | 6 +- go.sum | 6 ++ main.go | 19 +++--- user/level.go | 9 +-- user/xp.go | 3 +- 14 files changed, 226 insertions(+), 253 deletions(-) diff --git a/commands/config.go b/commands/config.go index c4644bc..838f7e9 100644 --- a/commands/config.go +++ b/commands/config.go @@ -7,7 +7,6 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) @@ -50,14 +49,6 @@ func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMa defaultChan = fmt.Sprintf("<#%s>", cfg.FallbackChannel) } //comp := component.New(). - // Add(component.NewTextDisplay("# Config")). - // Add(component.NewTextDisplay("**Salon par défaut**\n" + defaultChan)). - // Add(component.NewSeparator()). - // Add(component.NewTextDisplay("**Rôles liés aux niveaux**\n" + roles)). - // Add(component.NewSeparator()). - // Add(component.NewTextDisplay("**Salons désactivés**\n" + chans)). - // Add(component.NewSeparator()). - // Add(component.NewTextDisplay(fmt.Sprintf("**%s**\n%d", "Jours avant la réduction", cfg.DaysXPRemains))). // Add(component.NewActionRow().Add(component.NewStringSelect(ConfigModify). // SetPlaceholder("Modifier..."). // AddOption( @@ -82,31 +73,6 @@ func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMa // SetEmoji(&discordgo.ComponentEmoji{Name: "⌛"}), // ), // )) - comp := component.New(). - Add(component.NewActionRow().Add(component.NewStringSelect(ConfigModify). - SetPlaceholder("Modifier..."). - AddOption( - component.NewSelectOption("Rôles liés à l'XP", config.ModifyXpRole). - SetDescription("Gère les rôles liés à l'XP"). - SetEmoji(&discordgo.ComponentEmoji{Name: "🏅"}), - ). - AddOption( - component.NewSelectOption("Salons désactivés", config.ModifyDisChannel). - SetDescription("Gère les salons désactivés"). - SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), - ). - AddOption( - // I don't have a better idea for this... - component.NewSelectOption("Salons par défaut", config.ModifyFallbackChannel). - SetDescription("Spécifie le salon par défaut"). - SetEmoji(&discordgo.ComponentEmoji{Name: "💾"}), - ). - AddOption( - component.NewSelectOption("Temps avec la réduction", config.ModifyTimeReduce). - SetDescription("Gère le temps avant la réduction d'XP"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⌛"}), - ), - )) msg := fmt.Sprintf( "# Config\n**Salon par défaut**\n%s\n\n**Rôles liés aux niveaux**\n%s\n\n**Salons désactivés**\n%s\n\n**Jours avant la réduction**\n%d", defaultChan, @@ -114,7 +80,7 @@ func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMa chans, cfg.DaysXPRemains, ) - err := resp.SetComponents(comp).SetMessage(msg).IsEphemeral().Send() + err := resp.SetMessage(msg).IsEphemeral().Send() if err != nil { logger.Alert("config/guild.go - Sending config", err.Error()) } diff --git a/commands/rank.go b/commands/rank.go index 94dabf2..0adfde6 100644 --- a/commands/rank.go +++ b/commands/rank.go @@ -16,14 +16,14 @@ func Rank(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.Optio m := i.Member var err error if v, ok := optMap["copaing"]; ok { - u := v.UserValue(s) + u := v.UserValue(s.UserAPI()) if u.Bot { err = resp.SetMessage("Imagine si les bots avaient un niveau :rolling_eyes:").IsEphemeral().Send() if err != nil { logger.Alert("commands/rank.go - Reply error user is a bot", err.Error()) } } - m, err = s.GuildMember(i.GuildID, u.ID) + m, err = s.GuildAPI().Member(i.GuildID, u.ID) if err != nil { logger.Alert( "commands/rank.go - Fetching guild member", diff --git a/commands/reset.go b/commands/reset.go index 07e3ba3..f50bb21 100644 --- a/commands/reset.go +++ b/commands/reset.go @@ -25,7 +25,7 @@ func ResetUser(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd. } return } - m := v.UserValue(s) + m := v.UserValue(s.UserAPI()) if m.Bot { if err := resp.SetMessage("Les bots n'ont pas de niveau :upside_down:").Send(); err != nil { logger.Alert("commands/reset.go - Copaing not set", err.Error()) diff --git a/commands/stats.go b/commands/stats.go index 15fb556..1a7a379 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -18,6 +18,7 @@ import ( "github.com/anhgelus/gokord/logger" "github.com/jackc/pgx/v5/pgtype" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/channel" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" @@ -66,7 +67,7 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM go func() { var w io.WriterTo if v, ok := opt["user"]; ok { - w, err = statsMember(s, i, days, v.UserValue(s).ID) + w, err = statsMember(s, i, days, v.UserValue(s.UserAPI()).ID) } else { w, err = statsAll(s, i, days) } @@ -81,7 +82,7 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM if err != nil { logger.Alert("commands/stats.go - Writing png", err.Error()) } - err = resp.AddFile(&discordgo.File{ + err = resp.AddFile(&channel.File{ Name: "plot.png", ContentType: "image/png", Reader: b, @@ -99,7 +100,7 @@ func statsAll(s *discordgo.Session, i *discordgo.InteractionCreate, days int) (i } func statsMember(s *discordgo.Session, i *discordgo.InteractionCreate, days int, discordID string) (io.WriterTo, error) { - _, err := s.GuildMember(i.GuildID, discordID) + _, err := s.GuildAPI().Member(i.GuildID, discordID) if err != nil { return nil, err } @@ -199,7 +200,7 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings cnt := 0 for in, c := range copaings { - m, err := s.GuildMember(i.GuildID, c.DiscordID) + m, err := s.GuildAPI().Member(i.GuildID, c.DiscordID) if err != nil { logger.Alert("commands/stats.go - Fetching guild member", err.Error()) return nil, err diff --git a/commands/top.go b/commands/top.go index ecbf6f4..21a1456 100644 --- a/commands/top.go +++ b/commands/top.go @@ -10,6 +10,7 @@ import ( "github.com/anhgelus/gokord/cmd" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/channel" ) func Top(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { @@ -18,7 +19,7 @@ func Top(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, logger.Alert("commands/top.go - Sending deferred", err.Error()) return } - embeds := make([]*discordgo.MessageEmbed, 3) + embeds := make([]*channel.MessageEmbed, 3) wg := sync.WaitGroup{} fn := func(s string, n uint, d int, id int) { @@ -26,14 +27,14 @@ func Top(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, tops, err := user.GetBestXP(i.GuildID, n, d) if err != nil { logger.Alert("commands/top.go - Fetching best xp", err.Error(), "n", n, "d", d, "id", id, "guild_id", i.GuildID) - embeds[id] = &discordgo.MessageEmbed{ + embeds[id] = &channel.MessageEmbed{ Title: s, Description: "Erreur : impossible de récupérer la liste", Color: 0x831010, } return } - embeds[id] = &discordgo.MessageEmbed{ + embeds[id] = &channel.MessageEmbed{ Title: s, Description: genTopsMessage(tops), Color: 0x10E6AD, diff --git a/config/channel.go b/config/channel.go index 537d586..c09061f 100644 --- a/config/channel.go +++ b/config/channel.go @@ -4,9 +4,9 @@ import ( "strings" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/interaction" ) const ( @@ -20,16 +20,16 @@ const ( DisChannelDelSet = "disabled_channel_del_set" ) -func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow().Add( - component.NewChannelSelect(FallbackChannelSet).AddChannelType(discordgo.ChannelTypeGuildText), - ))).Send() - if err != nil { - logger.Alert("config/channel.go - Sending channel list for fallback", err.Error()) - } +func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow().Add( + // component.NewChannelSelect(FallbackChannelSet).AddChannelType(discordgo.ChannelTypeGuildText), + //))).Send() + //if err != nil { + // logger.Alert("config/channel.go - Sending channel list for fallback", err.Error()) + //} } -func HandleFallbackChannelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { +func HandleFallbackChannelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) @@ -49,61 +49,61 @@ func HandleFallbackChannelSet(_ *discordgo.Session, i *discordgo.InteractionCrea } } -func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow(). - Add( - component.NewButton(DisChannelAdd, discordgo.PrimaryButton). - SetLabel("Désactiver un salon"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⬇️"}), - ). - Add( - component.NewButton(DisChannelDel, discordgo.DangerButton). - SetLabel("Réactiver un salon"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), - ), - )).Send() - if err != nil { - logger.Alert("config/channel.go - Sending action type", err.Error()) - } +func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow(). + // Add( + // component.NewButton(DisChannelAdd, discordgo.PrimaryButton). + // SetLabel("Désactiver un salon"). + // SetEmoji(&discordgo.ComponentEmoji{Name: "⬇️"}), + // ). + // Add( + // component.NewButton(DisChannelDel, discordgo.DangerButton). + // SetLabel("Réactiver un salon"). + // SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), + // ), + //)).Send() + //if err != nil { + // logger.Alert("config/channel.go - Sending action type", err.Error()) + //} } -func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral().SetMessage("Salon à désactiver...") - cID := DisChannelAddSet - if data.CustomID == DisChannelDel { - resp.SetMessage("Salon à réactiver...") - cID = DisChannelDelSet - } - err := resp.SetComponents(component.New().Add(component.NewActionRow().Add(component.NewChannelSelect(cID)))).Send() - if err != nil { - logger.Alert("config/channel.go - Sending channel list for disable", err.Error()) - } +func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //resp.IsEphemeral().SetMessage("Salon à désactiver...") + //cID := DisChannelAddSet + //if data.CustomID == DisChannelDel { + // resp.SetMessage("Salon à réactiver...") + // cID = DisChannelDelSet + //} + //err := resp.SetComponents(component.New().Add(component.NewActionRow().Add(component.NewChannelSelect(cID)))).Send() + //if err != nil { + // logger.Alert("config/channel.go - Sending channel list for disable", err.Error()) + //} } -func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - cfg := GetGuildConfig(i.GuildID) - id := data.Values[0] - if strings.Contains(cfg.DisabledChannels, id) { - err := resp.SetMessage("Le salon est déjà dans la liste des salons désactivés").Send() - if err != nil { - logger.Alert("commands/config.go - Channel already disabled", err.Error()) - } - return - } - cfg.DisabledChannels += id + ";" - if err := cfg.Save(); err != nil { - logger.Alert("commands/config.go - Saving config disable add", err.Error()) - if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving config", err.Error()) - } - } - if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { - logger.Alert("commands/config.go - Modification saved message disable add", err.Error()) - } +func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //resp.IsEphemeral() + //cfg := GetGuildConfig(i.GuildID) + //id := data.Values[0] + //if strings.Contains(cfg.DisabledChannels, id) { + // err := resp.SetMessage("Le salon est déjà dans la liste des salons désactivés").Send() + // if err != nil { + // logger.Alert("commands/config.go - Channel already disabled", err.Error()) + // } + // return + //} + //cfg.DisabledChannels += id + ";" + //if err := cfg.Save(); err != nil { + // logger.Alert("commands/config.go - Saving config disable add", err.Error()) + // if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { + // logger.Alert("config/channel.go - Sending error while saving config", err.Error()) + // } + //} + //if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { + // logger.Alert("commands/config.go - Modification saved message disable add", err.Error()) + //} } -func HandleDisChannelDelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { +func HandleDisChannelDelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) id := data.Values[0] diff --git a/config/xp_reduce.go b/config/xp_reduce.go index defc54b..4bcdd1e 100644 --- a/config/xp_reduce.go +++ b/config/xp_reduce.go @@ -1,12 +1,9 @@ package config import ( - "strconv" - "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/interaction" ) const ( @@ -14,47 +11,47 @@ const ( TimeReduceSet = "time_reduce_set" ) -func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsModal(). - SetCustomID(TimeReduceSet). - SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( - component.NewTextInput(TimeReduceSet, "Jours avant la réduction", discordgo.TextInputShort). - SetMinLength(1). - SetMaxLength(3), - ))).Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Sending modal for periodic reduce", err.Error()) - } +func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //err := resp.IsModal(). + // SetCustomID(TimeReduceSet). + // SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( + // component.NewTextInput(TimeReduceSet, "Jours avant la réduction", discordgo.TextInputShort). + // SetMinLength(1). + // SetMaxLength(3), + // ))).Send() + //if err != nil { + // logger.Alert("config/xp_reduce.go - Sending modal for periodic reduce", err.Error()) + //} } -func HandleTimeReduceSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.ModalSubmitInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - v := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value - days, err := strconv.Atoi(v) - if err != nil { - logger.Debug(err.Error()) - if err = resp.SetMessage("Nombres de jours invalides. Merci de mettre un entier.").Send(); err != nil { - logger.Alert("config/xp_reduce.go - Sending bad input", err.Error()) - } - return - } - if days < 30 { - err = resp.SetMessage("Le nombre de jours est inférieur à 30.").Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Days < 30 (fallback)", err.Error()) - } - return - } - cfg := GetGuildConfig(i.GuildID) - cfg.DaysXPRemains = uint(days) - if err = cfg.Save(); err != nil { - logger.Alert("config/channel.go - Saving days xp remains", err.Error()) - if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { - logger.Alert("config/xp_reduce.go - Sending error while saving days xp remains", err.Error()) - } - return - } - if err = resp.SetMessage("Modification sauvegardée.").Send(); err != nil { - logger.Alert("config/xp_reduce.go - Sending days saved", err.Error()) - } +func HandleTimeReduceSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { + //resp.IsEphemeral() + //v := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value + //days, err := strconv.Atoi(v) + //if err != nil { + // logger.Debug(err.Error()) + // if err = resp.SetMessage("Nombres de jours invalides. Merci de mettre un entier.").Send(); err != nil { + // logger.Alert("config/xp_reduce.go - Sending bad input", err.Error()) + // } + // return + //} + //if days < 30 { + // err = resp.SetMessage("Le nombre de jours est inférieur à 30.").Send() + // if err != nil { + // logger.Alert("config/xp_reduce.go - Days < 30 (fallback)", err.Error()) + // } + // return + //} + //cfg := GetGuildConfig(i.GuildID) + //cfg.DaysXPRemains = uint(days) + //if err = cfg.Save(); err != nil { + // logger.Alert("config/channel.go - Saving days xp remains", err.Error()) + // if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { + // logger.Alert("config/xp_reduce.go - Sending error while saving days xp remains", err.Error()) + // } + // return + //} + //if err = resp.SetMessage("Modification sauvegardée.").Send(); err != nil { + // logger.Alert("config/xp_reduce.go - Sending days saved", err.Error()) + //} } diff --git a/config/xp_role.go b/config/xp_role.go index 97de8be..39e48f6 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -2,15 +2,12 @@ package config import ( "fmt" - "strconv" - "time" - "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/component" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/interaction" ) type XpRole struct { @@ -36,50 +33,50 @@ var ( configModifyMap = map[string]uint{} ) -func HandleModifyXpRole(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral(). - SetMessage("Action à réaliser"). - SetComponents(component.New().Add(component.NewActionRow(). - Add(component.NewButton(XpRoleAdd, discordgo.PrimaryButton). - SetLabel("Ajouter"). - SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), - ). - Add(component.NewButton(XpRoleEdit, discordgo.SecondaryButton). - SetLabel("Modifier"). - SetEmoji(&discordgo.ComponentEmoji{Name: "📝"}), - ). - Add(component.NewButton(XpRoleDel, discordgo.DangerButton). - SetLabel("Supprimer"). - SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), - ), - )).Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Sending config", err.Error()) - } +func HandleModifyXpRole(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //err := resp.IsEphemeral(). + // SetMessage("Action à réaliser"). + // SetComponents(component.New().Add(component.NewActionRow(). + // Add(component.NewButton(XpRoleAdd, discordgo.PrimaryButton). + // SetLabel("Ajouter"). + // SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), + // ). + // Add(component.NewButton(XpRoleEdit, discordgo.SecondaryButton). + // SetLabel("Modifier"). + // SetEmoji(&discordgo.ComponentEmoji{Name: "📝"}), + // ). + // Add(component.NewButton(XpRoleDel, discordgo.DangerButton). + // SetLabel("Supprimer"). + // SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), + // ), + // )).Send() + //if err != nil { + // logger.Alert("config/xp_reduce.go - Sending config", err.Error()) + //} } -func HandleXpRoleAddEdit(_ *discordgo.Session, _ *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - cID := XpRoleAddLevel - if data.CustomID == XpRoleEdit { - cID = XpRoleEditLevel - } - err := resp.IsModal(). - SetTitle("Role"). - SetCustomID(cID). - SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( - component.NewTextInput(cID, "Niveau", discordgo.TextInputShort). - SetPlaceholder("5"). - IsRequired(). - SetMinLength(0). - SetMaxLength(5), - ))). - Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Sending modal to add/edit", err.Error()) - } +func HandleXpRoleAddEdit(_ *discordgo.Session, _ *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //cID := XpRoleAddLevel + //if data.CustomID == XpRoleEdit { + // cID = XpRoleEditLevel + //} + //err := resp.IsModal(). + // SetTitle("Role"). + // SetCustomID(cID). + // SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( + // component.NewTextInput(cID, "Niveau", discordgo.TextInputShort). + // SetPlaceholder("5"). + // IsRequired(). + // SetMinLength(0). + // SetMaxLength(5), + // ))). + // Send() + //if err != nil { + // logger.Alert("config/xp_reduce.go - Sending modal to add/edit", err.Error()) + //} } -func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { +func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) roleId := data.Values[0] @@ -111,7 +108,7 @@ func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, d } } -func HandleXpRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { +func HandleXpRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) roleId := data.Values[0] @@ -139,17 +136,17 @@ func HandleXpRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, } } -func HandleXpRoleDel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { - err := resp.IsEphemeral(). - SetMessage("Rôle à supprimer"). - SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(XpRoleDelRole)))). - Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Sending response to del", err.Error()) - } +func HandleXpRoleDel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + //err := resp.IsEphemeral(). + // SetMessage("Rôle à supprimer"). + // SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(XpRoleDelRole)))). + // Send() + //if err != nil { + // logger.Alert("config/xp_reduce.go - Sending response to del", err.Error()) + //} } -func HandleXpRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { +func HandleXpRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) roleId := data.Values[0] @@ -176,39 +173,39 @@ func HandleXpRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, d } } -func HandleXpRoleLevel(_ *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.ModalSubmitInteractionData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - input := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput) - - k := getKeyConfigRole(i) - in, err := strconv.Atoi(input.Value) - if err != nil || in < 0 { - if err = resp. - SetMessage("Impossible de lire le nombre. Il doit s'agit d'un nombre entier positif."). - Send(); err != nil { - logger.Alert("command/config.go - Sending bad number", err.Error()) - } - return - } - configModifyMap[k] = exp.LevelXP(uint(in)) - go func(i *discordgo.InteractionCreate, k string) { - time.Sleep(5 * time.Minute) - delete(configModifyMap, k) - }(i, k) - - cID := XpRoleAddRole - resp.SetMessage("Rôle à ajouter") - if data.CustomID == XpRoleEditLevel { - cID = XpRoleEditRole - resp.SetMessage("Rôle à modifier") - } - - err = resp. - SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(cID)))). - Send() - if err != nil { - logger.Alert("config/xp_reduce.go - Sending response to add/edit", err.Error()) - } +func HandleXpRoleLevel(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { + //resp.IsEphemeral() + //input := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput) + // + //k := getKeyConfigRole(i) + //in, err := strconv.Atoi(input.Value) + //if err != nil || in < 0 { + // if err = resp. + // SetMessage("Impossible de lire le nombre. Il doit s'agit d'un nombre entier positif."). + // Send(); err != nil { + // logger.Alert("command/config.go - Sending bad number", err.Error()) + // } + // return + //} + //configModifyMap[k] = exp.LevelXP(uint(in)) + //go func(i *discordgo.InteractionCreate, k string) { + // time.Sleep(5 * time.Minute) + // delete(configModifyMap, k) + //}(i, k) + // + //cID := XpRoleAddRole + //resp.SetMessage("Rôle à ajouter") + //if data.CustomID == XpRoleEditLevel { + // cID = XpRoleEditRole + // resp.SetMessage("Rôle à modifier") + //} + // + //err = resp. + // SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(cID)))). + // Send() + //if err != nil { + // logger.Alert("config/xp_reduce.go - Sending response to add/edit", err.Error()) + //} } func getKeyConfigRole(i *discordgo.InteractionCreate) string { diff --git a/events.go b/events.go index abf9d03..cae0ef3 100644 --- a/events.go +++ b/events.go @@ -38,7 +38,7 @@ func OnMessage(s *discordgo.Session, m *discordgo.MessageCreate) { m.Member.GuildID = m.GuildID xp := min(exp.MessageXP(uint(len(trimmed)), exp.CalcDiversity(trimmed)), MaxXpPerMessage) c.AddXP(s, m.Member, xp, func(_ uint, _ uint) { - if err := s.MessageReactionAdd(m.ChannelID, m.Message.ID, "⬆"); err != nil { + if err := s.ChannelAPI().MessageReactionAdd(m.ChannelID, m.Message.ID, "⬆"); err != nil { logger.Alert( "events.go - add reaction for new level", err.Error(), "channel id", m.ChannelID, @@ -108,7 +108,7 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { if len(cfg.FallbackChannel) == 0 { return } - _, err := s.ChannelMessageSend(cfg.FallbackChannel, fmt.Sprintf( + _, err := s.ChannelAPI().MessageSend(cfg.FallbackChannel, fmt.Sprintf( "%s est maintenant niveau %d", e.Member.Mention(), newLevel, )) if err != nil { diff --git a/go.mod b/go.mod index c46a307..ea40184 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,12 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae + github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.30.0 + github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb github.com/pelletier/go-toml/v2 v2.2.4 gorm.io/driver/postgres v1.6.0 - gorm.io/gorm v1.30.5 + gorm.io/gorm v1.31.0 ) require ( diff --git a/go.sum b/go.sum index 2c43204..f4ede94 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3 h1:j7Im8+Vd7BIh github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae h1:7UFLx1EybWFZ5wW+x2PLZyJqwSjiO7kLMIaisX4pUxk= github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= +github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be h1:D7bFu20Qr2P+hLgv/bWVhscuQ2tt0y0km8fTVZ5ThmY= +github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be/go.mod h1:J/Ja3EIKFOxxy5lx09kjsxyrwv4ardc015cMtmM8XPg= 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= @@ -70,6 +72,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/nyttikord/gokord v0.30.0 h1:O4LhpCMyfWcgLqziPXQgMCopb9VO7kwcZG3phblOaTA= github.com/nyttikord/gokord v0.30.0/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= +github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb h1:HUL4CikIHguqjKrAqzXYghkzlaZi8+54BBObxBUgeos= +github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= 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= @@ -153,4 +157,6 @@ gorm.io/gorm v1.30.3 h1:QiG8upl0Sg9ba2Zatfjy0fy4It2iNBL2/eMdvEkdXNs= gorm.io/gorm v1.30.3/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= gorm.io/gorm v1.30.5 h1:dvEfYwxL+i+xgCNSGGBT1lDjCzfELK8fHZxL3Ee9X0s= gorm.io/gorm v1.30.5/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= +gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= diff --git a/main.go b/main.go index 3d32389..7db4893 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,9 @@ import ( "github.com/anhgelus/gokord/logger" "github.com/joho/godotenv" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/discord" + "github.com/nyttikord/gokord/discord/types" + "github.com/nyttikord/gokord/interaction" "golang.org/x/image/font/opentype" "gonum.org/v1/plot" "gonum.org/v1/plot/font" @@ -77,7 +80,7 @@ func main() { rankCmd := cmd.New("rank", "Affiche le niveau d'un copaing"). AddOption(cmd.NewOption( - discordgo.ApplicationCommandOptionUser, + types.CommandOptionUser, "copaing", "Le niveau du Copaing que vous souhaitez obtenir", )). @@ -96,7 +99,7 @@ func main() { resetUserCmd := cmd.New("reset-user", "Reset l'xp d'un utilisation"). AddOption(cmd.NewOption( - discordgo.ApplicationCommandOptionUser, + types.CommandOptionUser, "user", "Copaing a reset", ).IsRequired()). @@ -108,12 +111,12 @@ func main() { statsCmd := cmd.New("stats", "Affiche des stats :D"). AddOption(cmd.NewOption( - discordgo.ApplicationCommandOptionInteger, + types.CommandOptionInteger, "days", "Nombre de jours à afficher dans le graphique", )). AddOption(cmd.NewOption( - discordgo.ApplicationCommandOptionUser, + types.CommandOptionUser, "user", "Utilisateur à inspecter", )). @@ -168,13 +171,13 @@ func main() { }, Innovations: innovations, Version: &Version, - Intents: discordgo.IntentsAllWithoutPrivileged | - discordgo.IntentsMessageContent | - discordgo.IntentGuildMembers, + Intents: discord.IntentsAllWithoutPrivileged | + discord.IntentsMessageContent | + discord.IntentGuildMembers, } // interaction: /config - bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data discordgo.MessageComponentInteractionData, resp *cmd.ResponseBuilder) { + bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { if len(data.Values) != 1 { logger.Alert("main.go - Handle config modify", "invalid data values", "values", data.Values) return diff --git a/user/level.go b/user/level.go index cf4d99b..6f92ce7 100644 --- a/user/level.go +++ b/user/level.go @@ -10,9 +10,10 @@ import ( "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/user" ) -func onNewLevel(dg *discordgo.Session, m *discordgo.Member, level uint) { +func onNewLevel(dg *discordgo.Session, m *user.Member, level uint) { cfg := config.GetGuildConfig(m.GuildID) xpForLevel := exp.LevelXP(level) for _, role := range cfg.XpRoles { @@ -23,7 +24,7 @@ func onNewLevel(dg *discordgo.Session, m *discordgo.Member, level uint) { "user_id", m.User.ID, "guild_id", m.GuildID, ) - err := dg.GuildMemberRoleAdd(m.GuildID, m.User.ID, role.RoleID) + err := dg.GuildAPI().MemberRoleAdd(m.GuildID, m.User.ID, role.RoleID) if err != nil { logger.Alert("user/level.go - Adding role", err.Error(), "role_id", role.RoleID) } @@ -34,7 +35,7 @@ func onNewLevel(dg *discordgo.Session, m *discordgo.Member, level uint) { "user_id", m.User.ID, "guild_id", m.GuildID, ) - err := dg.GuildMemberRoleRemove(m.GuildID, m.User.ID, role.RoleID) + err := dg.GuildAPI().MemberRoleRemove(m.GuildID, m.User.ID, role.RoleID) if err != nil { logger.Alert("user/level.go - Removing role", err.Error(), "role_id", role.RoleID) } @@ -43,7 +44,7 @@ func onNewLevel(dg *discordgo.Session, m *discordgo.Member, level uint) { } func (c *Copaing) OnNewLevel(dg *discordgo.Session, level uint) { - m, err := dg.GuildMember(c.GuildID, c.DiscordID) + m, err := dg.GuildAPI().Member(c.GuildID, c.DiscordID) if err != nil { logger.Alert( "user/level.go - Getting member for new level", err.Error(), diff --git a/user/xp.go b/user/xp.go index 45080ea..550f3bf 100644 --- a/user/xp.go +++ b/user/xp.go @@ -9,6 +9,7 @@ import ( "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/user" ) type cXP struct { @@ -24,7 +25,7 @@ func (c *cXP) GetXP() uint { return c.Cxp } -func (c *Copaing) AddXP(s *discordgo.Session, m *discordgo.Member, xp uint, fn func(uint, uint)) { +func (c *Copaing) AddXP(s *discordgo.Session, m *user.Member, xp uint, fn func(uint, uint)) { old, err := c.GetXP() if err != nil { logger.Alert("user/xp.go - Getting xp", err.Error(), "discord_id", c.DiscordID, "guild_id", c.GuildID) -- cgit v1.2.3 From e42ecdd7154d740800ef392c6318220944b55a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 13 Sep 2025 21:31:16 +0200 Subject: build(gokord): use latest version --- commands/config.go | 5 ++--- commands/credits.go | 5 ++--- commands/rank.go | 28 +++++++------------------- commands/reset.go | 15 +++++++------- commands/stats.go | 26 ++++++++++++------------ commands/top.go | 15 +++++++------- config/channel.go | 19 +++++++++--------- config/xp_role.go | 46 ++++++++++++++---------------------------- go.mod | 4 ++-- go.sum | 8 ++++++++ main.go | 10 +++++----- user/level.go | 57 ++++++++++++++++++++--------------------------------- user/xp.go | 23 +++++++-------------- 13 files changed, 105 insertions(+), 156 deletions(-) diff --git a/commands/config.go b/commands/config.go index 838f7e9..cc1e942 100644 --- a/commands/config.go +++ b/commands/config.go @@ -7,7 +7,6 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) @@ -15,7 +14,7 @@ const ( ConfigModify = "config_modify" ) -func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Config(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { cfg := config.GetGuildConfig(i.GuildID) roles := "" l := len(cfg.XpRoles) - 1 @@ -82,6 +81,6 @@ func Config(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMa ) err := resp.SetMessage(msg).IsEphemeral().Send() if err != nil { - logger.Alert("config/guild.go - Sending config", err.Error()) + s.LogError(err, "sending config") } } diff --git a/commands/credits.go b/commands/credits.go index d58547e..e5fd711 100644 --- a/commands/credits.go +++ b/commands/credits.go @@ -3,11 +3,10 @@ package commands import ( "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) -func Credits(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Credits(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { msg := "**Les Copaings**, le bot gérant les serveurs privés de [anhgelus]().\n" msg += "Code source : \n\n" msg += "Host du bot : " + gokord.BaseCfg.GetAuthor() + ".\n\n" @@ -15,6 +14,6 @@ func Credits(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionM msg += "- [Inter]()" err := resp.SetMessage(msg).Send() if err != nil { - logger.Alert("commands/credits.go - Sending credits", err.Error(), "guild_id", i.GuildID) + s.LogError(err, "sending credits") } } diff --git a/commands/rank.go b/commands/rank.go index 0adfde6..d3a9f70 100644 --- a/commands/rank.go +++ b/commands/rank.go @@ -6,7 +6,6 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) @@ -20,22 +19,16 @@ func Rank(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.Optio if u.Bot { err = resp.SetMessage("Imagine si les bots avaient un niveau :rolling_eyes:").IsEphemeral().Send() if err != nil { - logger.Alert("commands/rank.go - Reply error user is a bot", err.Error()) + s.LogError(err, "reply error user is a bot") } + return } m, err = s.GuildAPI().Member(i.GuildID, u.ID) if err != nil { - logger.Alert( - "commands/rank.go - Fetching guild member", - err.Error(), - "discord_id", - u.ID, - "guild_id", - i.GuildID, - ) + s.LogError(err, "Fetching guild member %s in %s", u.Username, i.GuildID) err = resp.SetMessage("Erreur : impossible de récupérer le membre").IsEphemeral().Send() if err != nil { - logger.Alert("commands/rank.go - Reply error fetching guild member", err.Error()) + s.LogError(err, "reply error fetching guild member") } return } @@ -44,17 +37,10 @@ func Rank(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.Optio } xp, err := c.GetXP() if err != nil { - logger.Alert( - "commands/rank.go - Fetching xp", - err.Error(), - "discord_id", - c.ID, - "guild_id", - i.GuildID, - ) + s.LogError(err, "fetching xp for copaing %s in %s", c.ID, i.GuildID) err = resp.SetMessage("Erreur : impossible de récupérer l'XP").IsEphemeral().Send() if err != nil { - logger.Alert("commands/rank.go - Reply error fetching xp", err.Error()) + s.LogError(err, "reply error fetching xp") } return } @@ -68,6 +54,6 @@ func Rank(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.Optio nxtLvlXP-xp, )).Send() if err != nil { - logger.Alert("commands/rank.go - Sending rank", err.Error()) + s.LogError(err, "sending rank") } } diff --git a/commands/reset.go b/commands/reset.go index f50bb21..77561c1 100644 --- a/commands/reset.go +++ b/commands/reset.go @@ -4,15 +4,14 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) -func Reset(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Reset(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { 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 { - logger.Alert("commands/reset.go - Sending success (all)", err.Error()) + s.LogError(err, "sending reset success") } } @@ -21,26 +20,26 @@ func ResetUser(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd. v, ok := optMap["user"] if !ok { if err := resp.SetMessage("Le user n'a pas été renseigné.").Send(); err != nil { - logger.Alert("commands/reset.go - Copaing not set", err.Error()) + s.LogError(err, "sending error copaing not set") } 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 { - logger.Alert("commands/reset.go - Copaing not set", err.Error()) + s.LogError(err, "sending error bot does not have xp") } return } err := user.GetCopaing(m.ID, i.GuildID).Delete() if err != nil { - logger.Alert("commands/reset.go - Copaing not deleted", err.Error(), "discord_id", m.ID, "guild_id", i.GuildID) + s.LogError(err, "deleting copaings %s in %s", m.Username, i.GuildID) err = resp.SetMessage("Erreur : impossible de reset l'utilisateur").Send() if err != nil { - logger.Alert("commands/reset.go - Error deleting", err.Error()) + s.LogError(err, "sending error while deleting") } } if err = resp.SetMessage("Le user bien été reset.").Send(); err != nil { - logger.Alert("commands/reset.go - Sending success (user)", err.Error()) + s.LogError(err, "sending reset success") } } diff --git a/commands/stats.go b/commands/stats.go index 1a7a379..e2c2ba4 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -15,7 +15,6 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" "github.com/jackc/pgx/v5/pgtype" discordgo "github.com/nyttikord/gokord" "github.com/nyttikord/gokord/channel" @@ -53,7 +52,7 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM 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 { - logger.Alert("commands/stats.go - Sending invalid days", err.Error()) + s.LogError(err, "sending error invalid days") } return } @@ -61,7 +60,7 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM } err := resp.IsDeferred().Send() if err != nil { - logger.Alert("commands/stats.go - Sending deferred", err.Error()) + s.LogError(err, "sending deferred") return } go func() { @@ -72,15 +71,16 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM w, err = statsAll(s, i, days) } if err != nil { + s.LogError(err, "generating stats in %s", i.GuildID) if err = resp.IsEphemeral().SetMessage("Il y a eu une erreur...").Send(); err != nil { - logger.Alert("commands/stats.go - Sending error occurred", err.Error()) + s.LogError(err, "sending error occurred") } return } b := new(bytes.Buffer) _, err = w.WriteTo(b) if err != nil { - logger.Alert("commands/stats.go - Writing png", err.Error()) + s.LogError(err, "writing png") } err = resp.AddFile(&channel.File{ Name: "plot.png", @@ -88,7 +88,7 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM Reader: b, }).Send() if err != nil { - logger.Alert("commands/stats.go - Sending response", err.Error()) + s.LogError(err, "sending stats") } }() } @@ -117,7 +117,7 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS if gokord.Debug { var rawCopaingData []*user.CopaingXP if err := execSql("SELECT * FROM copaing_xps ", "").Scan(&rawCopaingData).Error; err != nil { - logger.Alert("commands/stats.go - Fetching result", err.Error()) + s.LogError(err, "fetching result") return nil, err } rawData = make([]*data, len(rawCopaingData)) @@ -133,7 +133,7 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS 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 { - logger.Alert("commands/stats.go - Fetching result", err.Error()) + s.LogError(err, "fetching result") return nil, err } rawData = make([]*data, len(rawDbData)) @@ -155,10 +155,10 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS var cp user.Copaing if err := gokord.DB.First(&cp, raw.CopaingID).Error; err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { - logger.Alert("commands/stats.go - Finding copaing", err.Error(), "id", raw.CopaingID) + s.LogError(err, "finding copaing %d", raw.CopaingID) return nil, err } - logger.Warn("Copaing not found, skipping entry", "old_id", raw.CopaingID) + s.LogWarn("Copaing %d not found, skipping", raw.CopaingID) continue } copaings[raw.CopaingID] = &cp @@ -202,7 +202,7 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings for in, c := range copaings { m, err := s.GuildAPI().Member(i.GuildID, c.DiscordID) if err != nil { - logger.Alert("commands/stats.go - Fetching guild member", err.Error()) + s.LogError(err, "fetching guild member") return nil, err } slices.SortFunc(stats[in], func(a, b plotter.XY) int { @@ -216,7 +216,7 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings }) l, _, err := plotter.NewLinePoints(plotter.XYs(stats[in])) if err != nil { - logger.Alert("commands/stats.go - Adding line points", err.Error()) + s.LogError(err, "adding line points") return nil, err } l.Color = colors[cnt%len(colors)] @@ -226,7 +226,7 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings } w, err := p.WriterTo(8*vg.Inch, 6*vg.Inch, "png") if err != nil { - logger.Alert("commands/stats.go - Generating png", err.Error()) + s.LogError(err, "generating png") return nil, err } return w, nil diff --git a/commands/top.go b/commands/top.go index 21a1456..195ee9b 100644 --- a/commands/top.go +++ b/commands/top.go @@ -8,34 +8,33 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" "github.com/nyttikord/gokord/channel" ) -func Top(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Top(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { err := resp.IsDeferred().Send() if err != nil { - logger.Alert("commands/top.go - Sending deferred", err.Error()) + s.LogError(err, "sending deferred") return } embeds := make([]*channel.MessageEmbed, 3) wg := sync.WaitGroup{} - fn := func(s string, n uint, d int, id int) { + fn := func(str string, n uint, d int, id int) { defer wg.Done() tops, err := user.GetBestXP(i.GuildID, n, d) if err != nil { - logger.Alert("commands/top.go - Fetching best xp", err.Error(), "n", n, "d", d, "id", id, "guild_id", i.GuildID) + s.LogError(err, "fetching best xp, n: %d, d: %d, id: %d, guild: %s", n, d, id, i.GuildID) embeds[id] = &channel.MessageEmbed{ - Title: s, + Title: str, Description: "Erreur : impossible de récupérer la liste", Color: 0x831010, } return } embeds[id] = &channel.MessageEmbed{ - Title: s, + Title: str, Description: genTopsMessage(tops), Color: 0x10E6AD, } @@ -60,7 +59,7 @@ func Top(_ *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, } err = resp.Send() if err != nil { - logger.Alert("commands/top.go - Sending response top", err.Error()) + s.LogError(err, "sending response top") } }() } diff --git a/config/channel.go b/config/channel.go index c09061f..918af6d 100644 --- a/config/channel.go +++ b/config/channel.go @@ -4,7 +4,6 @@ import ( "strings" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" "github.com/nyttikord/gokord/interaction" ) @@ -29,7 +28,7 @@ func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionC //} } -func HandleFallbackChannelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleFallbackChannelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) @@ -38,14 +37,14 @@ func HandleFallbackChannelSet(_ *discordgo.Session, i *discordgo.InteractionCrea cfg.FallbackChannel = channelID err := cfg.Save() if err != nil { - logger.Alert("config/channel.go - Saving fallback channel", err.Error()) + s.LogError(err, "saving fallback channel") if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving channel", err.Error()) + s.LogError(err, "sending error while saving channel") } return } if err = resp.SetMessage("Salon sauvegardé.").Send(); err != nil { - logger.Alert("config/channel.go - Sending channel saved", err.Error()) + s.LogError(err, "sending channel saved") } } @@ -103,25 +102,25 @@ func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate //} } -func HandleDisChannelDelSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleDisChannelDelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) id := data.Values[0] if !strings.Contains(cfg.DisabledChannels, id) { err := resp.SetMessage("Le salon n'est pas désactivé").Send() if err != nil { - logger.Alert("commands/config.go - Channel not disabled", err.Error()) + s.LogError(err, "sending channel not disabled") } return } cfg.DisabledChannels = strings.ReplaceAll(cfg.DisabledChannels, id+";", "") if err := cfg.Save(); err != nil { - logger.Alert("commands/config.go - Saving config disable del", err.Error()) + s.LogError(err, "saving config disable del") if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { - logger.Alert("config/channel.go - Sending error while saving config", err.Error()) + s.LogError(err, "sending error while saving config") } } if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { - logger.Alert("commands/config.go - Modification saved message disable del", err.Error()) + s.LogError(err, "modification saved message disable del") } } diff --git a/config/xp_role.go b/config/xp_role.go index 39e48f6..1a8fa8a 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -5,7 +5,6 @@ import ( "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" "github.com/nyttikord/gokord/interaction" ) @@ -76,7 +75,7 @@ func HandleXpRoleAddEdit(_ *discordgo.Session, _ *discordgo.InteractionCreate, d //} } -func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleXpRoleAddRole(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) roleId := data.Values[0] @@ -84,7 +83,7 @@ func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, d if r.RoleID == roleId { err := resp.SetMessage("Le rôle est déjà présent dans la config").Send() if err != nil { - logger.Alert("config/xp_role.go - Role already in config", err.Error()) + s.LogError(err, "sending role already in config") } return } @@ -95,20 +94,15 @@ func HandleXpRoleAddRole(_ *discordgo.Session, i *discordgo.InteractionCreate, d }) err := cfg.Save() if err != nil { - logger.Alert( - "config/xp_role.go - Saving config", - err.Error(), - "guild_id", i.GuildID, - "role_id", roleId, - "type", "add", - ) + s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + return } if err = resp.SetMessage("Rôle ajouté.").Send(); err != nil { - logger.Alert("config/xp_role.go - Sending success", err.Error()) + s.LogError(err, "Sending role saved") } } -func HandleXpRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleXpRoleEditRole(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) roleId := data.Values[0] @@ -116,23 +110,18 @@ func HandleXpRoleEditRole(_ *discordgo.Session, i *discordgo.InteractionCreate, if r == nil { err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() if err != nil { - logger.Alert("config/xp_role.go - Role not found (edit)", err.Error()) + s.LogError(err, "role not found") } return } r.XP = configModifyMap[getKeyConfigRole(i)] err := gokord.DB.Save(r).Error if err != nil { - logger.Alert( - "config/xp_role.go - Saving config", - err.Error(), - "guild_id", i.GuildID, - "role_id", roleId, - "type", "edit", - ) + s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + return } if err = resp.SetMessage("Rôle modifié.").Send(); err != nil { - logger.Alert("config/xp_role.go - Sending success", err.Error()) + s.LogError(err, "sending role saved") } } @@ -146,7 +135,7 @@ func HandleXpRoleDel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ int //} } -func HandleXpRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleXpRoleDelRole(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) roleId := data.Values[0] @@ -154,22 +143,17 @@ func HandleXpRoleDelRole(_ *discordgo.Session, i *discordgo.InteractionCreate, d if r == nil { err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() if err != nil { - logger.Alert("config/xp_role.go - Sending role not found (del)", err.Error()) + s.LogError(err, "sending role not found") } return } err := gokord.DB.Delete(r).Error if err != nil { - logger.Alert( - "config/xp_role.go - Deleting entry", - err.Error(), - "guild_id", i.GuildID, - "role_id", roleId, - "type", "del", - ) + s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + return } if err = resp.SetMessage("Rôle supprimé.").Send(); err != nil { - logger.Alert("config/xp_role.go - Sending success", err.Error()) + s.LogError(err, "sending role deleted") } } diff --git a/go.mod b/go.mod index ea40184..506cb86 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be + github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb + github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa github.com/pelletier/go-toml/v2 v2.2.4 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.0 diff --git a/go.sum b/go.sum index f4ede94..055023e 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,10 @@ github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae h1:7UFLx1EybWFZ github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be h1:D7bFu20Qr2P+hLgv/bWVhscuQ2tt0y0km8fTVZ5ThmY= github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be/go.mod h1:J/Ja3EIKFOxxy5lx09kjsxyrwv4ardc015cMtmM8XPg= +github.com/anhgelus/gokord v0.11.1-0.20250913150335-4bcccc1dab83 h1:LyaYwAVoULEXib96M8YlJF7So2srAZktGN6Y6xiOBxs= +github.com/anhgelus/gokord v0.11.1-0.20250913150335-4bcccc1dab83/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= +github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b h1:p9XoghqPoBwj2GDR4SNyirKZVm6UI4KNPBa387G8LKM= +github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= 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= @@ -74,6 +78,10 @@ github.com/nyttikord/gokord v0.30.0 h1:O4LhpCMyfWcgLqziPXQgMCopb9VO7kwcZG3phblOa github.com/nyttikord/gokord v0.30.0/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb h1:HUL4CikIHguqjKrAqzXYghkzlaZi8+54BBObxBUgeos= github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= +github.com/nyttikord/gokord v0.30.1-0.20250913143152-425cd430dee0 h1:bvSFyK1JXTupt67Y78pzbFPg/5tBaouK0BxAfvpwZBw= +github.com/nyttikord/gokord v0.30.1-0.20250913143152-425cd430dee0/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= +github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa h1:P9zaVyRF0bDnmhUg6PaNfmyUqDZ+EvHpBnCdH0/0T3s= +github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= 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= diff --git a/main.go b/main.go index 7db4893..7be2e68 100644 --- a/main.go +++ b/main.go @@ -12,12 +12,12 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - "github.com/anhgelus/gokord/logger" "github.com/joho/godotenv" discordgo "github.com/nyttikord/gokord" "github.com/nyttikord/gokord/discord" "github.com/nyttikord/gokord/discord/types" "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" @@ -42,7 +42,7 @@ var interTTF []byte func init() { err := godotenv.Load() if err != nil && !errors.Is(err, os.ErrNotExist) { - logger.Warn("Error while loading .env file", "error", err.Error()) + logger.Log(logger.LevelError, 0, "Error while loading .env file: %v", err.Error()) } flag.StringVar(&token, "token", os.Getenv("TOKEN"), "token of the bot") @@ -165,7 +165,7 @@ func main() { user.PeriodicReducer(dg) stopPeriodicReducer = gokord.NewTimer(d, func(stop chan<- interface{}) { - logger.Debug("Periodic reducer") + dg.LogDebug("Periodic reducer") user.PeriodicReducer(dg) }) }, @@ -179,7 +179,7 @@ func main() { // interaction: /config bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { if len(data.Values) != 1 { - logger.Alert("main.go - Handle config modify", "invalid data values", "values", data.Values) + bot.LogError(errors.New("invalid data values"), "handle config modify, values: %#v", data.Values) return } switch data.Values[0] { @@ -192,7 +192,7 @@ func main() { case config.ModifyTimeReduce: config.HandleModifyPeriodicReduce(s, i, data, resp) default: - logger.Alert("main.go - Detecting value", "unkown value", "value", data.Values[0]) + bot.LogError(errors.New("unknown value"), "detecting value %s", data.Values[0]) return } }, commands.ConfigModify) diff --git a/user/level.go b/user/level.go index 6f92ce7..e11ac03 100644 --- a/user/level.go +++ b/user/level.go @@ -8,59 +8,44 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" "github.com/nyttikord/gokord/user" ) -func onNewLevel(dg *discordgo.Session, m *user.Member, level uint) { +func onNewLevel(s *discordgo.Session, m *user.Member, level uint) { cfg := config.GetGuildConfig(m.GuildID) xpForLevel := exp.LevelXP(level) for _, role := range cfg.XpRoles { if role.XP <= xpForLevel && !slices.Contains(m.Roles, role.RoleID) { - logger.Debug( - "Add role", - "role_id", role.RoleID, - "user_id", m.User.ID, - "guild_id", m.GuildID, - ) - err := dg.GuildAPI().MemberRoleAdd(m.GuildID, m.User.ID, role.RoleID) + s.LogDebug("add role %s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) + err := s.GuildAPI().MemberRoleAdd(m.GuildID, m.User.ID, role.RoleID) if err != nil { - logger.Alert("user/level.go - Adding role", err.Error(), "role_id", role.RoleID) + s.LogError(err, "adding role %s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) } } else if role.XP > xpForLevel && slices.Contains(m.Roles, role.RoleID) { - logger.Debug( - "Remove role", - "role_id", role.RoleID, - "user_id", m.User.ID, - "guild_id", m.GuildID, - ) - err := dg.GuildAPI().MemberRoleRemove(m.GuildID, m.User.ID, role.RoleID) + s.LogDebug("remove role %s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) + err := s.GuildAPI().MemberRoleRemove(m.GuildID, m.User.ID, role.RoleID) if err != nil { - logger.Alert("user/level.go - Removing role", err.Error(), "role_id", role.RoleID) + s.LogError(err, "removing role s to %s in %s", role.RoleID, m.DisplayName(), m.GuildID) } } } } -func (c *Copaing) OnNewLevel(dg *discordgo.Session, level uint) { - m, err := dg.GuildAPI().Member(c.GuildID, c.DiscordID) +func (c *Copaing) OnNewLevel(s *discordgo.Session, level uint) { + m, err := s.GuildAPI().Member(c.GuildID, c.DiscordID) if err != nil { - logger.Alert( - "user/level.go - Getting member for new level", err.Error(), - "discord_id", c.DiscordID, - "guild_id", c.GuildID, - ) + s.LogError(err, "getting member %s in %s for new level", c.DiscordID, c.GuildID) return } - onNewLevel(dg, m, level) + onNewLevel(s, m, level) } -func PeriodicReducer(dg *discordgo.Session) { +func PeriodicReducer(s *discordgo.Session) { wg := &sync.WaitGroup{} var cs []*Copaing if err := gokord.DB.Find(&cs).Error; err != nil { - logger.Alert("user/level.go - Fetching all copaings", err.Error()) + s.LogError(err, "fetching all copaings") return } cxps := make([]*cXP, len(cs)) @@ -73,7 +58,7 @@ func PeriodicReducer(dg *discordgo.Session) { defer wg.Done() xp, err := c.GetXP() if err != nil { - logger.Alert("user/level.go - Getting XP", err.Error(), "copaing_id", c.ID, "guild_id", c.GuildID) + s.LogError(err, "getting xp of copaing %d in %s", c.ID, c.GuildID) xp = 0 } cxps[i] = &cXP{ @@ -83,7 +68,7 @@ func PeriodicReducer(dg *discordgo.Session) { }() } wg.Wait() - for _, g := range dg.State.Guilds { + for _, g := range s.State.Guilds { wg.Add(1) go func() { defer wg.Done() @@ -93,26 +78,26 @@ func PeriodicReducer(dg *discordgo.Session) { Where("guild_id = ? and created_at < ?", g.ID, exp.TimeStampNDaysBefore(cfg.DaysXPRemains)). Delete(&CopaingXP{}) if res.Error != nil { - logger.Alert("user/level.go - Removing old XP", res.Error.Error(), "guild_id", g.ID) + s.LogError(res.Error, "removing old xp in %s", g.ID) } - logger.Debug("Guild cleaned", "guild", g.Name, "rows affected", res.RowsAffected) + s.LogDebug("Guild cleaned %s, rows affected: %d", g.Name, res.RowsAffected) }() } wg.Wait() for i, c := range cxps { if i%50 == 49 { - logger.Debug("Sleeping...") + s.LogDebug("Sleeping...") time.Sleep(15 * time.Second) // prevents spamming the API } oldXp := c.GetXP() xp, err := c.ToCopaing().GetXP() if err != nil { - logger.Alert("user/level.go - Getting XP", err.Error(), "guild_id", c.ID, "discord_id", c.DiscordID) + s.LogError(err, "getting xp of copaing %s in %s", c.ID, c.GuildID) continue } if exp.Level(oldXp) != exp.Level(xp) { - c.OnNewLevel(dg, exp.Level(xp)) + c.OnNewLevel(s, exp.Level(xp)) } } - logger.Debug("Periodic reduce finished", "len(guilds)", len(dg.State.Guilds)) + s.LogDebug("Periodic reduce finished for %d guilds", len(s.State.Guilds)) } diff --git a/user/xp.go b/user/xp.go index 550f3bf..d130cae 100644 --- a/user/xp.go +++ b/user/xp.go @@ -7,8 +7,8 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/logger" "github.com/nyttikord/gokord/user" ) @@ -28,23 +28,14 @@ func (c *cXP) GetXP() uint { func (c *Copaing) AddXP(s *discordgo.Session, m *user.Member, xp uint, fn func(uint, uint)) { old, err := c.GetXP() if err != nil { - logger.Alert("user/xp.go - Getting xp", err.Error(), "discord_id", c.DiscordID, "guild_id", c.GuildID) + s.LogError(err, "getting xp for %s in %s", m.DisplayName(), c.GuildID) return } pastLevel := exp.Level(old) - logger.Debug("Adding xp", "member", m.DisplayName(), "old xp", old, "xp to add", xp, "old level", pastLevel) + s.LogDebug("Adding xp to %s, old: %d, to add: %d", m.DisplayName(), old, xp) c.CopaingXPs = append(c.CopaingXPs, CopaingXP{CopaingID: c.ID, XP: xp, GuildID: c.GuildID}) if err = c.Save(); err != nil { - logger.Alert( - "user/xp.go - Saving user", - err.Error(), - "xp", - c.CopaingXPs, - "discord_id", - c.DiscordID, - "guild_id", - c.GuildID, - ) + s.LogError(err, "saving user %s with xp %d in %s", m.DisplayName(), xp, c.GuildID) return } newLevel := exp.Level(old + xp) @@ -78,7 +69,7 @@ func (c *Copaing) GetXPForDays(n uint) (uint, error) { var cxp CopaingXP err = gokord.DB.ScanRows(rows, &cxp) if err != nil { - logger.Alert("user/xp.go - Scanning rows", err.Error(), "copaing_id", c.ID, "guild_id", c.GuildID) + logger.Log(logger.LevelError, 0, "scanning rows of copaing %d in %s: %#v", c.ID, c.GuildID, err.Error()) continue } xp += cxp.XP @@ -105,7 +96,7 @@ func GetBestXP(guildId string, n uint, d int) ([]CopaingAccess, error) { var c Copaing err = gokord.DB.ScanRows(rows, &c) if err != nil { - logger.Alert("user/xp.go - Scanning rows", err.Error(), "guild_id", guildId) + logger.Log(logger.LevelError, 0, "scanning rows of copaing %d in %s: %#v", c.ID, c.GuildID, err.Error()) continue } wg.Add(1) @@ -113,7 +104,7 @@ func GetBestXP(guildId string, n uint, d int) ([]CopaingAccess, error) { defer wg.Done() xp, err := c.GetXPForDays(uint(d)) if err != nil { - logger.Alert("user/xp.go - Fetching xp", err.Error(), "discord_id", c.DiscordID, "guild_id", guildId) + logger.Log(logger.LevelError, 0, "fetching xp of copaing %d in %s: %#v", c.ID, c.GuildID, err.Error()) return } l = append(l, &cXP{Cxp: xp, Copaing: &c}) -- cgit v1.2.3 From 24519b76b48f521f1ef4c7e5e038574eaa66ebcd Mon Sep 17 00:00:00 2001 From: ascpial Date: Sat, 13 Sep 2025 21:40:24 +0200 Subject: feat(config): improve /config look and xp_role usability --- commands/config.go | 120 ++++++++---- config/guild.go | 9 + config/xp_role.go | 541 ++++++++++++++++++++++++++++++++++++++++------------- events.go | 43 ++--- go.mod | 2 +- go.sum | 2 + main.go | 78 +++++++- 7 files changed, 583 insertions(+), 212 deletions(-) diff --git a/commands/config.go b/commands/config.go index cc1e942..1c2db8c 100644 --- a/commands/config.go +++ b/commands/config.go @@ -8,13 +8,19 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord/cmd" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/channel" + "github.com/nyttikord/gokord/component" + "github.com/nyttikord/gokord/discord/types" + "github.com/nyttikord/gokord/emoji" + "github.com/nyttikord/gokord/interaction" ) const ( ConfigModify = "config_modify" + OpenConfig = "config" ) -func Config(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { cfg := config.GetGuildConfig(i.GuildID) roles := "" l := len(cfg.XpRoles) - 1 @@ -47,40 +53,84 @@ func Config(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMa } else { defaultChan = fmt.Sprintf("<#%s>", cfg.FallbackChannel) } - //comp := component.New(). - // Add(component.NewActionRow().Add(component.NewStringSelect(ConfigModify). - // SetPlaceholder("Modifier..."). - // AddOption( - // component.NewSelectOption("Rôles liés à l'XP", config.ModifyXpRole). - // SetDescription("Gère les rôles liés à l'XP"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "🏅"}), - // ). - // AddOption( - // component.NewSelectOption("Salons désactivés", config.ModifyDisChannel). - // SetDescription("Gère les salons désactivés"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), - // ). - // AddOption( - // // I don't have a better idea for this... - // component.NewSelectOption("Salons par défaut", config.ModifyFallbackChannel). - // SetDescription("Spécifie le salon par défaut"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "💾"}), - // ). - // AddOption( - // component.NewSelectOption("Temps avec la réduction", config.ModifyTimeReduce). - // SetDescription("Gère le temps avant la réduction d'XP"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "⌛"}), - // ), - // )) - msg := fmt.Sprintf( - "# Config\n**Salon par défaut**\n%s\n\n**Rôles liés aux niveaux**\n%s\n\n**Salons désactivés**\n%s\n\n**Jours avant la réduction**\n%d", - defaultChan, - roles, - chans, - cfg.DaysXPRemains, - ) - err := resp.SetMessage(msg).IsEphemeral().Send() + content := []component.Component{ + &component.Container{ + Components: []component.Message{ + &component.TextDisplay{Content: "## Configuration"}, + &component.Separator{}, + &component.TextDisplay{Content: "**Salon par défaut**\n" + defaultChan}, + &component.TextDisplay{Content: "**Rôles de niveau**\n" + roles}, + &component.TextDisplay{Content: "**Salons ignorés**\n" + chans}, + &component.TextDisplay{ + Content: fmt.Sprintf("**Jours avant la réduction**\n%d jours", cfg.DaysXPRemains), + }, + &component.ActionsRow{ + Components: []component.Message{ + &component.SelectMenu{ + MenuType: types.SelectMenuString, + Placeholder: "Gestion des paramètres", + CustomID: ConfigModify, + Options: []component.SelectMenuOption{ + { + Label: "Salons par défaut", + Value: config.ModifyFallbackChannel, + Emoji: &emoji.Component{Name: "📣"}, + }, + { + Label: "Rôles de niveaux", + Value: config.ModifyXpRole, + Emoji: &emoji.Component{Name: "🏅"}, + }, + { + Label: "Salons ignorés", + Value: config.ModifyDisChannel, + Emoji: &emoji.Component{Name: "🫣"}, + }, + { + Label: "Temps avant la réduction d'expérience", + Value: config.ModifyTimeReduce, + Emoji: &emoji.Component{Name: "📉"}, + }, + }, + }, + }, + }, + }, + }, + } + return &interaction.Response{ + Type: types.InteractionResponseChannelMessageWithSource, + Data: &interaction.ResponseData{ + Components: content, + Flags: channel.MessageFlagsEphemeral | channel.MessageFlagsIsComponentsV2, + }, + } +} + +func ConfigCommand( + session *discordgo.Session, + i *discordgo.InteractionCreate, + _ cmd.OptionMap, + resp *cmd.ResponseBuilder, +) { + err := session.InteractionAPI().Respond(i.Interaction, ConfigResponse(i)) + + if err != nil { + session.LogError(err, "config/guild.go - Sending config") + } +} + +func ConfigMessageComponent( + session *discordgo.Session, + i *discordgo.InteractionCreate, + _ interaction.MessageComponentData, + resp *cmd.ResponseBuilder, +) { + response := ConfigResponse(i) + response.Type = types.InteractionResponseUpdateMessage + err := session.InteractionAPI().Respond(i.Interaction, response) + if err != nil { - s.LogError(err, "sending config") + session.LogError(err, "sending config") } } diff --git a/config/guild.go b/config/guild.go index 8384d5b..6310fa4 100644 --- a/config/guild.go +++ b/config/guild.go @@ -43,3 +43,12 @@ func (cfg *GuildConfig) FindXpRole(roleID string) (int, *XpRole) { } return 0, nil } + +func (cfg *GuildConfig) FindXpRoleID(ID uint) (int, *XpRole) { + for i, r := range cfg.XpRoles { + if r.ID == ID { + return i, &r + } + } + return -1, nil +} diff --git a/config/xp_role.go b/config/xp_role.go index 1a8fa8a..b35966f 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -2,10 +2,16 @@ package config import ( "fmt" + "slices" + "strconv" + "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/channel" + "github.com/nyttikord/gokord/component" + "github.com/nyttikord/gokord/discord/types" "github.com/nyttikord/gokord/interaction" ) @@ -17,181 +23,446 @@ type XpRole struct { } const ( - ModifyXpRole = "xp_role" - XpRoleAdd = "xp_role_add" - XpRoleAddLevel = "xp_role_add_level" - XpRoleAddRole = "xp_role_add_role" - XpRoleDel = "xp_role_del" - XpRoleDelRole = "xp_role_del_role" - XpRoleEdit = "xp_role_edit" - XpRoleEditLevel = "xp_role_edit_level" - XpRoleEditRole = "xp_role_edit_role" + ModifyXpRole = "xp_role" + XpRoleNew = "xp_role_add" + XpRoleAdd = "xp_role_add_level" + XpRoleEditPattern = `^xp_role_edit_(\d+)$` + XpRoleEditLevelPattern = `^xp_role_edit_level_(\d+)$` + XpRoleEditLevelStartPattern = `^xp_role_edit_level_start_(\d+)$` + XpRoleEditRolePattern = `^xp_role_edit_role_(\d+)$` + XpRoleDel = `^xp_role_del_(\d+)$` ) -var ( - configModifyMap = map[string]uint{} -) +func HandleXpRole( + session *discordgo.Session, + i *discordgo.InteractionCreate, + _ interaction.MessageComponentData, + resp *cmd.ResponseBuilder, +) { + cfg := GetGuildConfig(i.GuildID) + container := component.Container{ + Components: []component.Message{ + &component.TextDisplay{Content: "## Configuration / Rôles de niveaux"}, + &component.Separator{}, + }, + } + for _, r := range cfg.XpRoles { + container.Components = append(container.Components, &component.Section{ + Components: []component.Message{ + &component.TextDisplay{ + Content: fmt.Sprintf("<@&%s> - Niveau %d", r.RoleID, exp.Level(r.XP)), + }, + }, + Accessory: &component.Button{ + CustomID: fmt.Sprintf("xp_role_edit_%d", r.ID), + Style: component.ButtonStyleSecondary, + Label: "Modifier", + }, + }) + } + container.Components = append(container.Components, + &component.ActionsRow{ + Components: []component.Message{ + &component.Button{ + CustomID: XpRoleNew, + Style: component.ButtonStylePrimary, + Label: "Nouveau rôle", + }, + }, + }, + &component.Separator{}, + &component.ActionsRow{ + Components: []component.Message{ + &component.Button{CustomID: "config", Style: component.ButtonStyleSecondary, Label: "Retour"}, + }, + }, + ) + + response := &interaction.Response{ + Type: types.InteractionResponseUpdateMessage, + Data: &interaction.ResponseData{ + Components: []component.Component{&container}, + Flags: channel.MessageFlagsIsComponentsV2, + }, + } + err := session.InteractionAPI().Respond(i.Interaction, response) + if err != nil { + session.LogError(err, "Sending config") + } +} -func HandleModifyXpRole(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - //err := resp.IsEphemeral(). - // SetMessage("Action à réaliser"). - // SetComponents(component.New().Add(component.NewActionRow(). - // Add(component.NewButton(XpRoleAdd, discordgo.PrimaryButton). - // SetLabel("Ajouter"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), - // ). - // Add(component.NewButton(XpRoleEdit, discordgo.SecondaryButton). - // SetLabel("Modifier"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "📝"}), - // ). - // Add(component.NewButton(XpRoleDel, discordgo.DangerButton). - // SetLabel("Supprimer"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "❌"}), - // ), - // )).Send() - //if err != nil { - // logger.Alert("config/xp_reduce.go - Sending config", err.Error()) - //} +func HandleXpRoleNew( + session *discordgo.Session, + i *discordgo.InteractionCreate, + data interaction.MessageComponentData, + resp *cmd.ResponseBuilder, +) { + one := 1 + response := &interaction.Response{ + Type: types.InteractionResponseModal, + Data: &interaction.ResponseData{ + Title: "Nouveau rôle de niveau", + CustomID: XpRoleAdd, + Components: []component.Component{ + &component.Label{ + Label: "Niveau", + Component: &component.TextInput{ + CustomID: "level", + Style: component.TextInputShort, + Placeholder: "5", + MinLength: 1, + MaxLength: 5, + Required: true, + }, + }, + &component.Label{ + Label: "Rôle", + Component: &component.SelectMenu{ + MenuType: types.SelectMenuRole, + CustomID: "role", + MinValues: &one, + MaxValues: one, + }, + }, + }, + }, + } + err := session.InteractionAPI().Respond(i.Interaction, response) + if err != nil { + session.LogError(err, "Sending modal to add") + } } -func HandleXpRoleAddEdit(_ *discordgo.Session, _ *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - //cID := XpRoleAddLevel - //if data.CustomID == XpRoleEdit { - // cID = XpRoleEditLevel - //} - //err := resp.IsModal(). - // SetTitle("Role"). - // SetCustomID(cID). - // SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( - // component.NewTextInput(cID, "Niveau", discordgo.TextInputShort). - // SetPlaceholder("5"). - // IsRequired(). - // SetMinLength(0). - // SetMaxLength(5), - // ))). - // Send() - //if err != nil { - // logger.Alert("config/xp_reduce.go - Sending modal to add/edit", err.Error()) - //} +func HandleXpRoleEdit( + session *discordgo.Session, + i *discordgo.InteractionCreate, + data interaction.MessageComponentData, + parameters []string, resp *cmd.ResponseBuilder, +) { + config := GetGuildConfig(i.GuildID) + id, err := getRoleLevelID(parameters) + if err != nil { + session.LogError(err, "Reading dynamic CustomID") + return + } + roleIndex := slices.IndexFunc(config.XpRoles, func(role XpRole) bool { return role.ID == id }) + if roleIndex == -1 { + return + } + role := config.XpRoles[roleIndex] + + roleSelect := &component.SelectMenu{ + MenuType: types.SelectMenuRole, + CustomID: fmt.Sprintf("xp_role_edit_role_%d", id), + DefaultValues: []component.SelectMenuDefaultValue{ + {ID: role.RoleID, Type: types.SelectMenuDefaultValueRole}, + }, + } + + container := &component.Container{ + Components: []component.Message{ + &component.TextDisplay{Content: "## Configuration / Rôles de niveaux"}, + &component.Separator{}, + &component.Section{ + Components: []component.Message{ + &component.TextDisplay{Content: fmt.Sprintf("Niveau **%d**", exp.Level(role.XP))}, + }, + Accessory: &component.Button{ + CustomID: fmt.Sprintf("xp_role_edit_level_start_%d", id), + Style: component.ButtonStyleSecondary, + Label: "Modifier", + }, + }, + &component.ActionsRow{Components: []component.Message{roleSelect}}, + &component.ActionsRow{Components: []component.Message{ + &component.Button{CustomID: fmt.Sprintf("xp_role_del_%d", id), Style: component.ButtonStyleDanger, Label: "Supprimer"}, + }}, + &component.Separator{}, + &component.ActionsRow{Components: []component.Message{ + &component.Button{Label: "Retour", CustomID: ModifyXpRole, Style: component.ButtonStyleSecondary}, + }}, + }, + } + + response := &interaction.Response{ + Type: types.InteractionResponseUpdateMessage, + Data: &interaction.ResponseData{ + Components: []component.Component{container}, + Flags: channel.MessageFlagsIsComponentsV2, + }, + } + + err = session.InteractionAPI().Respond(i.Interaction, response) + if err != nil { + session.LogError(err, "Sending xp_role config") + } } -func HandleXpRoleAddRole(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() +func HandleXpRoleEditRole( + session *discordgo.Session, + i *discordgo.InteractionCreate, + data interaction.MessageComponentData, + parameters []string, resp *cmd.ResponseBuilder, +) { + id, err := getRoleLevelID(parameters) + if err != nil { + session.LogError(err, "Reading dynamic CustomID") + return + } + role := data.Values[0] cfg := GetGuildConfig(i.GuildID) - roleId := data.Values[0] - for _, r := range cfg.XpRoles { - if r.RoleID == roleId { - err := resp.SetMessage("Le rôle est déjà présent dans la config").Send() + for _, xpRole := range cfg.XpRoles { + if xpRole.RoleID == role { + err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + Type: types.InteractionResponseChannelMessageWithSource, + Data: &interaction.ResponseData{ + Flags: channel.MessageFlagsEphemeral, + AllowedMentions: &channel.MessageAllowedMentions{}, + Content: fmt.Sprintf("Un autre niveau avec le rôle <@&%s> est déjà existant.", role), + }, + }) if err != nil { - s.LogError(err, "sending role already in config") + session.LogError(err, "Sending unable to Already existing role message") } return } } - cfg.XpRoles = append(cfg.XpRoles, XpRole{ - XP: configModifyMap[getKeyConfigRole(i)], - RoleID: roleId, - }) - err := cfg.Save() - if err != nil { - s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + index, xprole := cfg.FindXpRoleID(id) + if index == 0 { + err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + Type: types.InteractionResponseChannelMessageWithSource, + Data: &interaction.ResponseData{ + Flags: channel.MessageFlagsEphemeral, + Content: "Impossible de modifier le rôle. Peut-être a-t-il été supprimé ?", + }, + }) + if err != nil { + session.LogError(err, "Sending unable to get role message") + } return } - if err = resp.SetMessage("Rôle ajouté.").Send(); err != nil { - s.LogError(err, "Sending role saved") + xprole.RoleID = role + err = gokord.DB.Save(xprole).Error + if err != nil { + session.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) } + HandleXpRoleEdit(session, i, interaction.MessageComponentData{}, parameters, resp) } -func HandleXpRoleEditRole(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() +func HandleXpRoleEditLevelStart( + session *discordgo.Session, + i *discordgo.InteractionCreate, + data interaction.MessageComponentData, + parameters []string, + resp *cmd.ResponseBuilder, +) { + id, err := getRoleLevelID(parameters) + if err != nil { + session.LogError(err, "Reading dynamic CustomID") + return + } cfg := GetGuildConfig(i.GuildID) - roleId := data.Values[0] - _, r := cfg.FindXpRole(roleId) - if r == nil { - err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() + _, role := cfg.FindXpRoleID(id) + if role == nil { + err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + Type: types.InteractionResponseChannelMessageWithSource, + Data: &interaction.ResponseData{ + Flags: channel.MessageFlagsEphemeral, + Content: "Impossible de trouver le rôle. Peut-être a-t-il été supprimé ?", + }, + }) if err != nil { - s.LogError(err, "role not found") + session.LogError(err, "Sending Unable to get role message") } return } - r.XP = configModifyMap[getKeyConfigRole(i)] - err := gokord.DB.Save(r).Error + response := &interaction.Response{ + Type: types.InteractionResponseModal, + Data: &interaction.ResponseData{ + Title: "Modification du niveau lié au rôle", + CustomID: fmt.Sprintf("xp_role_edit_level_%d", id), + Components: []component.Component{ + &component.Label{ + Label: "Nouveau niveau", + Component: &component.TextInput{ + Style: component.TextInputShort, + Required: true, + CustomID: "level", + MinLength: 1, + MaxLength: 5, + Placeholder: "5", + Value: strconv.FormatUint(uint64(exp.Level(role.XP)), 10), + }, + }, + }, + }, + } + err = session.InteractionAPI().Respond(i.Interaction, response) + if err != nil { + session.LogError(err, "Sending Edit level modal") + } +} + +func HandleXpRoleEditLevel( + session *discordgo.Session, + i *discordgo.InteractionCreate, + data interaction.ModalSubmitData, + parameters []string, + resp *cmd.ResponseBuilder, +) { + id, err := getRoleLevelID(parameters) if err != nil { - s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + session.LogError(err, "Reading dynamic CustomID") return } - if err = resp.SetMessage("Rôle modifié.").Send(); err != nil { - s.LogError(err, "sending role saved") + + fmt.Printf("Alors?... %#v", data.Components) + levelInput := data.Components[0].(*component.Label).Component.(*component.TextInput) + level, err := strconv.Atoi(levelInput.Value) + if err != nil || level < 0 { + err = resp.IsEphemeral(). + SetMessage( + fmt.Sprintf("Le niveau doit être un nombre entier positif.\n-# Trouvé : %s", levelInput.Value), + ). + Send() + if err != nil { + session.LogError(err, "Sending bad number warning message") + } + return } -} + xp := exp.LevelXP(uint(level)) -func HandleXpRoleDel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - //err := resp.IsEphemeral(). - // SetMessage("Rôle à supprimer"). - // SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(XpRoleDelRole)))). - // Send() - //if err != nil { - // logger.Alert("config/xp_reduce.go - Sending response to del", err.Error()) - //} + cfg := GetGuildConfig(i.GuildID) + for _, xpRole := range cfg.XpRoles { + if xpRole.XP == xp { + err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + Type: types.InteractionResponseChannelMessageWithSource, + Data: &interaction.ResponseData{ + Flags: channel.MessageFlagsEphemeral, + Content: fmt.Sprintf("Un autre rôle est déjà lié au niveau %d.", level), + }, + }) + if err != nil { + session.LogError(err, "Sending unable to Already existing level message") + } + return + } + } + index, xprole := cfg.FindXpRoleID(id) + if index == -1 { + err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + Type: types.InteractionResponseChannelMessageWithSource, + Data: &interaction.ResponseData{ + Flags: channel.MessageFlagsEphemeral, + Content: "Impossible de modifier le rôle. Peut-être a-t-il été supprimé ?", + }, + }) + if err != nil { + session.LogError(err, "Sending unable to modify role message") + } + return + } + xprole.XP = xp + err = gokord.DB.Save(xprole).Error + if err != nil { + session.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) + } + HandleXpRoleEdit(session, i, interaction.MessageComponentData{}, parameters, resp) } -func HandleXpRoleDelRole(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() +func HandleXpRoleDel( + session *discordgo.Session, + i *discordgo.InteractionCreate, + _ interaction.MessageComponentData, + dynamic_values []string, + resp *cmd.ResponseBuilder, +) { + id, err := getRoleLevelID(dynamic_values) + if err != nil { + session.LogError(err, "reading dynamic CustomID") + return + } cfg := GetGuildConfig(i.GuildID) - roleId := data.Values[0] - _, r := cfg.FindXpRole(roleId) - if r == nil { - err := resp.SetMessage("Le rôle n'a pas été trouvé dans la config.").Send() + _, role := cfg.FindXpRoleID(id) + if role == nil { + err := session.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é ?", + Flags: channel.MessageFlagsEphemeral, + }, + }) if err != nil { - s.LogError(err, "sending role not found") + session.LogError(err, "Sending role not found message") } return } - err := gokord.DB.Delete(r).Error + err = gokord.DB.Delete(role).Error if err != nil { - s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + session.LogError(err, "Deleting entry guild_id %s, id %d, type del", i.GuildID, id) + } + + HandleXpRole(session, i, interaction.MessageComponentData{}, resp) +} + +func HandleXpRoleAdd( + session *discordgo.Session, + i *discordgo.InteractionCreate, + data interaction.ModalSubmitData, + resp *cmd.ResponseBuilder, +) { + levelInput := data.Components[0].(*component.Label).Component.(*component.TextInput) + + in, err := strconv.Atoi(levelInput.Value) + if err != nil || in < 0 { + err = resp.IsEphemeral(). + SetMessage( + fmt.Sprintf("Le niveau doit être un nombre entier positif.\n-# Trouvé : %s", levelInput.Value), + ). + Send() + if err != nil { + session.LogError(err, "sending bad number warning message") + } return } - if err = resp.SetMessage("Rôle supprimé.").Send(); err != nil { - s.LogError(err, "sending role deleted") + xp := exp.LevelXP(uint(in)) + + roleId := data.Components[1].(*component.Label).Component.(*component.SelectMenu).Values[0] + + cfg := GetGuildConfig(i.GuildID) + for _, r := range cfg.XpRoles { + if r.RoleID == roleId { + err := resp.IsEphemeral().SetMessage(fmt.Sprintf("Le rôle <@&%s> est déjà lié au niveau %d.", r.RoleID, exp.Level(r.XP))).Send() + if err != nil { + session.LogError(err, "sending role already in config") + } + return + } else if r.XP == xp { + err := resp.IsEphemeral().SetMessage(fmt.Sprintf("Le niveau %d est déjà lié au rôle <@&%s>.", in, r.RoleID)).Send() + if err != nil { + session.LogError(err, "sending role already in config") + } + return + } + } + cfg.XpRoles = append(cfg.XpRoles, XpRole{ + XP: xp, + RoleID: roleId, + }) + err = cfg.Save() + if err != nil { + session.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + return } -} -func HandleXpRoleLevel(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { - //resp.IsEphemeral() - //input := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput) - // - //k := getKeyConfigRole(i) - //in, err := strconv.Atoi(input.Value) - //if err != nil || in < 0 { - // if err = resp. - // SetMessage("Impossible de lire le nombre. Il doit s'agit d'un nombre entier positif."). - // Send(); err != nil { - // logger.Alert("command/config.go - Sending bad number", err.Error()) - // } - // return - //} - //configModifyMap[k] = exp.LevelXP(uint(in)) - //go func(i *discordgo.InteractionCreate, k string) { - // time.Sleep(5 * time.Minute) - // delete(configModifyMap, k) - //}(i, k) - // - //cID := XpRoleAddRole - //resp.SetMessage("Rôle à ajouter") - //if data.CustomID == XpRoleEditLevel { - // cID = XpRoleEditRole - // resp.SetMessage("Rôle à modifier") - //} - // - //err = resp. - // SetComponents(component.New().Add(component.NewActionRow().Add(component.NewRoleSelect(cID)))). - // Send() - //if err != nil { - // logger.Alert("config/xp_reduce.go - Sending response to add/edit", err.Error()) - //} + HandleXpRole(session, i, interaction.MessageComponentData{}, resp) } -func getKeyConfigRole(i *discordgo.InteractionCreate) string { - return fmt.Sprintf("r:%s:%s", i.GuildID, i.Member.User.ID) +func getRoleLevelID(dynamic []string) (uint, error) { + id64, err := strconv.ParseUint(dynamic[0], 10, 0) + if err != nil { + return 0, err + } + + return uint(id64), nil } diff --git a/events.go b/events.go index cae0ef3..9f247d3 100644 --- a/events.go +++ b/events.go @@ -9,7 +9,6 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" - "github.com/anhgelus/gokord/logger" discordgo "github.com/nyttikord/gokord" ) @@ -39,11 +38,7 @@ func OnMessage(s *discordgo.Session, m *discordgo.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 { - logger.Alert( - "events.go - add reaction for new level", err.Error(), - "channel id", m.ChannelID, - "message id", m.Message.ID, - ) + s.LogError(err, "add reaction for new level channel id %s, message id %s", m.ChannelID, m.Message.ID) } }) } @@ -70,8 +65,8 @@ func genMapKey(guildID string, userID string) string { return fmt.Sprintf("%s:%s", guildID, userID) } -func onConnection(_ *discordgo.Session, e *discordgo.VoiceStateUpdate) { - logger.Debug("User connected", "username", e.Member.DisplayName()) +func onConnection(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { + s.LogDebug("User connected username %s", e.Member.DisplayName()) connectedSince[genMapKey(e.GuildID, e.UserID)] = time.Now().Unix() } @@ -81,25 +76,19 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { // check the validity of user con, ok := connectedSince[genMapKey(e.GuildID, e.UserID)] if !ok || con == NotConnected { - logger.Warn(fmt.Sprintf( - "User %s diconnect from a vocal but was registered as not connected", e.Member.DisplayName(), - )) + s.LogWarn("User %s disconnect from a vocal but was registered as not connected", e.Member.DisplayName()) return } timeInVocal := now - con - logger.Debug("User disconnected", "username", e.Member.DisplayName(), "time in vocal", timeInVocal) + s.LogDebug("User disconnected username %s, time in vocal %d", e.Member.DisplayName(), timeInVocal) connectedSince[genMapKey(e.GuildID, e.UserID)] = NotConnected // add exp if timeInVocal < 0 { - logger.Alert( - "events.go - Calculating time spent in vocal", "the time is negative", - "discord_id", e.UserID, - "guild_id", e.GuildID, - ) + s.LogWarn("Time spent in vocal negative discord_id %s, guild_id %s", e.UserID, e.GuildID) return } if timeInVocal > MaxTimeInVocal { - logger.Warn(fmt.Sprintf("User %s spent more than 6 hours in vocal", e.Member.DisplayName())) + s.LogWarn("User %s spent more than 6 hours in vocal", e.Member.DisplayName()) timeInVocal = MaxTimeInVocal } e.Member.GuildID = e.GuildID @@ -112,13 +101,13 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { "%s est maintenant niveau %d", e.Member.Mention(), newLevel, )) if err != nil { - logger.Alert("events.go - Sending new level in fallback channel", err.Error()) + s.LogError(err, "Sending new level in fallback channel") } }) } -func OnLeave(_ *discordgo.Session, e *discordgo.GuildMemberRemove) { - logger.Debug("Leave event", "user_id", e.User.ID) +func OnLeave(s *discordgo.Session, e *discordgo.GuildMemberRemove) { + s.LogDebug("Leave event user_id %s", e.User.ID) if e.User.Bot { return } @@ -128,17 +117,9 @@ func OnLeave(_ *discordgo.Session, e *discordgo.GuildMemberRemove) { Delete(&user.CopaingXP{}). Error if err != nil { - logger.Alert( - "events.go - deleting user xp from db", err.Error(), - "user_id", e.User.ID, - "guild_id", e.GuildID, - ) + s.LogError(err, "Deleting user xp from db user_id %s, guild_id %s", e.User.ID, e.GuildID) } if err = c.Delete(); err != nil { - logger.Alert( - "events.go - deleting user from db", err.Error(), - "user_id", e.User.ID, - "guild_id", e.GuildID, - ) + s.LogError(err, "Deleting user from DB user_id %s, guild_id %s", e.User.ID, e.GuildID) } } diff --git a/go.mod b/go.mod index 506cb86..d9b3bd9 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.6 require ( github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa + github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2 github.com/pelletier/go-toml/v2 v2.2.4 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.0 diff --git a/go.sum b/go.sum index 055023e..17a19d2 100644 --- a/go.sum +++ b/go.sum @@ -82,6 +82,8 @@ github.com/nyttikord/gokord v0.30.1-0.20250913143152-425cd430dee0 h1:bvSFyK1JXTu github.com/nyttikord/gokord v0.30.1-0.20250913143152-425cd430dee0/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa h1:P9zaVyRF0bDnmhUg6PaNfmyUqDZ+EvHpBnCdH0/0T3s= github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= +github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2 h1:DHoH/b1SnmJVjDQDd1ZV2Ri+NIXOyrsGgmoRFG1rro8= +github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2/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= diff --git a/main.go b/main.go index 7be2e68..f6ccf5f 100644 --- a/main.go +++ b/main.go @@ -2,9 +2,11 @@ package main import ( _ "embed" + "encoding/json" "errors" "flag" "os" + "regexp" "time" "git.anhgelus.world/anhgelus/les-copaings-bot/commands" @@ -63,6 +65,61 @@ func init() { } +func handleDynamicMessageComponent( + b *gokord.Bot, + handler func( + *discordgo.Session, + *discordgo.InteractionCreate, + interaction.MessageComponentData, + []string, *cmd.ResponseBuilder, + ), + pattern string, +) { + compiledPattern := regexp.MustCompile(pattern) + b.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + if i.Type != types.InteractionMessageComponent { + return + } + + data := i.MessageComponentData() + parameters := compiledPattern.FindStringSubmatch(data.CustomID) + if parameters == nil { + return + } + parameters = parameters[1:] + handler(s, i, data, parameters, cmd.NewResponseBuilder(s, i)) + }) +} + +func handleDynamicModalComponent( + b *gokord.Bot, + handler func( + *discordgo.Session, + *discordgo.InteractionCreate, + interaction.ModalSubmitData, + []string, + *cmd.ResponseBuilder, + ), + pattern string, +) { + compiledPattern := regexp.MustCompile(pattern) + b.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + if i.Type != types.InteractionModalSubmit { + return + } + + data := i.ModalSubmitData() + content, _ := json.Marshal(data) + s.LogDebug(string(content)) + parameters := compiledPattern.FindStringSubmatch(data.CustomID) + if parameters == nil { + return + } + parameters = parameters[1:] + handler(s, i, data, parameters, cmd.NewResponseBuilder(s, i)) + }) +} + func main() { flag.Parse() gokord.UseRedis = false @@ -88,7 +145,7 @@ func main() { configCmd := cmd.New("config", "Modifie la config"). SetPermission(&adm). - SetHandler(commands.Config) + SetHandler(commands.ConfigCommand) topCmd := cmd.New("top", "Copaings les plus actifs"). SetHandler(commands.Top) @@ -184,7 +241,7 @@ func main() { } switch data.Values[0] { case config.ModifyXpRole: - config.HandleModifyXpRole(s, i, data, resp) + config.HandleXpRole(s, i, data, resp) case config.ModifyFallbackChannel: config.HandleModifyFallbackChannel(s, i, data, resp) case config.ModifyDisChannel: @@ -196,15 +253,16 @@ func main() { return } }, commands.ConfigModify) + bot.HandleMessageComponent(commands.ConfigMessageComponent, commands.OpenConfig) // xp role related - bot.HandleMessageComponent(config.HandleXpRoleAddEdit, config.XpRoleAdd) - bot.HandleMessageComponent(config.HandleXpRoleAddEdit, config.XpRoleEdit) - bot.HandleMessageComponent(config.HandleXpRoleAddRole, config.XpRoleAddRole) - bot.HandleMessageComponent(config.HandleXpRoleEditRole, config.XpRoleEditRole) - bot.HandleMessageComponent(config.HandleXpRoleDel, config.XpRoleDel) - bot.HandleMessageComponent(config.HandleXpRoleDelRole, config.XpRoleDelRole) - bot.HandleModal(config.HandleXpRoleLevel, config.XpRoleAddLevel) - bot.HandleModal(config.HandleXpRoleLevel, config.XpRoleEditLevel) + bot.HandleMessageComponent(config.HandleXpRole, config.ModifyXpRole) + bot.HandleMessageComponent(config.HandleXpRoleNew, config.XpRoleNew) + bot.HandleModal(config.HandleXpRoleAdd, config.XpRoleAdd) + handleDynamicMessageComponent(&bot, config.HandleXpRoleEdit, config.XpRoleEditPattern) + handleDynamicMessageComponent(&bot, config.HandleXpRoleEditRole, config.XpRoleEditRolePattern) + handleDynamicMessageComponent(&bot, config.HandleXpRoleEditLevelStart, config.XpRoleEditLevelStartPattern) + handleDynamicModalComponent(&bot, config.HandleXpRoleEditLevel, config.XpRoleEditLevelPattern) + handleDynamicMessageComponent(&bot, config.HandleXpRoleDel, config.XpRoleDel) // channel related bot.HandleMessageComponent(config.HandleFallbackChannelSet, config.FallbackChannelSet) bot.HandleMessageComponent(config.HandleDisChannel, config.DisChannelAdd) -- cgit v1.2.3 From 200b8f763947c251661397db0ca973d27a9a6816 Mon Sep 17 00:00:00 2001 From: ascpial Date: Mon, 15 Sep 2025 13:45:13 +0200 Subject: fix(config): some fixes --- config/xp_role.go | 61 +++++++------------------------------------------------ 1 file changed, 7 insertions(+), 54 deletions(-) diff --git a/config/xp_role.go b/config/xp_role.go index b35966f..8aae5a4 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -2,7 +2,6 @@ package config import ( "fmt" - "slices" "strconv" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" @@ -145,11 +144,11 @@ func HandleXpRoleEdit( session.LogError(err, "Reading dynamic CustomID") return } - roleIndex := slices.IndexFunc(config.XpRoles, func(role XpRole) bool { return role.ID == id }) - if roleIndex == -1 { + _, role := config.FindXpRoleID(id) + if role == nil { + HandleXpRole(session, i, interaction.MessageComponentData{}, resp) return } - role := config.XpRoles[roleIndex] roleSelect := &component.SelectMenu{ MenuType: types.SelectMenuRole, @@ -211,24 +210,8 @@ func HandleXpRoleEditRole( } role := data.Values[0] cfg := GetGuildConfig(i.GuildID) - for _, xpRole := range cfg.XpRoles { - if xpRole.RoleID == role { - err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ - Type: types.InteractionResponseChannelMessageWithSource, - Data: &interaction.ResponseData{ - Flags: channel.MessageFlagsEphemeral, - AllowedMentions: &channel.MessageAllowedMentions{}, - Content: fmt.Sprintf("Un autre niveau avec le rôle <@&%s> est déjà existant.", role), - }, - }) - if err != nil { - session.LogError(err, "Sending unable to Already existing role message") - } - return - } - } - index, xprole := cfg.FindXpRoleID(id) - if index == 0 { + _, xprole := cfg.FindXpRoleID(id) + if xprole == nil { err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ Type: types.InteractionResponseChannelMessageWithSource, Data: &interaction.ResponseData{ @@ -333,23 +316,8 @@ func HandleXpRoleEditLevel( xp := exp.LevelXP(uint(level)) cfg := GetGuildConfig(i.GuildID) - for _, xpRole := range cfg.XpRoles { - if xpRole.XP == xp { - err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ - Type: types.InteractionResponseChannelMessageWithSource, - Data: &interaction.ResponseData{ - Flags: channel.MessageFlagsEphemeral, - Content: fmt.Sprintf("Un autre rôle est déjà lié au niveau %d.", level), - }, - }) - if err != nil { - session.LogError(err, "Sending unable to Already existing level message") - } - return - } - } - index, xprole := cfg.FindXpRoleID(id) - if index == -1 { + _, xprole := cfg.FindXpRoleID(id) + if xprole == nil { err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ Type: types.InteractionResponseChannelMessageWithSource, Data: &interaction.ResponseData{ @@ -430,21 +398,6 @@ func HandleXpRoleAdd( roleId := data.Components[1].(*component.Label).Component.(*component.SelectMenu).Values[0] cfg := GetGuildConfig(i.GuildID) - for _, r := range cfg.XpRoles { - if r.RoleID == roleId { - err := resp.IsEphemeral().SetMessage(fmt.Sprintf("Le rôle <@&%s> est déjà lié au niveau %d.", r.RoleID, exp.Level(r.XP))).Send() - if err != nil { - session.LogError(err, "sending role already in config") - } - return - } else if r.XP == xp { - err := resp.IsEphemeral().SetMessage(fmt.Sprintf("Le niveau %d est déjà lié au rôle <@&%s>.", in, r.RoleID)).Send() - if err != nil { - session.LogError(err, "sending role already in config") - } - return - } - } cfg.XpRoles = append(cfg.XpRoles, XpRole{ XP: xp, RoleID: roleId, -- cgit v1.2.3 From 9d1ea00a2f7436ddddfad6b739adc0f433ecf9cd Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Thu, 18 Sep 2025 19:25:06 +0200 Subject: build(gokord): upgrade to latest nightly --- .gitignore | 2 ++ config/xp_reduce.go | 2 +- config/xp_role.go | 4 ++-- go.mod | 4 ++-- go.sum | 4 ++++ main.go | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c8977f6..b7d2fba 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ tmp config/**.toml data docker-compose.yml + +les-copaings-bot diff --git a/config/xp_reduce.go b/config/xp_reduce.go index 4bcdd1e..1afe8d7 100644 --- a/config/xp_reduce.go +++ b/config/xp_reduce.go @@ -24,7 +24,7 @@ func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCr //} } -func HandleTimeReduceSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { +func HandleTimeReduceSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { //resp.IsEphemeral() //v := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value //days, err := strconv.Atoi(v) diff --git a/config/xp_role.go b/config/xp_role.go index 8aae5a4..3ec8e3a 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -289,7 +289,7 @@ func HandleXpRoleEditLevelStart( func HandleXpRoleEditLevel( session *discordgo.Session, i *discordgo.InteractionCreate, - data interaction.ModalSubmitData, + data *interaction.ModalSubmitData, parameters []string, resp *cmd.ResponseBuilder, ) { @@ -376,7 +376,7 @@ func HandleXpRoleDel( func HandleXpRoleAdd( session *discordgo.Session, i *discordgo.InteractionCreate, - data interaction.ModalSubmitData, + data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder, ) { levelInput := data.Components[0].(*component.Label).Component.(*component.TextInput) diff --git a/go.mod b/go.mod index d9b3bd9..9201ec1 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b + github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0 github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2 + github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21 github.com/pelletier/go-toml/v2 v2.2.4 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.0 diff --git a/go.sum b/go.sum index 17a19d2..efad3f8 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,8 @@ github.com/anhgelus/gokord v0.11.1-0.20250913150335-4bcccc1dab83 h1:LyaYwAVoULEX github.com/anhgelus/gokord v0.11.1-0.20250913150335-4bcccc1dab83/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b h1:p9XoghqPoBwj2GDR4SNyirKZVm6UI4KNPBa387G8LKM= github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= +github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0 h1:LApN5na4GHlbMYMx+B3RBebrZTnhK6+fyjAUUexowHI= +github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0/go.mod h1:p5aU+u6mGR2pE5h/yM5ysXI8YlMnl8IP/ICRD3Q5zKY= 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= @@ -84,6 +86,8 @@ github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa h1:P9zaVyRF0bD github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2 h1:DHoH/b1SnmJVjDQDd1ZV2Ri+NIXOyrsGgmoRFG1rro8= github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= +github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21 h1:P10ofytwmj9/VwWiW+oSL4q2YWn5jb3LEcXAA4e/VYM= +github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21/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= diff --git a/main.go b/main.go index f6ccf5f..3bca23e 100644 --- a/main.go +++ b/main.go @@ -96,7 +96,7 @@ func handleDynamicModalComponent( handler func( *discordgo.Session, *discordgo.InteractionCreate, - interaction.ModalSubmitData, + *interaction.ModalSubmitData, []string, *cmd.ResponseBuilder, ), -- cgit v1.2.3 From 398213f2088b775787d4c022b5704366fdfe1aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Fri, 19 Sep 2025 18:42:07 +0200 Subject: build(gokord): bump to latest nightly --- commands/config.go | 4 ++-- config/channel.go | 12 ++++++------ config/xp_reduce.go | 4 ++-- config/xp_role.go | 32 ++++++++++++++++---------------- go.mod | 4 ++-- go.sum | 4 ++++ main.go | 26 +++++++++++++------------- 7 files changed, 45 insertions(+), 41 deletions(-) diff --git a/commands/config.go b/commands/config.go index 1c2db8c..d1e144d 100644 --- a/commands/config.go +++ b/commands/config.go @@ -123,8 +123,8 @@ func ConfigCommand( func ConfigMessageComponent( session *discordgo.Session, i *discordgo.InteractionCreate, - _ interaction.MessageComponentData, - resp *cmd.ResponseBuilder, + _ *interaction.MessageComponentData, + _ *cmd.ResponseBuilder, ) { response := ConfigResponse(i) response.Type = types.InteractionResponseUpdateMessage diff --git a/config/channel.go b/config/channel.go index 918af6d..e5fc81b 100644 --- a/config/channel.go +++ b/config/channel.go @@ -19,7 +19,7 @@ const ( DisChannelDelSet = "disabled_channel_del_set" ) -func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder) { //err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow().Add( // component.NewChannelSelect(FallbackChannelSet).AddChannelType(discordgo.ChannelTypeGuildText), //))).Send() @@ -28,7 +28,7 @@ func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionC //} } -func HandleFallbackChannelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleFallbackChannelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) @@ -48,7 +48,7 @@ func HandleFallbackChannelSet(s *discordgo.Session, i *discordgo.InteractionCrea } } -func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder) { //err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow(). // Add( // component.NewButton(DisChannelAdd, discordgo.PrimaryButton). @@ -66,7 +66,7 @@ func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate //} } -func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { //resp.IsEphemeral().SetMessage("Salon à désactiver...") //cID := DisChannelAddSet //if data.CustomID == DisChannelDel { @@ -79,7 +79,7 @@ func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data //} } -func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { //resp.IsEphemeral() //cfg := GetGuildConfig(i.GuildID) //id := data.Values[0] @@ -102,7 +102,7 @@ func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate //} } -func HandleDisChannelDelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleDisChannelDelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { resp.IsEphemeral() cfg := GetGuildConfig(i.GuildID) id := data.Values[0] diff --git a/config/xp_reduce.go b/config/xp_reduce.go index 1afe8d7..a61ef1a 100644 --- a/config/xp_reduce.go +++ b/config/xp_reduce.go @@ -11,7 +11,7 @@ const ( TimeReduceSet = "time_reduce_set" ) -func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { //err := resp.IsModal(). // SetCustomID(TimeReduceSet). // SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( @@ -24,7 +24,7 @@ func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCr //} } -func HandleTimeReduceSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { +func HandleTimeReduceSet(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.ModalSubmitData, _ *cmd.ResponseBuilder) { //resp.IsEphemeral() //v := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value //days, err := strconv.Atoi(v) diff --git a/config/xp_role.go b/config/xp_role.go index 3ec8e3a..72af42b 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -35,8 +35,8 @@ const ( func HandleXpRole( session *discordgo.Session, i *discordgo.InteractionCreate, - _ interaction.MessageComponentData, - resp *cmd.ResponseBuilder, + _ *interaction.MessageComponentData, + _ *cmd.ResponseBuilder, ) { cfg := GetGuildConfig(i.GuildID) container := component.Container{ @@ -93,8 +93,8 @@ func HandleXpRole( func HandleXpRoleNew( session *discordgo.Session, i *discordgo.InteractionCreate, - data interaction.MessageComponentData, - resp *cmd.ResponseBuilder, + _ *interaction.MessageComponentData, + _ *cmd.ResponseBuilder, ) { one := 1 response := &interaction.Response{ @@ -135,7 +135,7 @@ func HandleXpRoleNew( func HandleXpRoleEdit( session *discordgo.Session, i *discordgo.InteractionCreate, - data interaction.MessageComponentData, + _ *interaction.MessageComponentData, parameters []string, resp *cmd.ResponseBuilder, ) { config := GetGuildConfig(i.GuildID) @@ -146,7 +146,7 @@ func HandleXpRoleEdit( } _, role := config.FindXpRoleID(id) if role == nil { - HandleXpRole(session, i, interaction.MessageComponentData{}, resp) + HandleXpRole(session, i, &interaction.MessageComponentData{}, resp) return } @@ -200,7 +200,7 @@ func HandleXpRoleEdit( func HandleXpRoleEditRole( session *discordgo.Session, i *discordgo.InteractionCreate, - data interaction.MessageComponentData, + data *interaction.MessageComponentData, parameters []string, resp *cmd.ResponseBuilder, ) { id, err := getRoleLevelID(parameters) @@ -229,15 +229,15 @@ func HandleXpRoleEditRole( if err != nil { session.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) } - HandleXpRoleEdit(session, i, interaction.MessageComponentData{}, parameters, resp) + HandleXpRoleEdit(session, i, &interaction.MessageComponentData{}, parameters, resp) } func HandleXpRoleEditLevelStart( session *discordgo.Session, i *discordgo.InteractionCreate, - data interaction.MessageComponentData, + _ *interaction.MessageComponentData, parameters []string, - resp *cmd.ResponseBuilder, + _ *cmd.ResponseBuilder, ) { id, err := getRoleLevelID(parameters) if err != nil { @@ -335,17 +335,17 @@ func HandleXpRoleEditLevel( if err != nil { session.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) } - HandleXpRoleEdit(session, i, interaction.MessageComponentData{}, parameters, resp) + HandleXpRoleEdit(session, i, &interaction.MessageComponentData{}, parameters, resp) } func HandleXpRoleDel( session *discordgo.Session, i *discordgo.InteractionCreate, - _ interaction.MessageComponentData, - dynamic_values []string, + _ *interaction.MessageComponentData, + dynamicValues []string, resp *cmd.ResponseBuilder, ) { - id, err := getRoleLevelID(dynamic_values) + id, err := getRoleLevelID(dynamicValues) if err != nil { session.LogError(err, "reading dynamic CustomID") return @@ -370,7 +370,7 @@ func HandleXpRoleDel( session.LogError(err, "Deleting entry guild_id %s, id %d, type del", i.GuildID, id) } - HandleXpRole(session, i, interaction.MessageComponentData{}, resp) + HandleXpRole(session, i, &interaction.MessageComponentData{}, resp) } func HandleXpRoleAdd( @@ -408,7 +408,7 @@ func HandleXpRoleAdd( return } - HandleXpRole(session, i, interaction.MessageComponentData{}, resp) + HandleXpRole(session, i, &interaction.MessageComponentData{}, resp) } func getRoleLevelID(dynamic []string) (uint, error) { diff --git a/go.mod b/go.mod index 9201ec1..b587589 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0 + github.com/anhgelus/gokord v0.11.1-0.20250919163649-80ed0b18f923 github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21 + github.com/nyttikord/gokord v0.30.1-0.20250919163233-9ebc33ea8afe github.com/pelletier/go-toml/v2 v2.2.4 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.0 diff --git a/go.sum b/go.sum index efad3f8..2ab6829 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b h1:p9XoghqPoBwj github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0 h1:LApN5na4GHlbMYMx+B3RBebrZTnhK6+fyjAUUexowHI= github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0/go.mod h1:p5aU+u6mGR2pE5h/yM5ysXI8YlMnl8IP/ICRD3Q5zKY= +github.com/anhgelus/gokord v0.11.1-0.20250919163649-80ed0b18f923 h1:+6qHfzip/A78UbgyhGYPy1Tz/xbZalBNtBIdtj8/PYM= +github.com/anhgelus/gokord v0.11.1-0.20250919163649-80ed0b18f923/go.mod h1:4/ywDZCTnaImbeK7V84Fob4qm4NbuvaN8PQWZIDzE1w= 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= @@ -88,6 +90,8 @@ github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2 h1:DHoH/b1SnmJ github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21 h1:P10ofytwmj9/VwWiW+oSL4q2YWn5jb3LEcXAA4e/VYM= github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= +github.com/nyttikord/gokord v0.30.1-0.20250919163233-9ebc33ea8afe h1:X/stBMAS1bfzRVC9A2q5OV0ozPIwl4XPinGZSik5HvU= +github.com/nyttikord/gokord v0.30.1-0.20250919163233-9ebc33ea8afe/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= diff --git a/main.go b/main.go index 3bca23e..ff8c55a 100644 --- a/main.go +++ b/main.go @@ -68,11 +68,11 @@ func init() { func handleDynamicMessageComponent( b *gokord.Bot, handler func( - *discordgo.Session, - *discordgo.InteractionCreate, - interaction.MessageComponentData, - []string, *cmd.ResponseBuilder, - ), + *discordgo.Session, + *discordgo.InteractionCreate, + *interaction.MessageComponentData, + []string, *cmd.ResponseBuilder, +), pattern string, ) { compiledPattern := regexp.MustCompile(pattern) @@ -94,12 +94,12 @@ func handleDynamicMessageComponent( func handleDynamicModalComponent( b *gokord.Bot, handler func( - *discordgo.Session, - *discordgo.InteractionCreate, - *interaction.ModalSubmitData, - []string, - *cmd.ResponseBuilder, - ), + *discordgo.Session, + *discordgo.InteractionCreate, + *interaction.ModalSubmitData, + []string, + *cmd.ResponseBuilder, +), pattern string, ) { compiledPattern := regexp.MustCompile(pattern) @@ -110,7 +110,7 @@ func handleDynamicModalComponent( data := i.ModalSubmitData() content, _ := json.Marshal(data) - s.LogDebug(string(content)) + s.LogDebug("%s", content) parameters := compiledPattern.FindStringSubmatch(data.CustomID) if parameters == nil { return @@ -234,7 +234,7 @@ func main() { } // interaction: /config - bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { if len(data.Values) != 1 { bot.LogError(errors.New("invalid data values"), "handle config modify, values: %#v", data.Values) return -- cgit v1.2.3 From e8b91140fba414c2bd7e7f36e8cff95d7651732d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 20 Sep 2025 13:40:41 +0200 Subject: fix(db): closing rows even if rows is nil --- main.go | 22 +++++++++++----------- user/xp.go | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index ff8c55a..e313c17 100644 --- a/main.go +++ b/main.go @@ -68,11 +68,11 @@ func init() { func handleDynamicMessageComponent( b *gokord.Bot, handler func( - *discordgo.Session, - *discordgo.InteractionCreate, - *interaction.MessageComponentData, - []string, *cmd.ResponseBuilder, -), + *discordgo.Session, + *discordgo.InteractionCreate, + *interaction.MessageComponentData, + []string, *cmd.ResponseBuilder, + ), pattern string, ) { compiledPattern := regexp.MustCompile(pattern) @@ -94,12 +94,12 @@ func handleDynamicMessageComponent( func handleDynamicModalComponent( b *gokord.Bot, handler func( - *discordgo.Session, - *discordgo.InteractionCreate, - *interaction.ModalSubmitData, - []string, - *cmd.ResponseBuilder, -), + *discordgo.Session, + *discordgo.InteractionCreate, + *interaction.ModalSubmitData, + []string, + *cmd.ResponseBuilder, + ), pattern string, ) { compiledPattern := regexp.MustCompile(pattern) diff --git a/user/xp.go b/user/xp.go index d130cae..96a8a27 100644 --- a/user/xp.go +++ b/user/xp.go @@ -61,10 +61,10 @@ func (c *Copaing) GetXPForDays(n uint) (uint, error) { c.ID, ). Rows() - defer rows.Close() if err != nil { return 0, err } + defer rows.Close() for rows.Next() { var cxp CopaingXP err = gokord.DB.ScanRows(rows, &cxp) @@ -86,10 +86,10 @@ func GetBestXP(guildId string, n uint, d int) ([]CopaingAccess, error) { d = int(cfg.DaysXPRemains) } rows, err := gokord.DB.Model(&Copaing{}).Where("guild_id = ?", guildId).Rows() - defer rows.Close() if err != nil { return nil, err } + defer rows.Close() var l []*cXP wg := sync.WaitGroup{} for rows.Next() { -- cgit v1.2.3 From 8d6fa726069bd5364ada1521b400bb5eb7865d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 20 Sep 2025 14:01:39 +0200 Subject: feat(stats): custom scale for Y to show level --- commands/stats.go | 4 ++++ exp/functions.go | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/commands/stats.go b/commands/stats.go index e2c2ba4..3156fd9 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -47,6 +47,9 @@ var colors = []color.RGBA{ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionMap, resp *cmd.ResponseBuilder) { cfg := config.GetGuildConfig(i.GuildID) days := 15 + if gokord.Debug { + days = 90 + } if v, ok := opt["days"]; ok { in := v.IntValue() if in < 1 || uint(in) > cfg.DaysXPRemains { @@ -195,6 +198,7 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings p.X.Label.Text = "Secondes" } p.Y.Label.Text = "XP" + p.Y.Scale = exp.LevelScale{} p.Add(plotter.NewGrid()) diff --git a/exp/functions.go b/exp/functions.go index 2608094..363aed8 100644 --- a/exp/functions.go +++ b/exp/functions.go @@ -33,12 +33,26 @@ func VocalXP(time uint) uint { )) } +type LevelScale struct{} + +func (LevelScale) Normalize(min, max, x float64) float64 { + if min < 0 || max < 0 || x < 0 { + panic("Values must be positive or null for a level scale.") + } + levelMin := LevelExact(min) + return (LevelExact(x) - levelMin) / (LevelExact(max) - levelMin) +} + // Level gives the level with the given XP. // See LevelXP to get the XP required to get a level. func Level(xp uint) uint { - return uint(math.Floor( - 0.2 * math.Sqrt(float64(xp)), - )) + return uint(math.Floor(LevelExact(float64(xp)))) +} + +// LevelExact gives the exact level with the given XP. +// See Level to get the floored level. +func LevelExact(xp float64) float64 { + return 0.2 * math.Sqrt(xp) } // LevelXP gives the XP required to get this level. -- cgit v1.2.3 From a0e93b4e031857e7379e2ab2d7bdae24561f4e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 20 Sep 2025 15:39:51 +0200 Subject: feat(stats): better style for the graph --- commands/stats.go | 31 +++++++++++++++++++++++++++---- exp/functions.go | 4 +++- main.go | 3 ++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/commands/stats.go b/commands/stats.go index 3156fd9..fcb0c29 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -21,6 +21,7 @@ import ( "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" + "gonum.org/v1/plot/vg/draw" "gorm.io/gorm" ) @@ -172,7 +173,7 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS pts = make([]plotter.XY, days+1) for i := 0; i < len(pts); i++ { pts[i] = plotter.XY{ - X: float64(i - int(days)), + X: float64(i - days), Y: 0, } } @@ -181,6 +182,8 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS t := raw.CreatedAt.Unix() - now if !gokord.Debug { t = int64(math.Ceil(float64(t) / (24 * 60 * 60))) + } else { + t = int64(math.Ceil(float64(t) / exp.DebugFactor)) } pts[int64(days)+t] = plotter.XY{ // because t <= 0 X: float64(t), @@ -192,10 +195,22 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings map[int]*user.Copaing, stats map[int][]plotter.XY) (io.WriterTo, error) { p := plot.New() - p.Title.Text = "Évolution de l'XP" + fontSizeTitle := vg.Length(16) + fontSize := vg.Length(12) + // set font size + p.Title.TextStyle.Font.Size = fontSizeTitle + p.X.Label.TextStyle.Font.Size = fontSizeTitle + p.Y.Label.TextStyle.Font.Size = fontSizeTitle + p.Legend.TextStyle.Font.Size = fontSize + // set legend style + p.Legend.YPosition = draw.PosTop + p.Legend.Top = true + p.Legend.Padding = vg.Points(2) + // set scales + p.Title.Text = "XP gagnées" p.X.Label.Text = "Jours" if gokord.Debug { - p.X.Label.Text = "Secondes" + p.X.Label.Text = fmt.Sprintf("%d secondes", exp.DebugFactor) } p.Y.Label.Text = "XP" p.Y.Scale = exp.LevelScale{} @@ -224,11 +239,19 @@ func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings return nil, err } l.Color = colors[cnt%len(colors)] + if len(copaings) < 4 { + l.Width = vg.Points(2) + } + if cnt/len(colors) > 0 { + size := 7 / min(cnt/len(colors), 7) + l.Dashes = []vg.Length{vg.Points(float64(size)), vg.Points(float64(size))} + } p.Add(l) p.Legend.Add(m.DisplayName(), l) cnt++ } - w, err := p.WriterTo(8*vg.Inch, 6*vg.Inch, "png") + w, err := p.WriterTo(12*vg.Inch, 8*vg.Inch, "png") + if err != nil { s.LogError(err, "generating png") return nil, err diff --git a/exp/functions.go b/exp/functions.go index 363aed8..681c135 100644 --- a/exp/functions.go +++ b/exp/functions.go @@ -11,6 +11,8 @@ import ( "github.com/anhgelus/gokord" ) +const DebugFactor = 30 + func MessageXP(length uint, diversity uint) uint { return uint(math.Floor( 0.025*math.Pow(float64(length), 1.25)*math.Sqrt(float64(diversity)) + 1, @@ -67,7 +69,7 @@ func LevelXP(level uint) uint { func TimeStampNDaysBefore(n uint) string { var unix time.Time if gokord.Debug { - unix = time.Unix(time.Now().Unix()-int64(n), 0) // reduce time for debug + unix = time.Unix(time.Now().Unix()-int64(DebugFactor*n), 0) // reduce time for debug } else { unix = time.Unix(time.Now().Unix()-int64(n*24*60*60), 0) } diff --git a/main.go b/main.go index e313c17..b2fdf84 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/commands" "git.anhgelus.world/anhgelus/les-copaings-bot/config" + "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" @@ -216,7 +217,7 @@ func main() { AfterInit: func(dg *discordgo.Session) { d := 24 * time.Hour if gokord.Debug { - d = 24 * time.Second + d = 3 * exp.DebugFactor * time.Second } user.PeriodicReducer(dg) -- cgit v1.2.3 From c4a5e7db48edb5c69af8bec3e60e444951146d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 20 Sep 2025 16:35:47 +0200 Subject: build(gokord): bump to v0.12.0 --- config/channel.go | 2 +- go.mod | 10 +++--- go.sum | 95 ++++++++----------------------------------------------- 3 files changed, 20 insertions(+), 87 deletions(-) diff --git a/config/channel.go b/config/channel.go index e5fc81b..c918810 100644 --- a/config/channel.go +++ b/config/channel.go @@ -116,7 +116,7 @@ func HandleDisChannelDelSet(s *discordgo.Session, i *discordgo.InteractionCreate cfg.DisabledChannels = strings.ReplaceAll(cfg.DisabledChannels, id+";", "") if err := cfg.Save(); err != nil { s.LogError(err, "saving config disable del") - if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { + if err = resp.SetMessage("Il y a eu une erreur lors de la modification de la base de données.").Send(); err != nil { s.LogError(err, "sending error while saving config") } } diff --git a/go.mod b/go.mod index b587589..b59127f 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,13 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.11.1-0.20250919163649-80ed0b18f923 + github.com/anhgelus/gokord v0.12.0 + github.com/jackc/pgx/v5 v5.7.5 github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.30.1-0.20250919163233-9ebc33ea8afe + github.com/nyttikord/gokord v0.31.0 github.com/pelletier/go-toml/v2 v2.2.4 + golang.org/x/image v0.30.0 + gonum.org/v1/plot v0.16.0 gorm.io/driver/postgres v1.6.0 gorm.io/gorm v1.31.0 ) @@ -26,16 +29,13 @@ require ( github.com/gorilla/websocket v1.5.3 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.5 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect 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 golang.org/x/crypto v0.42.0 // indirect - golang.org/x/image v0.30.0 // indirect golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.36.0 // indirect golang.org/x/text v0.29.0 // indirect - gonum.org/v1/plot v0.16.0 // indirect ) diff --git a/go.sum b/go.sum index 2ab6829..0ba1236 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,15 @@ +codeberg.org/go-fonts/dejavu v0.4.0 h1:2yn58Vkh4CFK3ipacWUAIE3XVBGNa0y1bc95Bmfx91I= +codeberg.org/go-fonts/dejavu v0.4.0/go.mod h1:abni088lmhQJvso2Lsb7azCKzwkfcnttl6tL1UTWKzg= +codeberg.org/go-fonts/latin-modern v0.4.0 h1:vkRCc1y3whKA7iL9Ep0fSGVuJfqjix0ica9UflHORO8= +codeberg.org/go-fonts/latin-modern v0.4.0/go.mod h1:BF68mZznJ9QHn+hic9ks2DaFl4sR5YhfM6xTYaP9vNw= codeberg.org/go-fonts/liberation v0.5.0 h1:SsKoMO1v1OZmzkG2DY+7ZkCL9U+rrWI09niOLfQ5Bo0= codeberg.org/go-fonts/liberation v0.5.0/go.mod h1:zS/2e1354/mJ4pGzIIaEtm/59VFCFnYC7YV6YdGl5GU= codeberg.org/go-latex/latex v0.1.0 h1:hoGO86rIbWVyjtlDLzCqZPjNykpWQ9YuTZqAzPcfL3c= codeberg.org/go-latex/latex v0.1.0/go.mod h1:LA0q/AyWIYrqVd+A9Upkgsb+IqPcmSTKc9Dny04MHMw= codeberg.org/go-pdf/fpdf v0.11.1 h1:U8+coOTDVLxHIXZgGvkfQEi/q0hYHYvEHFuGNX2GzGs= codeberg.org/go-pdf/fpdf v0.11.1/go.mod h1:Y0DGRAdZ0OmnZPvjbMp/1bYxmIPxm0ws4tfoPOc4LjU= +git.sr.ht/~sbinet/cmpimg v0.1.0 h1:E0zPRk2muWuCqSKSVZIWsgtU9pjsw3eKHi8VmQeScxo= +git.sr.ht/~sbinet/cmpimg v0.1.0/go.mod h1:FU12psLbF4TfNXkKH2ZZQ29crIqoiqTZmeQ7dkp/pxE= git.sr.ht/~sbinet/gg v0.6.0 h1:RIzgkizAk+9r7uPzf/VfbJHBMKUr0F5hRFxTUGMnt38= git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm94= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -11,44 +17,12 @@ github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/anhgelus/gokord v0.11.1-0.20250806000243-ddfebe2ca6f1 h1:irHDC/xUm65yLFx5HnVeCbM0qQRpm0i1vQHsyLXeEbo= -github.com/anhgelus/gokord v0.11.1-0.20250806000243-ddfebe2ca6f1/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250806003339-90cf89cde031 h1:56vqHQzCHCcMeBBhAWUyC466BETAhaIl1Qiq93WdrYI= -github.com/anhgelus/gokord v0.11.1-0.20250806003339-90cf89cde031/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250806003704-21a4238c64a0 h1:Jj4ja4bshyEHOd+stqqB4e0iuggtDx/hzZ8K69+rtsE= -github.com/anhgelus/gokord v0.11.1-0.20250806003704-21a4238c64a0/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250806004311-9988b375047f h1:OSTlmWDVRGw3bt4uHOBFyUWNNl5VV3zaB6Xj0TWlY0s= -github.com/anhgelus/gokord v0.11.1-0.20250806004311-9988b375047f/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250806122118-84c56722e29d h1:cbhaSdjjipiF5yFijgewtkjE0HyHZ6tJR7zHBpCkkBI= -github.com/anhgelus/gokord v0.11.1-0.20250806122118-84c56722e29d/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250806143823-567c33f63688 h1:0ngeLQxHr80Xup9UnPSjpdRH3ZpIH1mpf0ig3sEFVJk= -github.com/anhgelus/gokord v0.11.1-0.20250806143823-567c33f63688/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250807111049-5de23912c524 h1:mK7UtqJPNYhStRVeZ2N4c89tjlhlRZX0LcLs7TAB34I= -github.com/anhgelus/gokord v0.11.1-0.20250807111049-5de23912c524/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250821115246-50e5f7d17717 h1:KfcBHUpwbffRO6aIITq7iN7cP7KcKmUnIE+eWiwsYYw= -github.com/anhgelus/gokord v0.11.1-0.20250821115246-50e5f7d17717/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250821122244-0aee6c37eef6 h1:4eO/9UqTPfrKyss2CeLafeKeR06bgoFihudKOdLpWpI= -github.com/anhgelus/gokord v0.11.1-0.20250821122244-0aee6c37eef6/go.mod h1:4xpwLzIG34/XG9QZiPsnYScQhckiCpQMAI0CjP0Nc2k= -github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3 h1:j7Im8+Vd7BIhBPQKsK5Hs2BsyO71Q3/XVxgZntNJa5M= -github.com/anhgelus/gokord v0.11.1-0.20250904142107-2d0e3c982bc3/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= -github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae h1:7UFLx1EybWFZ5wW+x2PLZyJqwSjiO7kLMIaisX4pUxk= -github.com/anhgelus/gokord v0.11.1-0.20250911112818-b436d35950ae/go.mod h1:Tw1djmUOTFCIRhEUI7eG2onnreJbVGA40EWYQgj20bE= -github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be h1:D7bFu20Qr2P+hLgv/bWVhscuQ2tt0y0km8fTVZ5ThmY= -github.com/anhgelus/gokord v0.11.1-0.20250913111909-19135e5d37be/go.mod h1:J/Ja3EIKFOxxy5lx09kjsxyrwv4ardc015cMtmM8XPg= -github.com/anhgelus/gokord v0.11.1-0.20250913150335-4bcccc1dab83 h1:LyaYwAVoULEXib96M8YlJF7So2srAZktGN6Y6xiOBxs= -github.com/anhgelus/gokord v0.11.1-0.20250913150335-4bcccc1dab83/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= -github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b h1:p9XoghqPoBwj2GDR4SNyirKZVm6UI4KNPBa387G8LKM= -github.com/anhgelus/gokord v0.11.1-0.20250913175430-bf95758b4d3b/go.mod h1:MKTSrPK2w9VCDYHPQ8KwSAVFEFYF0LU8FaBEhNq4VoU= -github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0 h1:LApN5na4GHlbMYMx+B3RBebrZTnhK6+fyjAUUexowHI= -github.com/anhgelus/gokord v0.11.1-0.20250918172043-d5177a0473b0/go.mod h1:p5aU+u6mGR2pE5h/yM5ysXI8YlMnl8IP/ICRD3Q5zKY= -github.com/anhgelus/gokord v0.11.1-0.20250919163649-80ed0b18f923 h1:+6qHfzip/A78UbgyhGYPy1Tz/xbZalBNtBIdtj8/PYM= -github.com/anhgelus/gokord v0.11.1-0.20250919163649-80ed0b18f923/go.mod h1:4/ywDZCTnaImbeK7V84Fob4qm4NbuvaN8PQWZIDzE1w= +github.com/anhgelus/gokord v0.12.0 h1:6315krG631amMYRBXkp0Uz7voBtbgEHJZKsNgulu+18= +github.com/anhgelus/gokord v0.12.0/go.mod h1:AUguJsHtnNOozqQY8SCRDfXfoFX6c+LWL7lXNoeIRCk= 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= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bwmarrin/discordgo v0.29.0 h1:FmWeXFaKUwrcL3Cx65c20bTRW+vOb6k8AnaP+EgjDno= -github.com/bwmarrin/discordgo v0.29.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -60,7 +34,6 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= @@ -78,30 +51,12 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/nyttikord/gokord v0.30.0 h1:O4LhpCMyfWcgLqziPXQgMCopb9VO7kwcZG3phblOaTA= -github.com/nyttikord/gokord v0.30.0/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= -github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb h1:HUL4CikIHguqjKrAqzXYghkzlaZi8+54BBObxBUgeos= -github.com/nyttikord/gokord v0.30.1-0.20250913111646-475b917cccfb/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= -github.com/nyttikord/gokord v0.30.1-0.20250913143152-425cd430dee0 h1:bvSFyK1JXTupt67Y78pzbFPg/5tBaouK0BxAfvpwZBw= -github.com/nyttikord/gokord v0.30.1-0.20250913143152-425cd430dee0/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= -github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa h1:P9zaVyRF0bDnmhUg6PaNfmyUqDZ+EvHpBnCdH0/0T3s= -github.com/nyttikord/gokord v0.30.1-0.20250913173431-8e43619c03fa/go.mod h1:Lhk268VlZ1W6Pb3kYnlU9bIuTCioaumedjHdtw1sxck= -github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2 h1:DHoH/b1SnmJVjDQDd1ZV2Ri+NIXOyrsGgmoRFG1rro8= -github.com/nyttikord/gokord v0.30.1-0.20250914224716-68c5eb8c8ab2/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= -github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21 h1:P10ofytwmj9/VwWiW+oSL4q2YWn5jb3LEcXAA4e/VYM= -github.com/nyttikord/gokord v0.30.1-0.20250918171410-c7667e5caf21/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= -github.com/nyttikord/gokord v0.30.1-0.20250919163233-9ebc33ea8afe h1:X/stBMAS1bfzRVC9A2q5OV0ozPIwl4XPinGZSik5HvU= -github.com/nyttikord/gokord v0.30.1-0.20250919163233-9ebc33ea8afe/go.mod h1:Oi0y5sfiYa+hVuV5ZSJ9UMWAGkcaLOhM7xB1TiCdX3U= +github.com/nyttikord/gokord v0.31.0 h1:64DeVCTQpSWj8/RtBm0GtHeh0Gqo3arJGtrSIn5/U0I= +github.com/nyttikord/gokord v0.31.0/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.12.0 h1:XlVPGlflh4nxfhsNXPA8Qp6EmEfTo0rp8oaBzPipXnU= -github.com/redis/go-redis/v9 v9.12.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg= -github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/redis/go-redis/v9 v9.13.0 h1:PpmlVykE0ODh8P43U0HqC+2NXHXwG+GUtQyz+MPKGRg= -github.com/redis/go-redis/v9 v9.13.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -113,11 +68,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= -golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/image v0.30.0 h1:jD5RhkmVAnjqaCUXfbGBrn3lpxbknfN9w2UhHHU+5B4= @@ -126,31 +76,18 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= -golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= -golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -159,22 +96,18 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/plot v0.16.0 h1:dK28Qx/Ky4VmPUN/2zeW0ELyM6ucDnBAj5yun7M9n1g= gonum.org/v1/plot v0.16.0/go.mod h1:Xz6U1yDMi6Ni6aaXILqmVIb6Vro8E+K7Q/GeeH+Pn0c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314= -gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= -gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= -gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= -gorm.io/gorm v1.30.3 h1:QiG8upl0Sg9ba2Zatfjy0fy4It2iNBL2/eMdvEkdXNs= -gorm.io/gorm v1.30.3/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= -gorm.io/gorm v1.30.5 h1:dvEfYwxL+i+xgCNSGGBT1lDjCzfELK8fHZxL3Ee9X0s= -gorm.io/gorm v1.30.5/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -- cgit v1.2.3 From 8a7189c3835a431b7fc16b189162f6f343e80b84 Mon Sep 17 00:00:00 2001 From: ascpial Date: Sat, 20 Sep 2025 23:33:29 +0200 Subject: feat(config): finish upgrading config --- commands/config.go | 128 ++++++++++++++++++++++++++++++++-------------------- config/channel.go | 113 +++++++--------------------------------------- config/guild.go | 27 ++++++++++- config/xp_reduce.go | 101 ++++++++++++++++++++++++----------------- config/xp_role.go | 107 ++++++++++++++++++++++--------------------- events.go | 10 ++-- main.go | 28 +++++++----- 7 files changed, 257 insertions(+), 257 deletions(-) diff --git a/commands/config.go b/commands/config.go index d1e144d..5a2f763 100644 --- a/commands/config.go +++ b/commands/config.go @@ -2,6 +2,7 @@ package commands import ( "fmt" + "sort" "strings" "git.anhgelus.world/anhgelus/les-copaings-bot/config" @@ -11,7 +12,6 @@ import ( "github.com/nyttikord/gokord/channel" "github.com/nyttikord/gokord/component" "github.com/nyttikord/gokord/discord/types" - "github.com/nyttikord/gokord/emoji" "github.com/nyttikord/gokord/interaction" ) @@ -24,6 +24,9 @@ func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { cfg := config.GetGuildConfig(i.GuildID) roles := "" l := len(cfg.XpRoles) - 1 + sort.Slice(cfg.XpRoles, func(i, j int) bool { + return cfg.XpRoles[i].XP > cfg.XpRoles[j].XP + }) for i, r := range cfg.XpRoles { if i == l { roles += fmt.Sprintf("> Niveau %d - <@&%s>", exp.Level(r.XP), r.RoleID) @@ -32,68 +35,78 @@ func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { } } if len(roles) == 0 { - roles = "Aucun rôle configuré :(" + roles = "Aucun rôle configuré" } disChans := strings.Split(cfg.DisabledChannels, ";") - l = len(disChans) - 1 - chans := "" - for i, c := range disChans { - if i == l-1 { - chans += fmt.Sprintf("> <#%s>", c) - } else if i != l { - chans += fmt.Sprintf("> <#%s>\n", c) + disChansDefault := []component.SelectMenuDefaultValue{} + for _, c := range disChans { + if c != "" { + disChansDefault = append(disChansDefault, component.SelectMenuDefaultValue{ + ID: c, + Type: types.SelectMenuDefaultValueChannel, + }) } } - if len(chans) == 0 { - chans = "Aucun salon désactivé :)" - } - var defaultChan string - if len(cfg.FallbackChannel) == 0 { - defaultChan = "Pas de valeur" - } else { - defaultChan = fmt.Sprintf("<#%s>", cfg.FallbackChannel) + defaultChan := []component.SelectMenuDefaultValue{} + if len(cfg.FallbackChannel) > 0 { + defaultChan = append(defaultChan, component.SelectMenuDefaultValue{ + ID: cfg.FallbackChannel, + Type: types.SelectMenuDefaultValueChannel, + }) } + zero := 0 content := []component.Component{ &component.Container{ Components: []component.Message{ &component.TextDisplay{Content: "## Configuration"}, &component.Separator{}, - &component.TextDisplay{Content: "**Salon par défaut**\n" + defaultChan}, - &component.TextDisplay{Content: "**Rôles de niveau**\n" + roles}, - &component.TextDisplay{Content: "**Salons ignorés**\n" + chans}, - &component.TextDisplay{ - Content: fmt.Sprintf("**Jours avant la réduction**\n%d jours", cfg.DaysXPRemains), + &component.TextDisplay{Content: "**Salons par défaut**\n-# Les niveaux obtenue grâce à un appel sont affichés ici"}, + &component.ActionsRow{ + Components: []component.Message{ + &component.SelectMenu{ + MenuType: types.SelectMenuChannel, + CustomID: config.ModifyFallbackChannel, + Placeholder: "Pas de salon par défaut", + MinValues: &zero, + MaxValues: 1, + DefaultValues: defaultChan, + }, + }, }, + &component.TextDisplay{Content: "**Salons désactivé**\n-# Les messages ne donneront pas d'expérience dans ces salons"}, &component.ActionsRow{ Components: []component.Message{ &component.SelectMenu{ - MenuType: types.SelectMenuString, - Placeholder: "Gestion des paramètres", - CustomID: ConfigModify, - Options: []component.SelectMenuOption{ - { - Label: "Salons par défaut", - Value: config.ModifyFallbackChannel, - Emoji: &emoji.Component{Name: "📣"}, - }, - { - Label: "Rôles de niveaux", - Value: config.ModifyXpRole, - Emoji: &emoji.Component{Name: "🏅"}, - }, - { - Label: "Salons ignorés", - Value: config.ModifyDisChannel, - Emoji: &emoji.Component{Name: "🫣"}, - }, - { - Label: "Temps avant la réduction d'expérience", - Value: config.ModifyTimeReduce, - Emoji: &emoji.Component{Name: "📉"}, - }, - }, + MenuType: types.SelectMenuChannel, + CustomID: config.ModifyDisChannel, + Placeholder: "Pas de salons désactivé", + MinValues: &zero, + MaxValues: 25, + DefaultValues: disChansDefault, + }, + }, + }, + &component.Section{ + Components: []component.Message{ + &component.TextDisplay{Content: "**Rôles de niveau**\n" + roles}, + }, + Accessory: &component.Button{ + Label: "Modifier", + Style: component.ButtonStyleSecondary, + CustomID: config.ModifyXpRole, + }, + }, + &component.Section{ + Components: []component.Message{ + &component.TextDisplay{ + Content: fmt.Sprintf("**Jours avant la réduction**\n-# Seule l'expérience gagnée les x derniers jours est comptabilisée dans le niveau par défaut\n%d jours", cfg.DaysXPRemains), }, }, + Accessory: &component.Button{ + Label: "Modifier", + Style: component.ButtonStyleSecondary, + CustomID: config.ModifyTimeReduce, + }, }, }, }, @@ -121,16 +134,31 @@ func ConfigCommand( } func ConfigMessageComponent( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder, ) { response := ConfigResponse(i) response.Type = types.InteractionResponseUpdateMessage - err := session.InteractionAPI().Respond(i.Interaction, response) + err := s.InteractionAPI().Respond(i.Interaction, response) + + if err != nil { + s.LogError(err, "sending config") + } +} + +func ConfigModal( + s *discordgo.Session, + i *discordgo.InteractionCreate, + _ *interaction.ModalSubmitData, + resp *cmd.ResponseBuilder, +) { + response := ConfigResponse(i) + response.Type = types.InteractionResponseUpdateMessage + err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - session.LogError(err, "sending config") + s.LogError(err, "sending config") } } diff --git a/config/channel.go b/config/channel.go index c918810..8b45382 100644 --- a/config/channel.go +++ b/config/channel.go @@ -5,12 +5,13 @@ import ( "github.com/anhgelus/gokord/cmd" discordgo "github.com/nyttikord/gokord" + + // "github.com/nyttikord/gokord/component" "github.com/nyttikord/gokord/interaction" ) const ( ModifyFallbackChannel = "fallback_channel" - FallbackChannelSet = "fallback_channel_set" ModifyDisChannel = "disabled_channel" DisChannelAdd = "disabled_channel_add" @@ -19,108 +20,28 @@ const ( DisChannelDelSet = "disabled_channel_del_set" ) -func HandleModifyFallbackChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder) { - //err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow().Add( - // component.NewChannelSelect(FallbackChannelSet).AddChannelType(discordgo.ChannelTypeGuildText), - //))).Send() - //if err != nil { - // logger.Alert("config/channel.go - Sending channel list for fallback", err.Error()) - //} -} - -func HandleFallbackChannelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() - +func HandleModifyFallbackChannel(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) bool { cfg := GetGuildConfig(i.GuildID) - channelID := data.Values[0] - + var channelID string + if len(data.Values) > 0 { + channelID = data.Values[0] + } cfg.FallbackChannel = channelID err := cfg.Save() if err != nil { - s.LogError(err, "saving fallback channel") - if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { - s.LogError(err, "sending error while saving channel") - } - return - } - if err = resp.SetMessage("Salon sauvegardé.").Send(); err != nil { - s.LogError(err, "sending channel saved") + s.LogError(err, "Saving fallback channel") + return false } + return true } -func HandleModifyDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder) { - //err := resp.IsEphemeral().SetComponents(component.New().Add(component.NewActionRow(). - // Add( - // component.NewButton(DisChannelAdd, discordgo.PrimaryButton). - // SetLabel("Désactiver un salon"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "⬇️"}), - // ). - // Add( - // component.NewButton(DisChannelDel, discordgo.DangerButton). - // SetLabel("Réactiver un salon"). - // SetEmoji(&discordgo.ComponentEmoji{Name: "⬆️"}), - // ), - //)).Send() - //if err != nil { - // logger.Alert("config/channel.go - Sending action type", err.Error()) - //} -} - -func HandleDisChannel(_ *discordgo.Session, _ *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - //resp.IsEphemeral().SetMessage("Salon à désactiver...") - //cID := DisChannelAddSet - //if data.CustomID == DisChannelDel { - // resp.SetMessage("Salon à réactiver...") - // cID = DisChannelDelSet - //} - //err := resp.SetComponents(component.New().Add(component.NewActionRow().Add(component.NewChannelSelect(cID)))).Send() - //if err != nil { - // logger.Alert("config/channel.go - Sending channel list for disable", err.Error()) - //} -} - -func HandleDisChannelAddSet(_ *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - //resp.IsEphemeral() - //cfg := GetGuildConfig(i.GuildID) - //id := data.Values[0] - //if strings.Contains(cfg.DisabledChannels, id) { - // err := resp.SetMessage("Le salon est déjà dans la liste des salons désactivés").Send() - // if err != nil { - // logger.Alert("commands/config.go - Channel already disabled", err.Error()) - // } - // return - //} - //cfg.DisabledChannels += id + ";" - //if err := cfg.Save(); err != nil { - // logger.Alert("commands/config.go - Saving config disable add", err.Error()) - // if err = resp.SetMessage("Il y a eu une erreur lors de la modification de de la base de données.").Send(); err != nil { - // logger.Alert("config/channel.go - Sending error while saving config", err.Error()) - // } - //} - //if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { - // logger.Alert("commands/config.go - Modification saved message disable add", err.Error()) - //} -} - -func HandleDisChannelDelSet(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - resp.IsEphemeral() +func HandleModifyDisChannel(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) bool { cfg := GetGuildConfig(i.GuildID) - id := data.Values[0] - if !strings.Contains(cfg.DisabledChannels, id) { - err := resp.SetMessage("Le salon n'est pas désactivé").Send() - if err != nil { - s.LogError(err, "sending channel not disabled") - } - return - } - cfg.DisabledChannels = strings.ReplaceAll(cfg.DisabledChannels, id+";", "") - if err := cfg.Save(); err != nil { - s.LogError(err, "saving config disable del") - if err = resp.SetMessage("Il y a eu une erreur lors de la modification de la base de données.").Send(); err != nil { - s.LogError(err, "sending error while saving config") - } - } - if err := resp.SetMessage("Modification sauvegardé.").Send(); err != nil { - s.LogError(err, "modification saved message disable del") + cfg.DisabledChannels = strings.Join(data.Values, ";") + err := cfg.Save() + if err != nil { + s.LogError(err, "Unable to save disabled channel") + return false } + return true } diff --git a/config/guild.go b/config/guild.go index 6310fa4..8096096 100644 --- a/config/guild.go +++ b/config/guild.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/anhgelus/gokord" + discordgo "github.com/nyttikord/gokord" ) type GuildConfig struct { @@ -31,8 +32,30 @@ func (cfg *GuildConfig) Save() error { return gokord.DB.Save(cfg).Error } -func (cfg *GuildConfig) IsDisabled(channelID string) bool { - return strings.Contains(cfg.DisabledChannels, channelID) +func (cfg *GuildConfig) IsDisabled(s *discordgo.Session, channelID string) bool { + ok := true + s.LogInfo("Configuration: %s", cfg.DisabledChannels) + s.LogInfo("Channel %s, ok %t", channelID, ok) + for channelID != "" && ok { + s.LogInfo("Channel %s, ok %t", channelID, ok) + ok = !strings.Contains(cfg.DisabledChannels, channelID) + c, err := s.State.Channel(channelID) + if err != nil { + s.LogError(err, "Unable to find channel %s in state", c) + c, err = s.ChannelAPI().Channel(channelID) + if err == nil { + s.State.ChannelAdd(c) + } else { + s.LogError(err, "Unable to fetch channel %s", s) + return false + } + } + if err != nil { + return false + } + channelID = c.ParentID + } + return !ok } func (cfg *GuildConfig) FindXpRole(roleID string) (int, *XpRole) { diff --git a/config/xp_reduce.go b/config/xp_reduce.go index a61ef1a..bf04bf0 100644 --- a/config/xp_reduce.go +++ b/config/xp_reduce.go @@ -1,8 +1,13 @@ package config import ( + "fmt" + "strconv" + "github.com/anhgelus/gokord/cmd" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/component" + "github.com/nyttikord/gokord/discord/types" "github.com/nyttikord/gokord/interaction" ) @@ -11,47 +16,61 @@ const ( TimeReduceSet = "time_reduce_set" ) -func HandleModifyPeriodicReduce(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - //err := resp.IsModal(). - // SetCustomID(TimeReduceSet). - // SetComponents(component.New().ForModal().Add(component.NewActionRow().ForModal().Add( - // component.NewTextInput(TimeReduceSet, "Jours avant la réduction", discordgo.TextInputShort). - // SetMinLength(1). - // SetMaxLength(3), - // ))).Send() - //if err != nil { - // logger.Alert("config/xp_reduce.go - Sending modal for periodic reduce", err.Error()) - //} +func HandleModifyPeriodicReduceCommand(s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + cfg := GetGuildConfig(i.GuildID) + response := interaction.Response{ + Type: types.InteractionResponseModal, + Data: &interaction.ResponseData{ + CustomID: TimeReduceSet, + Title: "Modifier la durée de l'expérience", + Components: []component.Component{ + // TODO: When gokord supports it, enable this description again + // &component.TextDisplay{ + // Content: "Seul l'expérience gagnée sur cette période sera comptabilisée dans le niveau par défaut", + // }, + &component.Label{ + Label: "Durée en jours", + Component: &component.TextInput{ + CustomID: TimeReduceSet, + MinLength: 1, + MaxLength: 3, + Style: component.TextInputShort, + Placeholder: "Durée en jours", + Value: fmt.Sprintf("%d", cfg.DaysXPRemains), + }, + }, + }, + }, + } + err := s.InteractionAPI().Respond(i.Interaction, &response) + if err != nil { + s.LogError(err, "Sending xp reduce modal") + } } -func HandleTimeReduceSet(_ *discordgo.Session, _ *discordgo.InteractionCreate, _ *interaction.ModalSubmitData, _ *cmd.ResponseBuilder) { - //resp.IsEphemeral() - //v := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value - //days, err := strconv.Atoi(v) - //if err != nil { - // logger.Debug(err.Error()) - // if err = resp.SetMessage("Nombres de jours invalides. Merci de mettre un entier.").Send(); err != nil { - // logger.Alert("config/xp_reduce.go - Sending bad input", err.Error()) - // } - // return - //} - //if days < 30 { - // err = resp.SetMessage("Le nombre de jours est inférieur à 30.").Send() - // if err != nil { - // logger.Alert("config/xp_reduce.go - Days < 30 (fallback)", err.Error()) - // } - // return - //} - //cfg := GetGuildConfig(i.GuildID) - //cfg.DaysXPRemains = uint(days) - //if err = cfg.Save(); err != nil { - // logger.Alert("config/channel.go - Saving days xp remains", err.Error()) - // if err = resp.SetMessage("Erreur lors de la sauvegarde du salon").Send(); err != nil { - // logger.Alert("config/xp_reduce.go - Sending error while saving days xp remains", err.Error()) - // } - // return - //} - //if err = resp.SetMessage("Modification sauvegardée.").Send(); err != nil { - // logger.Alert("config/xp_reduce.go - Sending days saved", err.Error()) - //} +func HandleTimeReduceSet(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) bool { + v := data.Components[0].(*component.Label).Component.(*component.TextInput).Value + days, err := strconv.Atoi(v) + 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") + } + 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") + } + return false + } + cfg := GetGuildConfig(i.GuildID) + cfg.DaysXPRemains = uint(days) + err = cfg.Save() + if err != nil { + s.LogError(err, "Saving DaysXPRemains configuration") + return false + } + return true } diff --git a/config/xp_role.go b/config/xp_role.go index 72af42b..8939dd6 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "sort" "strconv" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" @@ -33,7 +34,7 @@ const ( ) func HandleXpRole( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder, @@ -42,9 +43,13 @@ func HandleXpRole( container := component.Container{ Components: []component.Message{ &component.TextDisplay{Content: "## Configuration / Rôles de niveaux"}, + &component.TextDisplay{Content: "Ces rôles seront donnés et retirés en fonction du niveau de chacun"}, &component.Separator{}, }, } + sort.Slice(cfg.XpRoles, func(i, j int) bool { + return cfg.XpRoles[i].XP > cfg.XpRoles[j].XP + }) for _, r := range cfg.XpRoles { container.Components = append(container.Components, &component.Section{ Components: []component.Message{ @@ -84,14 +89,14 @@ func HandleXpRole( Flags: channel.MessageFlagsIsComponentsV2, }, } - err := session.InteractionAPI().Respond(i.Interaction, response) + err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - session.LogError(err, "Sending config") + s.LogError(err, "Sending config") } } func HandleXpRoleNew( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder, @@ -126,14 +131,14 @@ func HandleXpRoleNew( }, }, } - err := session.InteractionAPI().Respond(i.Interaction, response) + err := s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - session.LogError(err, "Sending modal to add") + s.LogError(err, "Sending modal to add") } } func HandleXpRoleEdit( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, parameters []string, resp *cmd.ResponseBuilder, @@ -141,12 +146,12 @@ func HandleXpRoleEdit( config := GetGuildConfig(i.GuildID) id, err := getRoleLevelID(parameters) if err != nil { - session.LogError(err, "Reading dynamic CustomID") + s.LogError(err, "Reading dynamic CustomID") return } _, role := config.FindXpRoleID(id) if role == nil { - HandleXpRole(session, i, &interaction.MessageComponentData{}, resp) + HandleXpRole(s, i, &interaction.MessageComponentData{}, resp) return } @@ -191,28 +196,28 @@ func HandleXpRoleEdit( }, } - err = session.InteractionAPI().Respond(i.Interaction, response) + err = s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - session.LogError(err, "Sending xp_role config") + s.LogError(err, "Sending xp_role config") } } func HandleXpRoleEditRole( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, parameters []string, resp *cmd.ResponseBuilder, ) { id, err := getRoleLevelID(parameters) if err != nil { - session.LogError(err, "Reading dynamic CustomID") + s.LogError(err, "Reading dynamic CustomID") return } role := data.Values[0] cfg := GetGuildConfig(i.GuildID) - _, xprole := cfg.FindXpRoleID(id) - if xprole == nil { - err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + _, xpRole := cfg.FindXpRoleID(id) + if xpRole == nil { + err = s.InteractionAPI().Respond(i.Interaction, &interaction.Response{ Type: types.InteractionResponseChannelMessageWithSource, Data: &interaction.ResponseData{ Flags: channel.MessageFlagsEphemeral, @@ -220,20 +225,20 @@ func HandleXpRoleEditRole( }, }) if err != nil { - session.LogError(err, "Sending unable to get role message") + s.LogError(err, "Sending unable to get role message") } return } - xprole.RoleID = role - err = gokord.DB.Save(xprole).Error + xpRole.RoleID = role + err = gokord.DB.Save(xpRole).Error if err != nil { - session.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) + s.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) } - HandleXpRoleEdit(session, i, &interaction.MessageComponentData{}, parameters, resp) + HandleXpRoleEdit(s, i, &interaction.MessageComponentData{}, parameters, resp) } func HandleXpRoleEditLevelStart( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, parameters []string, @@ -241,13 +246,13 @@ func HandleXpRoleEditLevelStart( ) { id, err := getRoleLevelID(parameters) if err != nil { - session.LogError(err, "Reading dynamic CustomID") + s.LogError(err, "Reading dynamic CustomID") return } cfg := GetGuildConfig(i.GuildID) - _, role := cfg.FindXpRoleID(id) - if role == nil { - err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + _, xpRole := cfg.FindXpRoleID(id) + if xpRole == nil { + err = s.InteractionAPI().Respond(i.Interaction, &interaction.Response{ Type: types.InteractionResponseChannelMessageWithSource, Data: &interaction.ResponseData{ Flags: channel.MessageFlagsEphemeral, @@ -255,7 +260,7 @@ func HandleXpRoleEditLevelStart( }, }) if err != nil { - session.LogError(err, "Sending Unable to get role message") + s.LogError(err, "Sending Unable to get role message") } return } @@ -274,20 +279,20 @@ func HandleXpRoleEditLevelStart( MinLength: 1, MaxLength: 5, Placeholder: "5", - Value: strconv.FormatUint(uint64(exp.Level(role.XP)), 10), + Value: strconv.FormatUint(uint64(exp.Level(xpRole.XP)), 10), }, }, }, }, } - err = session.InteractionAPI().Respond(i.Interaction, response) + err = s.InteractionAPI().Respond(i.Interaction, response) if err != nil { - session.LogError(err, "Sending Edit level modal") + s.LogError(err, "Sending Edit level modal") } } func HandleXpRoleEditLevel( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, parameters []string, @@ -295,7 +300,7 @@ func HandleXpRoleEditLevel( ) { id, err := getRoleLevelID(parameters) if err != nil { - session.LogError(err, "Reading dynamic CustomID") + s.LogError(err, "Reading dynamic CustomID") return } @@ -309,16 +314,16 @@ func HandleXpRoleEditLevel( ). Send() if err != nil { - session.LogError(err, "Sending bad number warning message") + s.LogError(err, "Sending bad number warning message") } return } xp := exp.LevelXP(uint(level)) cfg := GetGuildConfig(i.GuildID) - _, xprole := cfg.FindXpRoleID(id) - if xprole == nil { - err = session.InteractionAPI().Respond(i.Interaction, &interaction.Response{ + _, xpRole := cfg.FindXpRoleID(id) + if xpRole == nil { + err = s.InteractionAPI().Respond(i.Interaction, &interaction.Response{ Type: types.InteractionResponseChannelMessageWithSource, Data: &interaction.ResponseData{ Flags: channel.MessageFlagsEphemeral, @@ -326,20 +331,20 @@ func HandleXpRoleEditLevel( }, }) if err != nil { - session.LogError(err, "Sending unable to modify role message") + s.LogError(err, "Sending unable to modify role message") } return } - xprole.XP = xp - err = gokord.DB.Save(xprole).Error + xpRole.XP = xp + err = gokord.DB.Save(xpRole).Error if err != nil { - session.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) + s.LogError(err, "Saving config guild_id %s, id %d, type add", i.GuildID, id) } - HandleXpRoleEdit(session, i, &interaction.MessageComponentData{}, parameters, resp) + HandleXpRoleEdit(s, i, &interaction.MessageComponentData{}, parameters, resp) } func HandleXpRoleDel( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, dynamicValues []string, @@ -347,13 +352,13 @@ func HandleXpRoleDel( ) { id, err := getRoleLevelID(dynamicValues) if err != nil { - session.LogError(err, "reading dynamic CustomID") + s.LogError(err, "reading dynamic CustomID") return } cfg := GetGuildConfig(i.GuildID) _, role := cfg.FindXpRoleID(id) if role == nil { - err := session.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é ?", @@ -361,20 +366,20 @@ func HandleXpRoleDel( }, }) if err != nil { - session.LogError(err, "Sending role not found message") + s.LogError(err, "Sending role not found message") } return } err = gokord.DB.Delete(role).Error if err != nil { - session.LogError(err, "Deleting entry guild_id %s, id %d, type del", i.GuildID, id) + s.LogError(err, "Deleting entry guild_id %s, id %d, type del", i.GuildID, id) } - HandleXpRole(session, i, &interaction.MessageComponentData{}, resp) + HandleXpRole(s, i, &interaction.MessageComponentData{}, resp) } func HandleXpRoleAdd( - session *discordgo.Session, + s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder, @@ -389,7 +394,7 @@ func HandleXpRoleAdd( ). Send() if err != nil { - session.LogError(err, "sending bad number warning message") + s.LogError(err, "sending bad number warning message") } return } @@ -404,11 +409,11 @@ func HandleXpRoleAdd( }) err = cfg.Save() if err != nil { - session.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) + s.LogError(err, "saving config for role %s in %s", roleId, i.GuildID) return } - HandleXpRole(session, i, &interaction.MessageComponentData{}, resp) + HandleXpRole(s, i, &interaction.MessageComponentData{}, resp) } func getRoleLevelID(dynamic []string) (uint, error) { diff --git a/events.go b/events.go index 9f247d3..38f259c 100644 --- a/events.go +++ b/events.go @@ -27,7 +27,7 @@ func OnMessage(s *discordgo.Session, m *discordgo.MessageCreate) { return } cfg := config.GetGuildConfig(m.GuildID) - if cfg.IsDisabled(m.ChannelID) { + if cfg.IsDisabled(s, m.ChannelID) { return } c := user.GetCopaing(m.Author.ID, m.GuildID) @@ -48,13 +48,13 @@ func OnVoiceUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { return } cfg := config.GetGuildConfig(e.GuildID) - if (e.BeforeUpdate == nil || cfg.IsDisabled(e.BeforeUpdate.ChannelID)) && e.ChannelID != "" { - if cfg.IsDisabled(e.ChannelID) { + if (e.BeforeUpdate == nil || cfg.IsDisabled(s, e.BeforeUpdate.ChannelID)) && e.ChannelID != "" { + if cfg.IsDisabled(s, e.ChannelID) { return } onConnection(s, e) - } else if e.BeforeUpdate != nil && (e.ChannelID == "" || cfg.IsDisabled(e.ChannelID)) { - if cfg.IsDisabled(e.BeforeUpdate.ChannelID) { + } else if e.BeforeUpdate != nil && (e.ChannelID == "" || cfg.IsDisabled(s, e.ChannelID)) { + if cfg.IsDisabled(s, e.BeforeUpdate.ChannelID) { return } onDisconnect(s, e) diff --git a/main.go b/main.go index b2fdf84..328b9b5 100644 --- a/main.go +++ b/main.go @@ -241,14 +241,8 @@ func main() { return } switch data.Values[0] { - case config.ModifyXpRole: - config.HandleXpRole(s, i, data, resp) - case config.ModifyFallbackChannel: - config.HandleModifyFallbackChannel(s, i, data, resp) case config.ModifyDisChannel: config.HandleModifyDisChannel(s, i, data, resp) - case config.ModifyTimeReduce: - config.HandleModifyPeriodicReduce(s, i, data, resp) default: bot.LogError(errors.New("unknown value"), "detecting value %s", data.Values[0]) return @@ -265,13 +259,23 @@ func main() { handleDynamicModalComponent(&bot, config.HandleXpRoleEditLevel, config.XpRoleEditLevelPattern) handleDynamicMessageComponent(&bot, config.HandleXpRoleDel, config.XpRoleDel) // channel related - bot.HandleMessageComponent(config.HandleFallbackChannelSet, config.FallbackChannelSet) - bot.HandleMessageComponent(config.HandleDisChannel, config.DisChannelAdd) - bot.HandleMessageComponent(config.HandleDisChannel, config.DisChannelDel) - bot.HandleMessageComponent(config.HandleDisChannelAddSet, config.DisChannelAddSet) - bot.HandleMessageComponent(config.HandleDisChannelDelSet, config.DisChannelDelSet) + bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + if config.HandleModifyFallbackChannel(s, i, data, resp) { + commands.ConfigMessageComponent(s, i, data, resp) + } + }, config.ModifyFallbackChannel) + bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + if config.HandleModifyDisChannel(s, i, data, resp) { + commands.ConfigMessageComponent(s, i, data, resp) + } + }, config.ModifyDisChannel) // reduce related - bot.HandleModal(config.HandleTimeReduceSet, config.TimeReduceSet) + bot.HandleMessageComponent(config.HandleModifyPeriodicReduceCommand, config.ModifyTimeReduce) + bot.HandleModal(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { + if config.HandleTimeReduceSet(s, i, data, resp) { + commands.ConfigModal(s, i, data, resp) + } + }, config.TimeReduceSet) // xp handlers bot.AddHandler(OnMessage) -- cgit v1.2.3 From 1d4994286d9d787724110821077cbba993b4f94a Mon Sep 17 00:00:00 2001 From: ascpial Date: Sun, 21 Sep 2025 00:00:23 +0200 Subject: fix(config): remove useless code --- main.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/main.go b/main.go index 328b9b5..3b7495a 100644 --- a/main.go +++ b/main.go @@ -235,19 +235,6 @@ func main() { } // interaction: /config - bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { - if len(data.Values) != 1 { - bot.LogError(errors.New("invalid data values"), "handle config modify, values: %#v", data.Values) - return - } - switch data.Values[0] { - case config.ModifyDisChannel: - config.HandleModifyDisChannel(s, i, data, resp) - default: - bot.LogError(errors.New("unknown value"), "detecting value %s", data.Values[0]) - return - } - }, commands.ConfigModify) bot.HandleMessageComponent(commands.ConfigMessageComponent, commands.OpenConfig) // xp role related bot.HandleMessageComponent(config.HandleXpRole, config.ModifyXpRole) -- cgit v1.2.3 From beaea94172f16c350515cb28941f3d5a2101b690 Mon Sep 17 00:00:00 2001 From: ascpial Date: Sun, 21 Sep 2025 00:18:15 +0200 Subject: perf(config): use more modern slices.SortFunc --- commands/config.go | 6 +++--- config/xp_role.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/commands/config.go b/commands/config.go index 5a2f763..fc15a5c 100644 --- a/commands/config.go +++ b/commands/config.go @@ -2,7 +2,7 @@ package commands import ( "fmt" - "sort" + "slices" "strings" "git.anhgelus.world/anhgelus/les-copaings-bot/config" @@ -24,8 +24,8 @@ func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { cfg := config.GetGuildConfig(i.GuildID) roles := "" l := len(cfg.XpRoles) - 1 - sort.Slice(cfg.XpRoles, func(i, j int) bool { - return cfg.XpRoles[i].XP > cfg.XpRoles[j].XP + slices.SortFunc(cfg.XpRoles, func(xp1, xp2 config.XpRole) int { + return int(xp2.XP) - int(xp1.XP) }) for i, r := range cfg.XpRoles { if i == l { diff --git a/config/xp_role.go b/config/xp_role.go index 8939dd6..d55e6d3 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -2,7 +2,7 @@ package config import ( "fmt" - "sort" + "slices" "strconv" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" @@ -47,8 +47,8 @@ func HandleXpRole( &component.Separator{}, }, } - sort.Slice(cfg.XpRoles, func(i, j int) bool { - return cfg.XpRoles[i].XP > cfg.XpRoles[j].XP + slices.SortFunc(cfg.XpRoles, func(xp1, xp2 XpRole) int { + return int(xp2.XP) - int(xp1.XP) }) for _, r := range cfg.XpRoles { container.Components = append(container.Components, &component.Section{ -- cgit v1.2.3 From 30f110d8d49cd1174882c58916147f52e09dd51e Mon Sep 17 00:00:00 2001 From: ascpial Date: Sun, 21 Sep 2025 23:34:31 +0200 Subject: fix(config): forgot some things --- config/channel.go | 1 - config/guild.go | 3 --- 2 files changed, 4 deletions(-) diff --git a/config/channel.go b/config/channel.go index 8b45382..723ec38 100644 --- a/config/channel.go +++ b/config/channel.go @@ -6,7 +6,6 @@ import ( "github.com/anhgelus/gokord/cmd" discordgo "github.com/nyttikord/gokord" - // "github.com/nyttikord/gokord/component" "github.com/nyttikord/gokord/interaction" ) diff --git a/config/guild.go b/config/guild.go index 8096096..9cdb7e4 100644 --- a/config/guild.go +++ b/config/guild.go @@ -34,10 +34,7 @@ func (cfg *GuildConfig) Save() error { func (cfg *GuildConfig) IsDisabled(s *discordgo.Session, channelID string) bool { ok := true - s.LogInfo("Configuration: %s", cfg.DisabledChannels) - s.LogInfo("Channel %s, ok %t", channelID, ok) for channelID != "" && ok { - s.LogInfo("Channel %s, ok %t", channelID, ok) ok = !strings.Contains(cfg.DisabledChannels, channelID) c, err := s.State.Channel(channelID) if err != nil { -- cgit v1.2.3 From b61a834b608df3d5e617912eefb28924ef3a46df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Fri, 26 Sep 2025 18:30:57 +0200 Subject: build(gokord): bump to latest nightly --- commands/config.go | 27 ++++++++++++++------------- commands/credits.go | 5 +++-- commands/rank.go | 5 +++-- commands/reset.go | 7 ++++--- commands/stats.go | 13 +++++++------ commands/top.go | 5 +++-- config/channel.go | 7 ++++--- config/guild.go | 15 +++++++++------ config/xp_reduce.go | 7 ++++--- config/xp_role.go | 35 ++++++++++++++++++----------------- events.go | 13 +++++++------ go.mod | 4 ++-- go.sum | 4 ++++ main.go | 50 ++++++++++++++++++++++++++------------------------ user/level.go | 9 ++++++--- user/xp.go | 4 ++-- 16 files changed, 116 insertions(+), 94 deletions(-) diff --git a/commands/config.go b/commands/config.go index fc15a5c..7ffd4af 100644 --- a/commands/config.go +++ b/commands/config.go @@ -8,10 +8,11 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/channel" "github.com/nyttikord/gokord/component" "github.com/nyttikord/gokord/discord/types" + "github.com/nyttikord/gokord/event" "github.com/nyttikord/gokord/interaction" ) @@ -20,7 +21,7 @@ const ( OpenConfig = "config" ) -func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { +func ConfigResponse(i *event.InteractionCreate) *interaction.Response { cfg := config.GetGuildConfig(i.GuildID) roles := "" l := len(cfg.XpRoles) - 1 @@ -38,7 +39,7 @@ func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { roles = "Aucun rôle configuré" } disChans := strings.Split(cfg.DisabledChannels, ";") - disChansDefault := []component.SelectMenuDefaultValue{} + var disChansDefault []component.SelectMenuDefaultValue for _, c := range disChans { if c != "" { disChansDefault = append(disChansDefault, component.SelectMenuDefaultValue{ @@ -47,7 +48,7 @@ func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { }) } } - defaultChan := []component.SelectMenuDefaultValue{} + var defaultChan []component.SelectMenuDefaultValue if len(cfg.FallbackChannel) > 0 { defaultChan = append(defaultChan, component.SelectMenuDefaultValue{ ID: cfg.FallbackChannel, @@ -121,21 +122,21 @@ func ConfigResponse(i *discordgo.InteractionCreate) *interaction.Response { } func ConfigCommand( - session *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder, ) { - err := session.InteractionAPI().Respond(i.Interaction, ConfigResponse(i)) + err := s.InteractionAPI().Respond(i.Interaction, ConfigResponse(i)) if err != nil { - session.LogError(err, "config/guild.go - Sending config") + s.LogError(err, "config/guild.go - Sending config") } } func ConfigMessageComponent( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder, ) { @@ -149,10 +150,10 @@ func ConfigMessageComponent( } func ConfigModal( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.ModalSubmitData, - resp *cmd.ResponseBuilder, + _ *cmd.ResponseBuilder, ) { response := ConfigResponse(i) response.Type = types.InteractionResponseUpdateMessage diff --git a/commands/credits.go b/commands/credits.go index e5fd711..b303834 100644 --- a/commands/credits.go +++ b/commands/credits.go @@ -3,10 +3,11 @@ package commands import ( "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" + "github.com/nyttikord/gokord/event" ) -func Credits(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Credits(s bot.Session, _ *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { msg := "**Les Copaings**, le bot gérant les serveurs privés de [anhgelus]().\n" msg += "Code source : \n\n" msg += "Host du bot : " + gokord.BaseCfg.GetAuthor() + ".\n\n" diff --git a/commands/rank.go b/commands/rank.go index d3a9f70..8f3090f 100644 --- a/commands/rank.go +++ b/commands/rank.go @@ -6,10 +6,11 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" + "github.com/nyttikord/gokord/event" ) -func Rank(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Rank(s bot.Session, i *event.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { c := user.GetCopaing(i.Member.User.ID, i.GuildID) // current user = member who used /rank msg := "Votre niveau" m := i.Member diff --git a/commands/reset.go b/commands/reset.go index 77561c1..7caa238 100644 --- a/commands/reset.go +++ b/commands/reset.go @@ -4,10 +4,11 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" + "github.com/nyttikord/gokord/event" ) -func Reset(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Reset(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { 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 { @@ -15,7 +16,7 @@ func Reset(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap } } -func ResetUser(s *discordgo.Session, i *discordgo.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { +func ResetUser(s bot.Session, i *event.InteractionCreate, optMap cmd.OptionMap, resp *cmd.ResponseBuilder) { resp.IsEphemeral() v, ok := optMap["user"] if !ok { diff --git a/commands/stats.go b/commands/stats.go index fcb0c29..2c22f0d 100644 --- a/commands/stats.go +++ b/commands/stats.go @@ -16,8 +16,9 @@ import ( "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" "github.com/jackc/pgx/v5/pgtype" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/channel" + "github.com/nyttikord/gokord/event" "gonum.org/v1/plot" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" @@ -45,7 +46,7 @@ var colors = []color.RGBA{ {193, 18, 31, 255}, } -func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionMap, resp *cmd.ResponseBuilder) { +func Stats(s bot.Session, i *event.InteractionCreate, opt cmd.OptionMap, resp *cmd.ResponseBuilder) { cfg := config.GetGuildConfig(i.GuildID) days := 15 if gokord.Debug { @@ -97,13 +98,13 @@ func Stats(s *discordgo.Session, i *discordgo.InteractionCreate, opt cmd.OptionM }() } -func statsAll(s *discordgo.Session, i *discordgo.InteractionCreate, days int) (io.WriterTo, error) { +func statsAll(s bot.Session, i *event.InteractionCreate, days int) (io.WriterTo, error) { return stats(s, i, days, func(before, after string) *gorm.DB { return gokord.DB.Raw(before+"WHERE guild_id = ? and created_at > ?"+after, i.GuildID, exp.TimeStampNDaysBefore(uint(days))) }) } -func statsMember(s *discordgo.Session, i *discordgo.InteractionCreate, days int, discordID string) (io.WriterTo, error) { +func statsMember(s bot.Session, i *event.InteractionCreate, days int, discordID string) (io.WriterTo, error) { _, err := s.GuildAPI().Member(i.GuildID, discordID) if err != nil { return nil, err @@ -116,7 +117,7 @@ func statsMember(s *discordgo.Session, i *discordgo.InteractionCreate, days int, }) } -func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execSql func(before, after string) *gorm.DB) (io.WriterTo, error) { +func stats(s bot.Session, i *event.InteractionCreate, days int, execSql func(before, after string) *gorm.DB) (io.WriterTo, error) { var rawData []*data if gokord.Debug { var rawCopaingData []*user.CopaingXP @@ -193,7 +194,7 @@ func stats(s *discordgo.Session, i *discordgo.InteractionCreate, days int, execS return generatePlot(s, i, copaings, stats) } -func generatePlot(s *discordgo.Session, i *discordgo.InteractionCreate, copaings map[int]*user.Copaing, stats map[int][]plotter.XY) (io.WriterTo, error) { +func generatePlot(s bot.Session, i *event.InteractionCreate, copaings map[int]*user.Copaing, stats map[int][]plotter.XY) (io.WriterTo, error) { p := plot.New() fontSizeTitle := vg.Length(16) fontSize := vg.Length(12) diff --git a/commands/top.go b/commands/top.go index 195ee9b..751f7fa 100644 --- a/commands/top.go +++ b/commands/top.go @@ -8,11 +8,12 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/channel" + "github.com/nyttikord/gokord/event" ) -func Top(s *discordgo.Session, i *discordgo.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { +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") diff --git a/config/channel.go b/config/channel.go index 723ec38..1ee6974 100644 --- a/config/channel.go +++ b/config/channel.go @@ -4,7 +4,8 @@ import ( "strings" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" + "github.com/nyttikord/gokord/event" "github.com/nyttikord/gokord/interaction" ) @@ -19,7 +20,7 @@ const ( DisChannelDelSet = "disabled_channel_del_set" ) -func HandleModifyFallbackChannel(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) bool { +func HandleModifyFallbackChannel(s bot.Session, i *event.InteractionCreate, data *interaction.MessageComponentData, _ *cmd.ResponseBuilder) bool { cfg := GetGuildConfig(i.GuildID) var channelID string if len(data.Values) > 0 { @@ -34,7 +35,7 @@ func HandleModifyFallbackChannel(s *discordgo.Session, i *discordgo.InteractionC return true } -func HandleModifyDisChannel(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) bool { +func HandleModifyDisChannel(s bot.Session, i *event.InteractionCreate, data *interaction.MessageComponentData, _ *cmd.ResponseBuilder) bool { cfg := GetGuildConfig(i.GuildID) cfg.DisabledChannels = strings.Join(data.Values, ";") err := cfg.Save() diff --git a/config/guild.go b/config/guild.go index 9cdb7e4..10c64fd 100644 --- a/config/guild.go +++ b/config/guild.go @@ -4,7 +4,7 @@ import ( "strings" "github.com/anhgelus/gokord" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" ) type GuildConfig struct { @@ -32,18 +32,21 @@ func (cfg *GuildConfig) Save() error { return gokord.DB.Save(cfg).Error } -func (cfg *GuildConfig) IsDisabled(s *discordgo.Session, channelID string) bool { +func (cfg *GuildConfig) IsDisabled(s bot.Session, channelID string) bool { ok := true for channelID != "" && ok { ok = !strings.Contains(cfg.DisabledChannels, channelID) - c, err := s.State.Channel(channelID) + c, err := s.ChannelAPI().State.Channel(channelID) if err != nil { - s.LogError(err, "Unable to find channel %s in state", c) + s.LogError(err, "unable to find channel %s in state", c) c, err = s.ChannelAPI().Channel(channelID) if err == nil { - s.State.ChannelAdd(c) + err = s.ChannelAPI().State.ChannelAdd(c) + if err != nil { + s.LogError(err, "unable to add channel %s to state", c) + } } else { - s.LogError(err, "Unable to fetch channel %s", s) + s.LogError(err, "unable to fetch channel %s", s) return false } } diff --git a/config/xp_reduce.go b/config/xp_reduce.go index bf04bf0..c3a3e10 100644 --- a/config/xp_reduce.go +++ b/config/xp_reduce.go @@ -5,9 +5,10 @@ import ( "strconv" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/component" "github.com/nyttikord/gokord/discord/types" + "github.com/nyttikord/gokord/event" "github.com/nyttikord/gokord/interaction" ) @@ -16,7 +17,7 @@ const ( TimeReduceSet = "time_reduce_set" ) -func HandleModifyPeriodicReduceCommand(s *discordgo.Session, i *discordgo.InteractionCreate, _ *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { +func HandleModifyPeriodicReduceCommand(s bot.Session, i *event.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder) { cfg := GetGuildConfig(i.GuildID) response := interaction.Response{ Type: types.InteractionResponseModal, @@ -48,7 +49,7 @@ func HandleModifyPeriodicReduceCommand(s *discordgo.Session, i *discordgo.Intera } } -func HandleTimeReduceSet(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) bool { +func HandleTimeReduceSet(s bot.Session, i *event.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) bool { v := data.Components[0].(*component.Label).Component.(*component.TextInput).Value days, err := strconv.Atoi(v) if err != nil { diff --git a/config/xp_role.go b/config/xp_role.go index d55e6d3..42fe9f4 100644 --- a/config/xp_role.go +++ b/config/xp_role.go @@ -8,10 +8,11 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" "github.com/anhgelus/gokord/cmd" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/channel" "github.com/nyttikord/gokord/component" "github.com/nyttikord/gokord/discord/types" + "github.com/nyttikord/gokord/event" "github.com/nyttikord/gokord/interaction" ) @@ -34,8 +35,8 @@ const ( ) func HandleXpRole( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder, ) { @@ -96,8 +97,8 @@ func HandleXpRole( } func HandleXpRoleNew( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.MessageComponentData, _ *cmd.ResponseBuilder, ) { @@ -138,8 +139,8 @@ func HandleXpRoleNew( } func HandleXpRoleEdit( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.MessageComponentData, parameters []string, resp *cmd.ResponseBuilder, ) { @@ -203,8 +204,8 @@ func HandleXpRoleEdit( } func HandleXpRoleEditRole( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, data *interaction.MessageComponentData, parameters []string, resp *cmd.ResponseBuilder, ) { @@ -238,8 +239,8 @@ func HandleXpRoleEditRole( } func HandleXpRoleEditLevelStart( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.MessageComponentData, parameters []string, _ *cmd.ResponseBuilder, @@ -292,8 +293,8 @@ func HandleXpRoleEditLevelStart( } func HandleXpRoleEditLevel( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, data *interaction.ModalSubmitData, parameters []string, resp *cmd.ResponseBuilder, @@ -344,8 +345,8 @@ func HandleXpRoleEditLevel( } func HandleXpRoleDel( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, _ *interaction.MessageComponentData, dynamicValues []string, resp *cmd.ResponseBuilder, @@ -379,8 +380,8 @@ func HandleXpRoleDel( } func HandleXpRoleAdd( - s *discordgo.Session, - i *discordgo.InteractionCreate, + s bot.Session, + i *event.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder, ) { diff --git a/events.go b/events.go index 38f259c..8de04b8 100644 --- a/events.go +++ b/events.go @@ -9,7 +9,8 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "git.anhgelus.world/anhgelus/les-copaings-bot/user" "github.com/anhgelus/gokord" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" + "github.com/nyttikord/gokord/event" ) const ( @@ -22,7 +23,7 @@ var ( connectedSince = map[string]int64{} ) -func OnMessage(s *discordgo.Session, m *discordgo.MessageCreate) { +func OnMessage(s bot.Session, m *event.MessageCreate) { if m.Author.Bot { return } @@ -43,7 +44,7 @@ func OnMessage(s *discordgo.Session, m *discordgo.MessageCreate) { }) } -func OnVoiceUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { +func OnVoiceUpdate(s bot.Session, e *event.VoiceStateUpdate) { if e.Member.User.Bot { return } @@ -65,12 +66,12 @@ func genMapKey(guildID string, userID string) string { return fmt.Sprintf("%s:%s", guildID, userID) } -func onConnection(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { +func onConnection(s bot.Session, e *event.VoiceStateUpdate) { s.LogDebug("User connected username %s", e.Member.DisplayName()) connectedSince[genMapKey(e.GuildID, e.UserID)] = time.Now().Unix() } -func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { +func onDisconnect(s bot.Session, e *event.VoiceStateUpdate) { now := time.Now().Unix() c := user.GetCopaing(e.UserID, e.GuildID) // check the validity of user @@ -106,7 +107,7 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { }) } -func OnLeave(s *discordgo.Session, e *discordgo.GuildMemberRemove) { +func OnLeave(s bot.Session, e *event.GuildMemberRemove) { s.LogDebug("Leave event user_id %s", e.User.ID) if e.User.Bot { return diff --git a/go.mod b/go.mod index b59127f..5d74727 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,10 @@ go 1.24.0 toolchain go1.24.6 require ( - github.com/anhgelus/gokord v0.12.0 + github.com/anhgelus/gokord v0.12.1-0.20250926161635-21b1b138fd90 github.com/jackc/pgx/v5 v5.7.5 github.com/joho/godotenv v1.5.1 - github.com/nyttikord/gokord v0.31.0 + github.com/nyttikord/gokord v0.31.1-0.20250926154959-93603cbc1df5 github.com/pelletier/go-toml/v2 v2.2.4 golang.org/x/image v0.30.0 gonum.org/v1/plot v0.16.0 diff --git a/go.sum b/go.sum index 0ba1236..1f11bf6 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyR github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/anhgelus/gokord v0.12.0 h1:6315krG631amMYRBXkp0Uz7voBtbgEHJZKsNgulu+18= 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/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= @@ -53,6 +55,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/nyttikord/gokord v0.31.0 h1:64DeVCTQpSWj8/RtBm0GtHeh0Gqo3arJGtrSIn5/U0I= 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/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= diff --git a/main.go b/main.go index 3b7495a..f1555f0 100644 --- a/main.go +++ b/main.go @@ -17,8 +17,10 @@ import ( "github.com/anhgelus/gokord/cmd" "github.com/joho/godotenv" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/discord" "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" @@ -69,15 +71,15 @@ func init() { func handleDynamicMessageComponent( b *gokord.Bot, handler func( - *discordgo.Session, - *discordgo.InteractionCreate, + bot.Session, + *event.InteractionCreate, *interaction.MessageComponentData, []string, *cmd.ResponseBuilder, ), pattern string, ) { compiledPattern := regexp.MustCompile(pattern) - b.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + b.AddHandler(func(s bot.Session, i *event.InteractionCreate) { if i.Type != types.InteractionMessageComponent { return } @@ -95,8 +97,8 @@ func handleDynamicMessageComponent( func handleDynamicModalComponent( b *gokord.Bot, handler func( - *discordgo.Session, - *discordgo.InteractionCreate, + bot.Session, + *event.InteractionCreate, *interaction.ModalSubmitData, []string, *cmd.ResponseBuilder, @@ -104,7 +106,7 @@ func handleDynamicModalComponent( pattern string, ) { compiledPattern := regexp.MustCompile(pattern) - b.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { + b.AddHandler(func(s bot.Session, i *event.InteractionCreate) { if i.Type != types.InteractionModalSubmit { return } @@ -185,7 +187,7 @@ func main() { panic(err) } - bot := gokord.Bot{ + b := gokord.Bot{ Token: token, Status: []*gokord.Status{ { @@ -235,41 +237,41 @@ func main() { } // interaction: /config - bot.HandleMessageComponent(commands.ConfigMessageComponent, commands.OpenConfig) + b.HandleMessageComponent(commands.ConfigMessageComponent, commands.OpenConfig) // xp role related - bot.HandleMessageComponent(config.HandleXpRole, config.ModifyXpRole) - bot.HandleMessageComponent(config.HandleXpRoleNew, config.XpRoleNew) - bot.HandleModal(config.HandleXpRoleAdd, config.XpRoleAdd) - handleDynamicMessageComponent(&bot, config.HandleXpRoleEdit, config.XpRoleEditPattern) - handleDynamicMessageComponent(&bot, config.HandleXpRoleEditRole, config.XpRoleEditRolePattern) - handleDynamicMessageComponent(&bot, config.HandleXpRoleEditLevelStart, config.XpRoleEditLevelStartPattern) - handleDynamicModalComponent(&bot, config.HandleXpRoleEditLevel, config.XpRoleEditLevelPattern) - handleDynamicMessageComponent(&bot, config.HandleXpRoleDel, config.XpRoleDel) + b.HandleMessageComponent(config.HandleXpRole, config.ModifyXpRole) + b.HandleMessageComponent(config.HandleXpRoleNew, config.XpRoleNew) + b.HandleModal(config.HandleXpRoleAdd, config.XpRoleAdd) + handleDynamicMessageComponent(&b, config.HandleXpRoleEdit, config.XpRoleEditPattern) + handleDynamicMessageComponent(&b, config.HandleXpRoleEditRole, config.XpRoleEditRolePattern) + handleDynamicMessageComponent(&b, config.HandleXpRoleEditLevelStart, config.XpRoleEditLevelStartPattern) + handleDynamicModalComponent(&b, config.HandleXpRoleEditLevel, config.XpRoleEditLevelPattern) + handleDynamicMessageComponent(&b, config.HandleXpRoleDel, config.XpRoleDel) // channel related - bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + b.HandleMessageComponent(func(s bot.Session, i *event.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { if config.HandleModifyFallbackChannel(s, i, data, resp) { commands.ConfigMessageComponent(s, i, data, resp) } }, config.ModifyFallbackChannel) - bot.HandleMessageComponent(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { + b.HandleMessageComponent(func(s bot.Session, i *event.InteractionCreate, data *interaction.MessageComponentData, resp *cmd.ResponseBuilder) { if config.HandleModifyDisChannel(s, i, data, resp) { commands.ConfigMessageComponent(s, i, data, resp) } }, config.ModifyDisChannel) // reduce related - bot.HandleMessageComponent(config.HandleModifyPeriodicReduceCommand, config.ModifyTimeReduce) - bot.HandleModal(func(s *discordgo.Session, i *discordgo.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { + b.HandleMessageComponent(config.HandleModifyPeriodicReduceCommand, config.ModifyTimeReduce) + b.HandleModal(func(s bot.Session, i *event.InteractionCreate, data *interaction.ModalSubmitData, resp *cmd.ResponseBuilder) { if config.HandleTimeReduceSet(s, i, data, resp) { commands.ConfigModal(s, i, data, resp) } }, config.TimeReduceSet) // xp handlers - bot.AddHandler(OnMessage) - bot.AddHandler(OnVoiceUpdate) - bot.AddHandler(OnLeave) + b.AddHandler(OnMessage) + b.AddHandler(OnVoiceUpdate) + b.AddHandler(OnLeave) - bot.Start() + b.Start() if stopPeriodicReducer != nil { stopPeriodicReducer <- true diff --git a/user/level.go b/user/level.go index e11ac03..88971e6 100644 --- a/user/level.go +++ b/user/level.go @@ -9,10 +9,11 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/user" ) -func onNewLevel(s *discordgo.Session, m *user.Member, level uint) { +func onNewLevel(s bot.Session, m *user.Member, level uint) { cfg := config.GetGuildConfig(m.GuildID) xpForLevel := exp.LevelXP(level) for _, role := range cfg.XpRoles { @@ -68,7 +69,9 @@ func PeriodicReducer(s *discordgo.Session) { }() } wg.Wait() - for _, g := range s.State.Guilds { + i := 0 + for g := range s.GuildAPI().State.Guilds() { + i++ wg.Add(1) go func() { defer wg.Done() @@ -99,5 +102,5 @@ func PeriodicReducer(s *discordgo.Session) { c.OnNewLevel(s, exp.Level(xp)) } } - s.LogDebug("Periodic reduce finished for %d guilds", len(s.State.Guilds)) + s.LogDebug("Periodic reduce finished for %d guilds", i) } diff --git a/user/xp.go b/user/xp.go index 96a8a27..16ba0ad 100644 --- a/user/xp.go +++ b/user/xp.go @@ -7,7 +7,7 @@ import ( "git.anhgelus.world/anhgelus/les-copaings-bot/config" "git.anhgelus.world/anhgelus/les-copaings-bot/exp" "github.com/anhgelus/gokord" - discordgo "github.com/nyttikord/gokord" + "github.com/nyttikord/gokord/bot" "github.com/nyttikord/gokord/logger" "github.com/nyttikord/gokord/user" ) @@ -25,7 +25,7 @@ func (c *cXP) GetXP() uint { return c.Cxp } -func (c *Copaing) AddXP(s *discordgo.Session, m *user.Member, xp uint, fn func(uint, uint)) { +func (c *Copaing) AddXP(s bot.Session, m *user.Member, xp uint, fn func(uint, uint)) { old, err := c.GetXP() if err != nil { s.LogError(err, "getting xp for %s in %s", m.DisplayName(), c.GuildID) -- cgit v1.2.3 From dca669455f4746666fd3a1177a4db2eaa5320cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Fri, 26 Sep 2025 18:46:06 +0200 Subject: feat(gokord): update updates.json --- updates.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/updates.json b/updates.json index 452a306..173aff0 100644 --- a/updates.json +++ b/updates.json @@ -40,5 +40,14 @@ "config" ] } + }, + { + "version": "3.3.0", + "commands": { + "added": [], + "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]().\n\nLa prochaine version devrait arrivée prochainement, elle touchera surtout des modifications en interne, peut visible par les utilisateurs et les administrateurs." } ] -- cgit v1.2.3 From cfdba5f417bb31aac564d13becc09874f17d075d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 27 Sep 2025 17:34:38 +0200 Subject: build(gokord): bump to latest nightly --- commands/config.go | 6 +++--- commands/credits.go | 2 +- commands/rank.go | 14 +++++++------- commands/reset.go | 12 ++++++------ commands/stats.go | 31 ++++++++++++------------------- commands/top.go | 8 ++++---- config/channel.go | 4 ++-- config/guild.go | 6 +++--- config/xp_reduce.go | 8 ++++---- config/xp_role.go | 40 ++++++++++++++++++++-------------------- events.go | 31 ++++++++++++++++++------------- go.mod | 6 +++--- go.sum | 6 ++++++ main.go | 8 ++++---- updates.json | 2 +- user/level.go | 40 ++++++++++++++++++++++++++-------------- 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]()" 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 } diff --git a/events.go b/events.go index 8de04b8..9a3f508 100644 --- a/events.go +++ b/events.go @@ -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) } } diff --git a/go.mod b/go.mod index 5d74727..8e1ebe9 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 1f11bf6..ad1282f 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/main.go b/main.go index f1555f0..56753e1 100644 --- a/main.go +++ b/main.go @@ -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]().\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]().\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) } diff --git a/user/xp.go b/user/xp.go index 16ba0ad..dbca9de 100644 --- a/user/xp.go +++ b/user/xp.go @@ -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}) -- cgit v1.2.3