aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/.env.example1
-rw-r--r--backend/go.mod4
-rw-r--r--backend/go.sum9
-rw-r--r--backend/handlers/map.go10
-rw-r--r--backend/main.go11
-rw-r--r--backend/models/models.go1
-rw-r--r--frontend/src/components/Summary.tsx25
-rw-r--r--frontend/src/types/Map.ts3
-rw-r--r--rankings/fetch.go50
-rw-r--r--rankings/input/records.json2
-rw-r--r--rankings/main.go5
11 files changed, 86 insertions, 35 deletions
diff --git a/backend/.env.example b/backend/.env.example
index b0a7101..0318aa1 100644
--- a/backend/.env.example
+++ b/backend/.env.example
@@ -12,3 +12,4 @@ B2_KEY_ID=123456789ABCDEF
12B2_API_KEY=123456789ABCDEF 12B2_API_KEY=123456789ABCDEF
13B2_DOWNLOAD_URL=https://lphub.s3.eu-central-001.backblazeb2.com/ 13B2_DOWNLOAD_URL=https://lphub.s3.eu-central-001.backblazeb2.com/
14LOCAL_DEMOS_PATH=/path/to/demos/ 14LOCAL_DEMOS_PATH=/path/to/demos/
15NEWRELIC_LICENSE_KEY=abcdef123456789
diff --git a/backend/go.mod b/backend/go.mod
index e6f87c4..f9fe0db 100644
--- a/backend/go.mod
+++ b/backend/go.mod
@@ -32,9 +32,13 @@ require (
32 github.com/josharian/intern v1.0.0 // indirect 32 github.com/josharian/intern v1.0.0 // indirect
33 github.com/klauspost/cpuid/v2 v2.2.8 // indirect 33 github.com/klauspost/cpuid/v2 v2.2.8 // indirect
34 github.com/mailru/easyjson v0.7.7 // indirect 34 github.com/mailru/easyjson v0.7.7 // indirect
35 github.com/newrelic/go-agent/v3 v3.40.1 // indirect
36 github.com/newrelic/go-agent/v3/integrations/nrgin v1.4.1 // indirect
35 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 37 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
36 golang.org/x/arch v0.10.0 // indirect 38 golang.org/x/arch v0.10.0 // indirect
37 golang.org/x/tools v0.25.0 // indirect 39 golang.org/x/tools v0.25.0 // indirect
40 google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
41 google.golang.org/grpc v1.65.0 // indirect
38 gopkg.in/yaml.v3 v3.0.1 // indirect 42 gopkg.in/yaml.v3 v3.0.1 // indirect
39) 43)
40 44
diff --git a/backend/go.sum b/backend/go.sum
index 59301ae..f655023 100644
--- a/backend/go.sum
+++ b/backend/go.sum
@@ -74,6 +74,10 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
74github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 74github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
75github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 75github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
76github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 76github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
77github.com/newrelic/go-agent/v3 v3.40.1 h1:8nb4R252Fpuc3oySvlHpDwqySqaPWL5nf7ZVEhqtUeA=
78github.com/newrelic/go-agent/v3 v3.40.1/go.mod h1:X0TLXDo+ttefTIue1V96Y5seb8H6wqf6uUq4UpPsYj8=
79github.com/newrelic/go-agent/v3/integrations/nrgin v1.4.1 h1:a1waTQToxDTKd31LpwpaFHKWPj8Dav/BrzZayBiiAq8=
80github.com/newrelic/go-agent/v3/integrations/nrgin v1.4.1/go.mod h1:mEbfsZIxBYIPT7FzboYvE+ed2ft4SCFXoCvleI2v5JQ=
77github.com/pektezol/bitreader v1.4.3 h1:+WjsD6qOAaI6Q1jOOlEJcnaEso8vPMKRZnnaDnZhTSg= 81github.com/pektezol/bitreader v1.4.3 h1:+WjsD6qOAaI6Q1jOOlEJcnaEso8vPMKRZnnaDnZhTSg=
78github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk= 82github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk=
79github.com/pektezol/steam_go v1.1.2 h1:fta6SW+La8NfmCtR/Kn73bAmTBvCgUkkLCplsJGzx7g= 83github.com/pektezol/steam_go v1.1.2 h1:fta6SW+La8NfmCtR/Kn73bAmTBvCgUkkLCplsJGzx7g=
@@ -150,6 +154,11 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
150golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= 154golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
151golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= 155golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
152golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 156golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
157google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0=
158google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8=
159google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
160google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
161google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
153google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 162google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
154google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 163google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
155gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 164gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/backend/handlers/map.go b/backend/handlers/map.go
index b2a0b91..9cb0bcc 100644
--- a/backend/handlers/map.go
+++ b/backend/handlers/map.go
@@ -77,12 +77,12 @@ func FetchMapSummary(c *gin.Context) {
77 } 77 }
78 // Get map data 78 // Get map data
79 response.Map.ID = intID 79 response.Map.ID = intID
80 sql := `SELECT m.id, g.name, c.name, m.name, m.image, g.is_coop, m.is_disabled 80 sql := `SELECT m.id, g.name, c.name, m.name, m.image, g.is_coop, m.is_disabled, m.difficulty
81 FROM maps m 81 FROM maps m
82 INNER JOIN games g ON m.game_id = g.id 82 INNER JOIN games g ON m.game_id = g.id
83 INNER JOIN chapters c ON m.chapter_id = c.id 83 INNER JOIN chapters c ON m.chapter_id = c.id
84 WHERE m.id = $1` 84 WHERE m.id = $1`
85 err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName, &response.Map.Image, &response.Map.IsCoop, &response.Map.IsDisabled) 85 err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName, &response.Map.Image, &response.Map.IsCoop, &response.Map.IsDisabled, &response.Map.Difficulty)
86 if err != nil { 86 if err != nil {
87 c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) 87 c.JSON(http.StatusOK, models.ErrorResponse(err.Error()))
88 return 88 return
@@ -492,6 +492,7 @@ func FetchMaps(c *gin.Context) {
492 m.id, 492 m.id,
493 m.name, 493 m.name,
494 m.is_disabled, 494 m.is_disabled,
495 m.difficulty,
495 m.image, 496 m.image,
496 cat.id, 497 cat.id,
497 cat.name, 498 cat.name,
@@ -529,7 +530,7 @@ func FetchMaps(c *gin.Context) {
529 for rows.Next() { 530 for rows.Next() {
530 var mapShort models.MapSelect 531 var mapShort models.MapSelect
531 var categoryPortal models.CategoryPortal 532 var categoryPortal models.CategoryPortal
532 if err := rows.Scan(&mapShort.ID, &mapShort.Name, &mapShort.IsDisabled, &mapShort.Image, &categoryPortal.Category.ID, &categoryPortal.Category.Name, &categoryPortal.PortalCount); err != nil { 533 if err := rows.Scan(&mapShort.ID, &mapShort.Name, &mapShort.IsDisabled, &mapShort.Difficulty, &mapShort.Image, &categoryPortal.Category.ID, &categoryPortal.Category.Name, &categoryPortal.PortalCount); err != nil {
533 c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) 534 c.JSON(http.StatusOK, models.ErrorResponse(err.Error()))
534 return 535 return
535 } 536 }
@@ -571,6 +572,7 @@ func FetchChapterMaps(c *gin.Context) {
571 m.name AS map_name, 572 m.name AS map_name,
572 c.name AS chapter_name, 573 c.name AS chapter_name,
573 m.is_disabled, 574 m.is_disabled,
575 m.difficulty,
574 m.image, 576 m.image,
575 cat.id, 577 cat.id,
576 cat.name, 578 cat.name,
@@ -610,7 +612,7 @@ func FetchChapterMaps(c *gin.Context) {
610 for rows.Next() { 612 for rows.Next() {
611 var mapShort models.MapSelect 613 var mapShort models.MapSelect
612 var categoryPortal models.CategoryPortal 614 var categoryPortal models.CategoryPortal
613 if err := rows.Scan(&mapShort.ID, &mapShort.Name, &chapterName, &mapShort.IsDisabled, &mapShort.Image, &categoryPortal.Category.ID, &categoryPortal.Category.Name, &categoryPortal.PortalCount); err != nil { 615 if err := rows.Scan(&mapShort.ID, &mapShort.Name, &chapterName, &mapShort.IsDisabled, &mapShort.Difficulty, &mapShort.Image, &categoryPortal.Category.ID, &categoryPortal.Category.Name, &categoryPortal.PortalCount); err != nil {
614 c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) 616 c.JSON(http.StatusOK, models.ErrorResponse(err.Error()))
615 return 617 return
616 } 618 }
diff --git a/backend/main.go b/backend/main.go
index a1a4a20..e422359 100644
--- a/backend/main.go
+++ b/backend/main.go
@@ -11,6 +11,8 @@ import (
11 11
12 "github.com/gin-gonic/gin" 12 "github.com/gin-gonic/gin"
13 "github.com/joho/godotenv" 13 "github.com/joho/godotenv"
14 nrgin "github.com/newrelic/go-agent/v3/integrations/nrgin"
15 "github.com/newrelic/go-agent/v3/newrelic"
14) 16)
15 17
16// @title Least Portals Hub 18// @title Least Portals Hub
@@ -30,7 +32,16 @@ func main() {
30 if os.Getenv("ENV") == "PROD" { 32 if os.Getenv("ENV") == "PROD" {
31 gin.SetMode(gin.ReleaseMode) 33 gin.SetMode(gin.ReleaseMode)
32 } 34 }
35 app, err := newrelic.NewApplication(
36 newrelic.ConfigAppName("lphub"),
37 newrelic.ConfigLicense(os.Getenv("NEWRELIC_LICENSE_KEY")),
38 newrelic.ConfigAppLogForwardingEnabled(true),
39 )
40 if err != nil {
41 log.Fatal("Error instrumenting newrelic")
42 }
33 router := gin.Default() 43 router := gin.Default()
44 router.Use(nrgin.Middleware(app))
34 database.ConnectDB() 45 database.ConnectDB()
35 api.InitRoutes(router) 46 api.InitRoutes(router)
36 // for debugging 47 // for debugging
diff --git a/backend/models/models.go b/backend/models/models.go
index a114f2c..3c38131 100644
--- a/backend/models/models.go
+++ b/backend/models/models.go
@@ -47,6 +47,7 @@ type Map struct {
47 Image string `json:"image"` 47 Image string `json:"image"`
48 IsCoop bool `json:"is_coop"` 48 IsCoop bool `json:"is_coop"`
49 IsDisabled bool `json:"is_disabled"` 49 IsDisabled bool `json:"is_disabled"`
50 Difficulty int `json:"difficulty"`
50} 51}
51 52
52type MapShort struct { 53type MapShort struct {
diff --git a/frontend/src/components/Summary.tsx b/frontend/src/components/Summary.tsx
index 686652a..ba91f57 100644
--- a/frontend/src/components/Summary.tsx
+++ b/frontend/src/components/Summary.tsx
@@ -175,24 +175,23 @@ const Summary: React.FC<SummaryProps> = ({
175 <section id="section4" className="summary1"> 175 <section id="section4" className="summary1">
176 <div id="difficulty"> 176 <div id="difficulty">
177 <span className="">Difficulty</span> 177 <span className="">Difficulty</span>
178 {data.summary.routes[selectedRun].rating === 0 && <span className="text-foreground">N/A</span>} 178 {data.map.difficulty <= 2 && (
179 {data.summary.routes[selectedRun].rating === 1 && ( 179 <span style={{ color: "lime" }}>Very Easy</span>
180 <span style={{ color: "lime" }}>Very easy</span>
181 )} 180 )}
182 {data.summary.routes[selectedRun].rating === 2 && ( 181 {data.map.difficulty > 2 && data.map.difficulty <= 4 && (
183 <span style={{ color: "green" }}>Easy</span> 182 <span style={{ color: "green" }}>Easy</span>
184 )} 183 )}
185 {data.summary.routes[selectedRun].rating === 3 && ( 184 {data.map.difficulty > 4 && data.map.difficulty <= 6 && (
186 <span style={{ color: "yellow" }}>Medium</span> 185 <span style={{ color: "yellow" }}>Medium</span>
187 )} 186 )}
188 {data.summary.routes[selectedRun].rating === 4 && ( 187 {data.map.difficulty > 6 && data.map.difficulty <= 8 && (
189 <span style={{ color: "orange" }}>Hard</span> 188 <span style={{ color: "orange" }}>Hard</span>
190 )} 189 )}
191 {data.summary.routes[selectedRun].rating === 5 && ( 190 {data.map.difficulty > 8 && data.map.difficulty <= 10 && (
192 <span style={{ color: "red" }}>Very hard</span> 191 <span style={{ color: "red" }}>Very Hard</span>
193 )} 192 )}
194 <div> 193 <div>
195 {data.summary.routes[selectedRun].rating === 1 ? ( 194 {data.map.difficulty <= 2 && ? (
196 <div 195 <div
197 className="difficulty-rating" 196 className="difficulty-rating"
198 style={{ backgroundColor: "lime" }} 197 style={{ backgroundColor: "lime" }}
@@ -200,7 +199,7 @@ const Summary: React.FC<SummaryProps> = ({
200 ) : ( 199 ) : (
201 <div className="difficulty-rating"></div> 200 <div className="difficulty-rating"></div>
202 )} 201 )}
203 {data.summary.routes[selectedRun].rating === 2 ? ( 202 {data.map.difficulty > 2 && data.map.difficulty <= 4 && ? (
204 <div 203 <div
205 className="difficulty-rating" 204 className="difficulty-rating"
206 style={{ backgroundColor: "green" }} 205 style={{ backgroundColor: "green" }}
@@ -208,7 +207,7 @@ const Summary: React.FC<SummaryProps> = ({
208 ) : ( 207 ) : (
209 <div className="difficulty-rating"></div> 208 <div className="difficulty-rating"></div>
210 )} 209 )}
211 {data.summary.routes[selectedRun].rating === 3 ? ( 210 {data.map.difficulty > 4 && data.map.difficulty <= 6 && ? (
212 <div 211 <div
213 className="difficulty-rating" 212 className="difficulty-rating"
214 style={{ backgroundColor: "yellow" }} 213 style={{ backgroundColor: "yellow" }}
@@ -216,7 +215,7 @@ const Summary: React.FC<SummaryProps> = ({
216 ) : ( 215 ) : (
217 <div className="difficulty-rating"></div> 216 <div className="difficulty-rating"></div>
218 )} 217 )}
219 {data.summary.routes[selectedRun].rating === 4 ? ( 218 {data.map.difficulty > 6 && data.map.difficulty <= 8 && ? (
220 <div 219 <div
221 className="difficulty-rating" 220 className="difficulty-rating"
222 style={{ backgroundColor: "orange" }} 221 style={{ backgroundColor: "orange" }}
@@ -224,7 +223,7 @@ const Summary: React.FC<SummaryProps> = ({
224 ) : ( 223 ) : (
225 <div className="difficulty-rating"></div> 224 <div className="difficulty-rating"></div>
226 )} 225 )}
227 {data.summary.routes[selectedRun].rating === 5 ? ( 226 {data.map.difficulty > 8 && data.map.difficulty <= 10 && ? (
228 <div 227 <div
229 className="difficulty-rating" 228 className="difficulty-rating"
230 style={{ backgroundColor: "red" }} 229 style={{ backgroundColor: "red" }}
diff --git a/frontend/src/types/Map.ts b/frontend/src/types/Map.ts
index 6a42c2a..a5c9404 100644
--- a/frontend/src/types/Map.ts
+++ b/frontend/src/types/Map.ts
@@ -80,7 +80,8 @@ interface MapSummaryMap {
80 map_name: string; 80 map_name: string;
81 is_coop: boolean; 81 is_coop: boolean;
82 is_disabled: boolean; 82 is_disabled: boolean;
83} 83 difficulty: number;
84};
84 85
85interface MapSummaryDetails { 86interface MapSummaryDetails {
86 routes: MapSummaryDetailsRoute[]; 87 routes: MapSummaryDetailsRoute[];
diff --git a/rankings/fetch.go b/rankings/fetch.go
index 7e63427..7e9a449 100644
--- a/rankings/fetch.go
+++ b/rankings/fetch.go
@@ -3,6 +3,7 @@ package main
3import ( 3import (
4 "encoding/json" 4 "encoding/json"
5 "encoding/xml" 5 "encoding/xml"
6 "errors"
6 "fmt" 7 "fmt"
7 "io" 8 "io"
8 "log" 9 "log"
@@ -12,7 +13,12 @@ import (
12 "strings" 13 "strings"
13) 14)
14 15
15func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, useCache bool) map[SteamID]*Player { 16var (
17 errLb error = errors.New("leaderboards error")
18 errPi error = errors.New("playerinfo error")
19)
20
21func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, useCache bool) (map[SteamID]*Player, error) {
16 log.Println("fetching leaderboard") 22 log.Println("fetching leaderboard")
17 players := map[SteamID]*Player{} 23 players := map[SteamID]*Player{}
18 // first init players map with records from portal gun and doors 24 // first init players map with records from portal gun and doors
@@ -21,7 +27,10 @@ func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, us
21 end := 5000 27 end := 5000
22 28
23 for fetchAnotherPage { 29 for fetchAnotherPage {
24 portalGunEntries := fetchRecordsFromMap(47459, 0, 5000, useCache) 30 portalGunEntries, err := fetchRecordsFromMap(47459, 0, 5000, useCache)
31 if err != nil {
32 return nil, err
33 }
25 fetchAnotherPage = portalGunEntries.needsAnotherPage(&records[0]) 34 fetchAnotherPage = portalGunEntries.needsAnotherPage(&records[0])
26 if fetchAnotherPage { 35 if fetchAnotherPage {
27 start = end + 1 36 start = end + 1
@@ -50,7 +59,10 @@ func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, us
50 end = 5000 59 end = 5000
51 60
52 for fetchAnotherPage { 61 for fetchAnotherPage {
53 doorsEntries := fetchRecordsFromMap(47740, start, end, useCache) 62 doorsEntries, err := fetchRecordsFromMap(47740, start, end, useCache)
63 if err != nil {
64 return nil, err
65 }
54 fetchAnotherPage = doorsEntries.needsAnotherPage(&records[51]) 66 fetchAnotherPage = doorsEntries.needsAnotherPage(&records[51])
55 if fetchAnotherPage { 67 if fetchAnotherPage {
56 start = end + 1 68 start = end + 1
@@ -94,7 +106,10 @@ func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, us
94 end := 5000 106 end := 5000
95 107
96 for fetchAnotherPage { 108 for fetchAnotherPage {
97 entries := fetchRecordsFromMap(record.MapID, start, end, useCache) 109 entries, err := fetchRecordsFromMap(record.MapID, start, end, useCache)
110 if err != nil {
111 return nil, err
112 }
98 fetchAnotherPage = entries.needsAnotherPage(&record) 113 fetchAnotherPage = entries.needsAnotherPage(&record)
99 if fetchAnotherPage { 114 if fetchAnotherPage {
100 start = end + 1 115 start = end + 1
@@ -137,10 +152,10 @@ func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, us
137 } 152 }
138 153
139 } 154 }
140 return players 155 return players, nil
141} 156}
142 157
143func fetchRecordsFromMap(mapID int, start int, end int, useCache bool) *Leaderboard { 158func fetchRecordsFromMap(mapID int, start int, end int, useCache bool) (*Leaderboard, error) {
144 var filename string 159 var filename string
145 if useCache { 160 if useCache {
146 filename := fmt.Sprintf("./cache/lb_%d_%d_%d.xml", mapID, start, end) 161 filename := fmt.Sprintf("./cache/lb_%d_%d_%d.xml", mapID, start, end)
@@ -152,25 +167,27 @@ func fetchRecordsFromMap(mapID int, start int, end int, useCache bool) *Leaderbo
152 if err != nil { 167 if err != nil {
153 log.Fatalln("failed to unmarshal cache.", err.Error()) 168 log.Fatalln("failed to unmarshal cache.", err.Error())
154 } 169 }
155 return &leaderboard 170 return &leaderboard, nil
156 } 171 }
157 } 172 }
158 173
159 url := fmt.Sprintf("https://steamcommunity.com/stats/Portal2/leaderboards/%d?xml=1&start=%d&end=%d", mapID, start, end) 174 url := fmt.Sprintf("https://steamcommunity.com/stats/Portal2/leaderboards/%d?xml=1&start=%d&end=%d", mapID, start, end)
160 resp, err := http.Get(url) 175 resp, err := http.Get(url)
161 log.Println("fetched", url, ":", resp.StatusCode)
162 if err != nil { 176 if err != nil {
163 log.Fatalln("failed to fetch leaderboard.", err.Error()) 177 log.Println("failed to fetch leaderboard.", err.Error())
178 return nil, errLb
164 } 179 }
165 respBytes, err := io.ReadAll(resp.Body) 180 respBytes, err := io.ReadAll(resp.Body)
166 if err != nil { 181 if err != nil {
167 log.Fatalln("failed to read leadeboard body.", err.Error()) 182 log.Println("failed to read leadeboard body.", err.Error())
183 return nil, errLb
168 } 184 }
169 leaderboard := Leaderboard{} 185 leaderboard := Leaderboard{}
170 err = xml.Unmarshal(respBytes, &leaderboard) 186 err = xml.Unmarshal(respBytes, &leaderboard)
171 if err != nil { 187 if err != nil {
172 log.Println(string(respBytes)) 188 log.Println(string(respBytes))
173 log.Fatalln("failed to unmarshal leaderboard.", err.Error()) 189 log.Println("failed to unmarshal leaderboard.", err.Error())
190 return nil, errLb
174 } 191 }
175 192
176 if useCache { 193 if useCache {
@@ -179,10 +196,10 @@ func fetchRecordsFromMap(mapID int, start int, end int, useCache bool) *Leaderbo
179 } 196 }
180 } 197 }
181 198
182 return &leaderboard 199 return &leaderboard, nil
183} 200}
184 201
185func fetchPlayerInfo(players []*Player) { 202func fetchPlayerInfo(players []*Player) error {
186 log.Println("fetching info for", len(players), "players") 203 log.Println("fetching info for", len(players), "players")
187 204
188 ids := make([]string, len(players)) 205 ids := make([]string, len(players))
@@ -193,11 +210,13 @@ func fetchPlayerInfo(players []*Player) {
193 url := fmt.Sprintf("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=%s&steamids=%s", os.Getenv("API_KEY"), strings.Join(ids, ",")) 210 url := fmt.Sprintf("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=%s&steamids=%s", os.Getenv("API_KEY"), strings.Join(ids, ","))
194 resp, err := http.Get(url) 211 resp, err := http.Get(url)
195 if err != nil { 212 if err != nil {
196 log.Fatalln(err.Error()) 213 log.Println(err.Error())
214 return errPi
197 } 215 }
198 body, err := io.ReadAll(resp.Body) 216 body, err := io.ReadAll(resp.Body)
199 if err != nil { 217 if err != nil {
200 log.Fatalln(err.Error()) 218 log.Println(err.Error())
219 return errPi
201 } 220 }
202 type PlayerSummary struct { 221 type PlayerSummary struct {
203 SteamID SteamID `json:"steamid"` 222 SteamID SteamID `json:"steamid"`
@@ -223,4 +242,5 @@ func fetchPlayerInfo(players []*Player) {
223 } 242 }
224 } 243 }
225 } 244 }
245 return nil
226} 246}
diff --git a/rankings/input/records.json b/rankings/input/records.json
index d960004..2b1fb21 100644
--- a/rankings/input/records.json
+++ b/rankings/input/records.json
@@ -377,7 +377,7 @@
377 "id": 47839, 377 "id": 47839,
378 "name": "Catapults", 378 "name": "Catapults",
379 "mode": 2, 379 "mode": 2,
380 "wr": 4 380 "wr": 3
381 }, 381 },
382 { 382 {
383 "id": 47842, 383 "id": 47842,
diff --git a/rankings/main.go b/rankings/main.go
index 552f058..928d3be 100644
--- a/rankings/main.go
+++ b/rankings/main.go
@@ -58,7 +58,10 @@ func run() {
58 overrides := readOverrides() 58 overrides := readOverrides()
59 log.Println("loaded", len(overrides), "player overrides") 59 log.Println("loaded", len(overrides), "player overrides")
60 60
61 players := fetchLeaderboard(records, overrides, useCache) 61 players, err := fetchLeaderboard(records, overrides, useCache)
62 if err != nil {
63 return
64 }
62 65
63 spRankings := []*Player{} 66 spRankings := []*Player{}
64 mpRankings := []*Player{} 67 mpRankings := []*Player{}