120 lines
2.8 KiB
Go
120 lines
2.8 KiB
Go
package level
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
|
|
"gitea.teamortix.com/chanbakjsd/Milen/db"
|
|
"gitea.teamortix.com/chanbakjsd/Milen/persistent"
|
|
"gitea.teamortix.com/chanbakjsd/Milen/util"
|
|
)
|
|
|
|
func RecalculateEverything(dg *discordgo.Session, guildID string) {
|
|
ShouldListen = false
|
|
defer func() {
|
|
ShouldListen = true
|
|
}()
|
|
|
|
startTime := time.Now()
|
|
guild, err := dg.Guild(guildID)
|
|
if err != nil {
|
|
util.ReportError(dg, err)
|
|
return
|
|
}
|
|
listOfMessages := make(map[string][]*discordgo.Message)
|
|
latestMessage := make(map[string]string)
|
|
for {
|
|
newMessagesFound := false
|
|
for _, v := range guild.Channels {
|
|
if persistent.IgnoredChannels[v.ID] {
|
|
continue
|
|
}
|
|
beforeID := ""
|
|
for {
|
|
messages, err := dg.ChannelMessages(v.ID, 100, beforeID, "", "")
|
|
if err != nil {
|
|
util.ReportError(dg, err)
|
|
return
|
|
}
|
|
dupe := false
|
|
for _, msg := range messages {
|
|
if msg.ID == latestMessage[v.ID] {
|
|
dupe = true
|
|
break
|
|
}
|
|
if list, ok := listOfMessages[msg.Author.ID]; ok {
|
|
listOfMessages[msg.Author.ID] = append(list, msg)
|
|
} else {
|
|
listOfMessages[msg.Author.ID] = []*discordgo.Message{msg}
|
|
}
|
|
}
|
|
if beforeID == "" && len(messages) > 0 && messages[0].ID != latestMessage[v.ID] {
|
|
newMessagesFound = true
|
|
latestMessage[v.ID] = messages[0].ID
|
|
}
|
|
if len(messages) < 100 || dupe {
|
|
break
|
|
}
|
|
beforeID = messages[99].ID
|
|
}
|
|
}
|
|
fmt.Printf("[RECALC] Batch step reached in %v.\n", time.Now().Sub(startTime))
|
|
if !newMessagesFound {
|
|
break
|
|
}
|
|
}
|
|
fetchedTime := time.Now()
|
|
totalXP := make(map[string]int64)
|
|
for k, v := range listOfMessages {
|
|
sort.Slice(v, func(i, j int) bool {
|
|
return v[i].ID < v[j].ID
|
|
})
|
|
prevTime, err := discordgo.SnowflakeTimestamp(v[0].ID)
|
|
if err != nil {
|
|
util.ReportError(dg, err)
|
|
return
|
|
}
|
|
for i := 1; i < len(v); i++ {
|
|
nextTime, err := discordgo.SnowflakeTimestamp(v[i].ID)
|
|
if err != nil {
|
|
util.ReportError(dg, err)
|
|
return
|
|
}
|
|
xp := int64(nextTime.Sub(prevTime).Seconds())
|
|
if xp > int64(len(v[i].Content)-3)/3 {
|
|
xp = int64(len(v[i].Content)-3) / 3
|
|
}
|
|
if xp > 10 {
|
|
xp = 10
|
|
}
|
|
if xp >= 0 {
|
|
totalXP[k] += xp
|
|
}
|
|
prevTime = nextTime
|
|
}
|
|
}
|
|
|
|
processTime := time.Now()
|
|
db.DeleteAllLevel()
|
|
for k, v := range totalXP {
|
|
userHistory := listOfMessages[k]
|
|
newestMessage := userHistory[len(userHistory)-1]
|
|
time, err := discordgo.SnowflakeTimestamp(newestMessage.ID)
|
|
if err != nil {
|
|
util.ReportError(dg, err)
|
|
return
|
|
}
|
|
db.SetXP(k, time, v)
|
|
}
|
|
|
|
finishTime := time.Now()
|
|
|
|
fmt.Printf("[RECALC] Fetch took %v.\n", fetchedTime.Sub(startTime))
|
|
fmt.Printf("[RECALC] XP calculation took %v.\n", processTime.Sub(fetchedTime))
|
|
fmt.Printf("[RECALC] DB write took %v.\n", finishTime.Sub(processTime))
|
|
fmt.Printf("[RECALC] Total took %v.\n", finishTime.Sub(startTime))
|
|
}
|