From df6f6cb5ff8957be8f01d58d60857da2c094a3d9 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 12 Sep 2024 00:25:15 +0300 Subject: refactor: unofficial rankings implementation --- rankings/fetch.go | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 rankings/fetch.go (limited to 'rankings/fetch.go') diff --git a/rankings/fetch.go b/rankings/fetch.go new file mode 100644 index 0000000..ee5d5bb --- /dev/null +++ b/rankings/fetch.go @@ -0,0 +1,185 @@ +package main + +import ( + "encoding/json" + "encoding/xml" + "fmt" + "io" + "log" + "net/http" + "os" + "strconv" +) + +func fetchLeaderboard(records *[]Record, overrides *map[string]map[string]int) *map[string]*Player { + log.Println("fetching leaderboard") + players := map[string]*Player{} + // first init players map with records from portal gun and doors + fetchAnotherPage := true + start := 0 + end := 5000 + + for fetchAnotherPage { + portalGunEntries := fetchRecordsFromMap(47459, 0, 5000) + fetchAnotherPage = portalGunEntries.needsAnotherPage(&(*records)[0]) + if fetchAnotherPage { + start = end + 1 + end = start + 5000 + } + for _, entry := range portalGunEntries.Entries.Entry { + if entry.Score < 0 { + continue // ban + } + players[entry.SteamID] = &Player{ + SteamID: entry.SteamID, + Entries: []PlayerEntry{ + { + MapID: 47459, + MapScore: entry.Score, + }, + }, + SpScoreCount: entry.Score, + SpIterations: 1, + } + } + } + + fetchAnotherPage = true + start = 0 + end = 5000 + + for fetchAnotherPage { + doorsEntries := fetchRecordsFromMap(47740, start, end) + fetchAnotherPage = doorsEntries.needsAnotherPage(&(*records)[51]) + if fetchAnotherPage { + start = end + 1 + end = start + 5000 + } + for _, entry := range doorsEntries.Entries.Entry { + if entry.Score < 0 { + continue // ban + } + player, ok := players[entry.SteamID] + if !ok { + players[entry.SteamID] = &Player{ + SteamID: entry.SteamID, + Entries: []PlayerEntry{ + { + MapID: 47740, + MapScore: entry.Score, + }, + }, + MpScoreCount: entry.Score, + MpIterations: 1, + } + } else { + player.Entries = append(player.Entries, PlayerEntry{ + MapID: 47740, + MapScore: entry.Score, + }) + player.MpScoreCount = entry.Score + player.MpIterations++ + } + } + } + + for _, record := range *records { + if record.MapID == 47459 || record.MapID == 47740 { + continue + } + + fetchAnotherPage := true + start := 0 + end := 5000 + + for fetchAnotherPage { + entries := fetchRecordsFromMap(record.MapID, start, end) + fetchAnotherPage = entries.needsAnotherPage(&record) + if fetchAnotherPage { + start = end + 1 + end = start + 5000 + } + for _, entry := range (*entries).Entries.Entry { + player, ok := players[entry.SteamID] + if !ok { + continue + } + score := entry.Score + if entry.Score < record.MapWR { + _, ok := (*overrides)[entry.SteamID] + if ok { + _, ok := (*overrides)[entry.SteamID][strconv.Itoa(record.MapID)] + if ok { + score = (*overrides)[entry.SteamID][strconv.Itoa(record.MapID)] + } else { + continue // ban + } + } else { + continue // ban + } + } + if record.MapLimit != nil && score > *record.MapLimit { + continue // ignore above limit + } + player.Entries = append(player.Entries, PlayerEntry{ + MapID: record.MapID, + MapScore: score, + }) + if record.MapMode == 1 { + player.SpScoreCount += score + player.SpIterations++ + } else if record.MapMode == 2 { + player.MpScoreCount += score + player.MpIterations++ + } + } + } + + } + return &players +} + +func fetchRecordsFromMap(mapID int, start int, end int) *Leaderboard { + resp, err := http.Get(fmt.Sprintf("https://steamcommunity.com/stats/Portal2/leaderboards/%d?xml=1&start=%d&end=%d", mapID, start, end)) + if err != nil { + log.Fatalln(err.Error()) + } + respBytes, err := io.ReadAll(resp.Body) + if err != nil { + log.Fatalln(err.Error()) + } + leaderboard := Leaderboard{} + err = xml.Unmarshal(respBytes, &leaderboard) + if err != nil { + log.Fatalln(err.Error()) + } + return &leaderboard +} + +func fetchPlayerInfo(player *Player) { + url := fmt.Sprintf("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=%s&steamids=%s", os.Getenv("API_KEY"), player.SteamID) + resp, err := http.Get(url) + if err != nil { + log.Fatalln(err.Error()) + } + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Fatalln(err.Error()) + } + type PlayerSummary struct { + PersonaName string `json:"personaname"` + AvatarFull string `json:"avatarfull"` + } + + type Result struct { + Response struct { + Players []PlayerSummary `json:"players"` + } `json:"response"` + } + var data Result + if err := json.Unmarshal(body, &data); err != nil { + log.Fatalln(err.Error()) + } + player.AvatarLink = data.Response.Players[0].AvatarFull + player.Username = data.Response.Players[0].PersonaName +} -- cgit v1.2.3