aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go1
-rw-r--r--xp/events.go107
-rw-r--r--xp/member.go12
3 files changed, 112 insertions, 8 deletions
diff --git a/main.go b/main.go
index 09835d2..bbe995e 100644
--- a/main.go
+++ b/main.go
@@ -55,4 +55,5 @@ func main() {
func afterInit(dg *discordgo.Session) {
dg.AddHandler(xp.OnMessage)
+ dg.AddHandler(xp.OnVoiceUpdate)
}
diff --git a/xp/events.go b/xp/events.go
index c82c489..13b4a84 100644
--- a/xp/events.go
+++ b/xp/events.go
@@ -1,26 +1,33 @@
package xp
import (
+ "context"
+ "errors"
+ "fmt"
+ "github.com/anhgelus/gokord"
"github.com/anhgelus/gokord/utils"
"github.com/bwmarrin/discordgo"
+ "github.com/redis/go-redis/v9"
+ "strconv"
+ "time"
+)
+
+const (
+ ConnectedSince = "connected_since"
+ NotConnected = -1
+ MaxTimeInVocal = 60 * 60 * 6
)
func OnMessage(s *discordgo.Session, m *discordgo.MessageCreate) {
c := Copaing{DiscordID: m.Author.ID, GuildID: m.GuildID}
c.Load()
// add xp
- pastLevel := Level(c.XP)
trimmed := utils.TrimMessage(m.Content)
- c.XP += XPMessage(uint(len(trimmed)), calcDiversity(trimmed))
- c.Save()
- newLevel := Level(c.XP)
- // handle new level
- if pastLevel < newLevel {
+ c.AddXP(s, XPMessage(uint(len(trimmed)), calcDiversity(trimmed)), func(_ uint, _ uint) {
if err := s.MessageReactionAdd(m.ChannelID, m.Message.ID, "⬆"); err != nil {
utils.SendAlert("xp/events.go - reaction add new level", "cannot add the reaction: "+err.Error())
}
- onNewLevel(s, newLevel)
- }
+ })
}
func calcDiversity(msg string) uint {
@@ -38,3 +45,87 @@ func calcDiversity(msg string) uint {
}
return uint(len(chars))
}
+
+func OnVoiceUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) {
+ if e.Member.User.Bot {
+ return
+ }
+ redis, err := gokord.BaseCfg.Redis.Get()
+ if err != nil {
+ utils.SendAlert("events.go - Getting redis client", err.Error())
+ }
+ if e.BeforeUpdate == nil {
+ onConnection(s, e, redis)
+ } else {
+ onDisconnect(s, e, redis)
+ }
+ err = redis.Close()
+ if err != nil {
+ utils.SendAlert("events.go - Closing redis client", err.Error())
+ }
+}
+
+func onConnection(s *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis.Client) {
+ u := gokord.UserBase{DiscordID: e.UserID, GuildID: e.GuildID}
+ err := r.Set(
+ context.Background(),
+ fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince),
+ strconv.FormatInt(time.Now().Unix(), 10),
+ 0,
+ ).Err()
+ if err != nil {
+ utils.SendAlert("events.go - Setting connected_since", err.Error())
+ }
+}
+
+func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis.Client) {
+ u := gokord.UserBase{DiscordID: e.UserID, GuildID: e.GuildID}
+ key := fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince)
+ res := r.Get(context.Background(), key)
+ now := time.Now().Unix()
+ if errors.Is(res.Err(), redis.Nil) {
+ utils.SendWarn(fmt.Sprintf(
+ "User %s diconnect from a vocal but does not have a connected_since",
+ e.Member.DisplayName(),
+ ))
+ return
+ }
+ if res.Err() != nil {
+ utils.SendAlert("events.go - Getting connected_since", res.Err().Error())
+ err := r.Set(context.Background(), key, strconv.Itoa(NotConnected), 0).Err()
+ if err != nil {
+ utils.SendAlert("events.go - Set connected_since to not connected after get err", err.Error())
+ }
+ return
+ }
+ con, err := res.Int64()
+ if err != nil {
+ utils.SendAlert("events.go - Converting result to int64", err.Error())
+ return
+ }
+ if con == NotConnected {
+ utils.SendWarn(fmt.Sprintf(
+ "User %s diconnect from a vocal but was registered as not connected",
+ e.Member.DisplayName(),
+ ))
+ return
+ }
+ err = r.Set(context.Background(), key, strconv.Itoa(NotConnected), 0).Err()
+ if err != nil {
+ utils.SendAlert("events.go - Set connected_since to not connected", err.Error())
+ }
+ timeInVocal := now - con
+ if timeInVocal < 0 {
+ utils.SendAlert("events.go - Calculating time spent in vocal", "the time is negative")
+ return
+ }
+ if timeInVocal > MaxTimeInVocal {
+ utils.SendWarn(fmt.Sprintf("User %s spent more than 6 hours in vocal", e.Member.DisplayName()))
+ timeInVocal = MaxTimeInVocal
+ }
+ c := Copaing{DiscordID: u.DiscordID, GuildID: u.GuildID}
+ c.Load()
+ c.AddXP(s, XPVocal(uint(timeInVocal)), func(_ uint, _ uint) {
+ //TODO: handle new level in vocal
+ })
+}
diff --git a/xp/member.go b/xp/member.go
index 751bbd7..e3714fa 100644
--- a/xp/member.go
+++ b/xp/member.go
@@ -2,6 +2,7 @@ package xp
import (
"github.com/anhgelus/gokord"
+ "github.com/bwmarrin/discordgo"
"gorm.io/gorm"
)
@@ -20,3 +21,14 @@ func (c *Copaing) Load() *Copaing {
func (c *Copaing) Save() {
gokord.DB.Save(c)
}
+
+func (c *Copaing) AddXP(s *discordgo.Session, xp uint, fn func(uint, uint)) {
+ pastLevel := Level(c.XP)
+ c.XP += xp
+ c.Save()
+ newLevel := Level(c.XP)
+ if newLevel > pastLevel {
+ fn(c.XP, newLevel)
+ onNewLevel(s, newLevel)
+ }
+}