diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2025-08-15 18:10:19 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2025-08-15 18:10:19 +0300 |
| commit | f1798f570d645c5148908461064e402baadd2ed1 (patch) | |
| tree | 9990b4c94a406d712b50f10e9d53dab63696f9f1 | |
| parent | chore: frontend package stuff (diff) | |
| parent | feat/backend: add newrelic integration (#274) (diff) | |
| download | lphub-f1798f570d645c5148908461064e402baadd2ed1.tar.gz lphub-f1798f570d645c5148908461064e402baadd2ed1.tar.bz2 lphub-f1798f570d645c5148908461064e402baadd2ed1.zip | |
feat/frontend: update tailwind to main branch
| -rw-r--r-- | backend/.env.example | 1 | ||||
| -rw-r--r-- | backend/go.mod | 4 | ||||
| -rw-r--r-- | backend/go.sum | 9 | ||||
| -rw-r--r-- | backend/handlers/map.go | 10 | ||||
| -rw-r--r-- | backend/main.go | 11 | ||||
| -rw-r--r-- | backend/models/models.go | 1 | ||||
| -rw-r--r-- | frontend/src/components/Summary.tsx | 25 | ||||
| -rw-r--r-- | frontend/src/types/Map.ts | 3 | ||||
| -rw-r--r-- | rankings/fetch.go | 50 | ||||
| -rw-r--r-- | rankings/input/records.json | 2 | ||||
| -rw-r--r-- | rankings/main.go | 5 |
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 | |||
| 12 | B2_API_KEY=123456789ABCDEF | 12 | B2_API_KEY=123456789ABCDEF |
| 13 | B2_DOWNLOAD_URL=https://lphub.s3.eu-central-001.backblazeb2.com/ | 13 | B2_DOWNLOAD_URL=https://lphub.s3.eu-central-001.backblazeb2.com/ |
| 14 | LOCAL_DEMOS_PATH=/path/to/demos/ | 14 | LOCAL_DEMOS_PATH=/path/to/demos/ |
| 15 | NEWRELIC_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 | |||
| 74 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | 74 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= |
| 75 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | 75 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= |
| 76 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | 76 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= |
| 77 | github.com/newrelic/go-agent/v3 v3.40.1 h1:8nb4R252Fpuc3oySvlHpDwqySqaPWL5nf7ZVEhqtUeA= | ||
| 78 | github.com/newrelic/go-agent/v3 v3.40.1/go.mod h1:X0TLXDo+ttefTIue1V96Y5seb8H6wqf6uUq4UpPsYj8= | ||
| 79 | github.com/newrelic/go-agent/v3/integrations/nrgin v1.4.1 h1:a1waTQToxDTKd31LpwpaFHKWPj8Dav/BrzZayBiiAq8= | ||
| 80 | github.com/newrelic/go-agent/v3/integrations/nrgin v1.4.1/go.mod h1:mEbfsZIxBYIPT7FzboYvE+ed2ft4SCFXoCvleI2v5JQ= | ||
| 77 | github.com/pektezol/bitreader v1.4.3 h1:+WjsD6qOAaI6Q1jOOlEJcnaEso8vPMKRZnnaDnZhTSg= | 81 | github.com/pektezol/bitreader v1.4.3 h1:+WjsD6qOAaI6Q1jOOlEJcnaEso8vPMKRZnnaDnZhTSg= |
| 78 | github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk= | 82 | github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk= |
| 79 | github.com/pektezol/steam_go v1.1.2 h1:fta6SW+La8NfmCtR/Kn73bAmTBvCgUkkLCplsJGzx7g= | 83 | github.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 | |||
| 150 | golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= | 154 | golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= |
| 151 | golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= | 155 | golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= |
| 152 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | 156 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
| 157 | google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= | ||
| 158 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= | ||
| 159 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= | ||
| 160 | google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= | ||
| 161 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= | ||
| 153 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= | 162 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= |
| 154 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= | 163 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= |
| 155 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | 164 | gopkg.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 | ||
| 52 | type MapShort struct { | 53 | type 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 | ||
| 85 | interface MapSummaryDetails { | 86 | interface 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 | |||
| 3 | import ( | 3 | import ( |
| 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 | ||
| 15 | func fetchLeaderboard(records []Record, overrides map[SteamID]map[string]int, useCache bool) map[SteamID]*Player { | 16 | var ( |
| 17 | errLb error = errors.New("leaderboards error") | ||
| 18 | errPi error = errors.New("playerinfo error") | ||
| 19 | ) | ||
| 20 | |||
| 21 | func 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 | ||
| 143 | func fetchRecordsFromMap(mapID int, start int, end int, useCache bool) *Leaderboard { | 158 | func 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 | ||
| 185 | func fetchPlayerInfo(players []*Player) { | 202 | func 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{} |