package models import ( "cmp" "slices" "time" "github.com/mergestat/timediff" ) type MapScoreList []MapScore type Capture struct { ID int64 `bun:",pk,autoincrement"` Host string `bun:",notnull"` Port string `bun:",notnull"` Name string `bun:",unique,notnull"` Active bool `bun:",notnull"` Start time.Time `bun:",notnull,default:current_timestamp"` MapScores MapScoreList `bun:"rel:has-many,join:id=capture_id"` } type MapScore struct { ID int64 `bun:",pk,autoincrement"` CaptureID int64 `bun:"capture_id"` StartTime time.Time `bun:",notnull"` Map string `bun:",notnull"` Counted bool `bun:",notnull"` ScoreList []Score `bun:"rel:has-many,join:id=mapscore_id"` } type Score struct { Name string `bun:",pk,notnull"` MapScoreID int64 `bun:"mapscore_id,pk,notnull"` Score int Ping int } type ResultTable struct { Header []ResultTableHeader Rows []ResultTableRow } type ResultTableHeader struct { Title string Subtitle string } type ResultTableRow struct { Name string Total int Individual []int } func (msl MapScoreList) BuildTable() *ResultTable { rt := &ResultTable{ Header: []ResultTableHeader{{Title: "Name"}, {Title: "Total"}}, } userMapRows := make(map[string]int) rt.Header = append(rt.Header, make([]ResultTableHeader, len(msl))...) filteredMapScores := []MapScore{} for _, ms := range msl { if ms.Counted { filteredMapScores = append(filteredMapScores, ms) } } for mapIndex, mapScore := range filteredMapScores { reversedIndex := len(filteredMapScores) - 1 - mapIndex rt.Header[reversedIndex+2] = ResultTableHeader{ Title: mapScore.Map, Subtitle: timediff.TimeDiff(mapScore.StartTime), } for _, score := range mapScore.ScoreList { if score.Ping > 0 { if _, ok := userMapRows[score.Name]; !ok { rt.Rows = append(rt.Rows, ResultTableRow{ Name: score.Name, Total: 0, Individual: make([]int, len(filteredMapScores)), }) userMapRows[score.Name] = len(rt.Rows) - 1 } row := userMapRows[score.Name] rt.Rows[row].Total = rt.Rows[row].Total + score.Score rt.Rows[row].Individual[reversedIndex] = score.Score } } } slices.SortFunc(rt.Rows, func(a, b ResultTableRow) int { return cmp.Compare(b.Total, a.Total) }) return rt }