Milen/level/recalculateEngine.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))
}