aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnhgelus Morhtuuzh <anhgelus@anhgelus.world>2025-03-10 21:53:59 +0100
committerAnhgelus Morhtuuzh <anhgelus@anhgelus.world>2025-03-10 21:53:59 +0100
commitd0253f36b4b4b98f936efeb973f588affb35c935 (patch)
tree44516e3a2059970be5a67cdf247ad54360f4bac0
parent48c9f5ae80b9ec765a9bf5f1096d7158bcfa74ef (diff)
feat(copaing): restore data if copaing rejoins after max 48 hours
-rw-r--r--main.go14
-rw-r--r--xp/member.go61
2 files changed, 68 insertions, 7 deletions
diff --git a/main.go b/main.go
index b019b7c..5bbc289 100644
--- a/main.go
+++ b/main.go
@@ -18,9 +18,11 @@ var (
updatesData []byte
Version = gokord.Version{
Major: 2,
- Minor: 3,
- Patch: 5,
- } // git version: 0.3.5 (it's the v2 of the bot)
+ Minor: 4,
+ Patch: 0,
+ } // git version: 0.4.0 (it's the v2 of the bot)
+
+ stopPeriodicReducer chan<- interface{}
)
func init() {
@@ -170,6 +172,10 @@ func main() {
}
bot.Start()
+ if stopPeriodicReducer != nil {
+ stopPeriodicReducer <- true
+ }
+
xp.CloseRedisClient()
}
@@ -185,7 +191,7 @@ func afterInit(dg *discordgo.Session) {
// reduce time for debug
d = time.Minute
}
- utils.NewTimer(d, func(stop chan<- interface{}) {
+ stopPeriodicReducer = utils.NewTimer(d, func(stop chan<- interface{}) {
xp.PeriodicReducer(dg)
})
}
diff --git a/xp/member.go b/xp/member.go
index c7afc47..ad9e6c5 100644
--- a/xp/member.go
+++ b/xp/member.go
@@ -21,7 +21,16 @@ type Copaing struct {
GuildID string `gorm:"not null"`
}
-var redisClient *redis.Client
+type leftCopaing struct {
+ ID uint
+ StopDelete chan<- interface{}
+}
+
+var (
+ redisClient *redis.Client
+
+ leftCopaingsMap = map[string]*leftCopaing{}
+)
const (
LastEvent = "last_event"
@@ -45,7 +54,50 @@ func GetCopaing(discordID string, guildID string) *Copaing {
}
func (c *Copaing) Load() error {
- return gokord.DB.Where("discord_id = ? and guild_id = ?", c.DiscordID, c.GuildID).FirstOrCreate(c).Error
+ // check if user left in the past 48 hours
+ k := c.GuildID + ":" + c.DiscordID
+ l, ok := leftCopaingsMap[k]
+ if !ok || l == nil {
+ // if not, common first or create
+ return gokord.DB.Where("discord_id = ? and guild_id = ?", c.DiscordID, c.GuildID).FirstOrCreate(c).Error
+ }
+ // else, getting last data
+ tmp := Copaing{
+ Model: gorm.Model{
+ ID: c.ID,
+ },
+ DiscordID: c.DiscordID,
+ GuildID: c.GuildID,
+ }
+ if err := gokord.DB.Unscoped().Find(&tmp).Error; err != nil {
+ // if error, avoid getting old data and use new one
+ utils.SendAlert(
+ "xp/member.go - Getting copaing in soft delete", err.Error(),
+ "discord_id", c.DiscordID,
+ "guild_id", c.DiscordID,
+ "last_id", l.ID,
+ )
+ return gokord.DB.Where("discord_id = ? and guild_id = ?", c.DiscordID, c.GuildID).FirstOrCreate(c).Error
+ }
+ // resetting internal data
+ tmp.Model = gorm.Model{}
+ l.StopDelete <- true
+ leftCopaingsMap[k] = nil
+ // creating new data
+ err := gokord.DB.Create(&tmp).Error
+ if err != nil {
+ return err
+ }
+ // delete old data
+ if err = gokord.DB.Unscoped().Delete(&tmp).Error; err != nil {
+ utils.SendAlert(
+ "xp/member.go - Deleting copaing in soft delete", err.Error(),
+ "discord_id", c.DiscordID,
+ "guild_id", c.DiscordID,
+ "last_id", l.ID,
+ )
+ }
+ return nil
}
func (c *Copaing) Save() error {
@@ -208,7 +260,8 @@ func (c *Copaing) AfterDelete(db *gorm.DB) error {
id := c.ID
dID := c.DiscordID
gID := c.GuildID
- utils.NewTimer(48*time.Hour, func(stop chan<- interface{}) {
+ k := c.GuildID + ":" + c.DiscordID
+ ch := utils.NewTimer(48*time.Hour, func(stop chan<- interface{}) {
if err := db.Unscoped().Where("id = ?", id).Delete(c).Error; err != nil {
utils.SendAlert(
"xp/member.go - Removing copaing from database", err.Error(),
@@ -217,7 +270,9 @@ func (c *Copaing) AfterDelete(db *gorm.DB) error {
)
}
stop <- true
+ leftCopaingsMap[k] = nil
})
+ leftCopaingsMap[k] = &leftCopaing{id, ch}
return nil
}