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)) }