aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--config/guild.go15
-rw-r--r--config/xp_role.go7
-rw-r--r--go.sum10
-rw-r--r--user/xp.go30
5 files changed, 43 insertions, 21 deletions
diff --git a/README.md b/README.md
index 6355f32..efd2005 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Bot for the private server Discord "Les Copaings"
- Roles management
- Purge command
-### CopaingXPs
+### XPs
Functions:
- $xp-message(x;y) = 0.025 x^{1.25}\sqrt{y}+1$ where $x$ is the length of the message and $y$ is the diversity of the
diff --git a/config/guild.go b/config/guild.go
index e046ca7..c2a1636 100644
--- a/config/guild.go
+++ b/config/guild.go
@@ -11,11 +11,26 @@ type GuildConfig struct {
ID uint `gorm:"primarykey"`
GuildID string `gorm:"not null;unique"`
XpRoles []XpRole
+ BoostXpRoles []BoostXpRole
DisabledChannels string
FallbackChannel string
DaysXPRemains uint `gorm:"default:90"` // 30 * 3 = 90 (three months)
}
+type XpRole struct {
+ ID uint `gorm:"primarykey"`
+ XP uint
+ RoleID string
+ GuildConfigID uint
+}
+
+type BoostXpRole struct {
+ ID uint `gorm:"primarykey"`
+ Boost float64
+ RoleID string
+ GuildConfigID uint
+}
+
func GetGuildConfig(guildID string) *GuildConfig {
cfg := GuildConfig{GuildID: guildID}
if err := cfg.Load(); err != nil {
diff --git a/config/xp_role.go b/config/xp_role.go
index f857289..8ea9d1e 100644
--- a/config/xp_role.go
+++ b/config/xp_role.go
@@ -16,13 +16,6 @@ import (
"github.com/nyttikord/gokord/interaction"
)
-type XpRole struct {
- ID uint `gorm:"primarykey"`
- XP uint
- RoleID string
- GuildConfigID uint
-}
-
const (
ModifyXpRole = "xp_role"
XpRoleNew = "xp_role_add"
diff --git a/go.sum b/go.sum
index ad1282f..80c514d 100644
--- a/go.sum
+++ b/go.sum
@@ -17,10 +17,6 @@ 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.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/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=
@@ -55,18 +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.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/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=
diff --git a/user/xp.go b/user/xp.go
index dbca9de..6b0f6cc 100644
--- a/user/xp.go
+++ b/user/xp.go
@@ -2,6 +2,7 @@ package user
import (
"log/slog"
+ "math"
"slices"
"sync"
@@ -32,10 +33,16 @@ func (c *Copaing) AddXP(s bot.Session, m *user.Member, xp uint, fn func(uint, ui
return
}
pastLevel := exp.Level(old)
- 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})
+ s.Logger().Debug("adding xp", "member", m.DisplayName(), "old xp", old, "xp to add", xp, "old level", pastLevel)
+ c.CopaingXPs = append(c.CopaingXPs, CopaingXP{CopaingID: c.ID, XP: uint(math.Floor(float64(xp) * c.GetBoost(m))), GuildID: c.GuildID})
if err = c.Save(); err != nil {
- s.Logger().Error("saving user", "error", err, "user", m.DisplayName(), "xp", xp, "guild", c.GuildID)
+ s.Logger().Error(
+ "saving user",
+ "error", err.Error(),
+ "xp", c.CopaingXPs,
+ "discord_id", c.DiscordID,
+ "guild_id", c.GuildID,
+ )
return
}
newLevel := exp.Level(old + xp)
@@ -77,6 +84,23 @@ func (c *Copaing) GetXPForDays(logger *slog.Logger, n uint) (uint, error) {
return xp, nil
}
+func (c *Copaing) GetBoost(m *user.Member) float64 {
+ boost := 1.0
+ if m.PremiumSince != nil {
+ boost = max(boost, 2.0)
+ }
+ cfg := config.GetGuildConfig(c.GuildID)
+ for _, r := range cfg.BoostXpRoles {
+ if slices.Contains(m.Roles, r.RoleID) {
+ boost = max(boost, r.Boost)
+ }
+ }
+ if m.User.PrimaryGuild.GuildID == c.GuildID {
+ boost = max(boost, 1.5)
+ }
+ return boost
+}
+
// GetBestXP returns n Copaing with the best XP within d days (d <= cfg.DaysXPRemain; d < 0 <=> d = cfg.DaysXPRemain)
//
// This function is slow