diff options
| -rw-r--r-- | backend/api/routes.go | 6 | ||||
| -rw-r--r-- | backend/docs/docs.go | 148 | ||||
| -rw-r--r-- | backend/docs/swagger.json | 148 | ||||
| -rw-r--r-- | backend/docs/swagger.yaml | 87 | ||||
| -rw-r--r-- | backend/go.mod | 41 | ||||
| -rw-r--r-- | backend/go.sum | 90 | ||||
| -rw-r--r-- | backend/handlers/logs.go | 103 | ||||
| -rw-r--r-- | backend/handlers/record.go | 10 | ||||
| -rw-r--r-- | backend/handlers/stats.go | 204 | ||||
| -rw-r--r-- | backend/main.go | 36 |
10 files changed, 561 insertions, 312 deletions
diff --git a/backend/api/routes.go b/backend/api/routes.go index 690f844..ab6e704 100644 --- a/backend/api/routes.go +++ b/backend/api/routes.go | |||
| @@ -54,8 +54,8 @@ func InitRoutes(router *gin.Engine) { | |||
| 54 | v1.GET("/games/:gameid", RateLimit, handlers.FetchChapters) | 54 | v1.GET("/games/:gameid", RateLimit, handlers.FetchChapters) |
| 55 | v1.GET("/chapters/:chapterid", RateLimit, handlers.FetchChapterMaps) | 55 | v1.GET("/chapters/:chapterid", RateLimit, handlers.FetchChapterMaps) |
| 56 | v1.GET("/games/:gameid/maps", RateLimit, handlers.FetchMaps) | 56 | v1.GET("/games/:gameid/maps", RateLimit, handlers.FetchMaps) |
| 57 | // Logs | 57 | // Stats |
| 58 | v1.GET("/logs/score", RateLimit, handlers.ScoreLogs) | 58 | v1.GET("/stats/timeline", RateLimit, handlers.Timeline) |
| 59 | // v1.GET("/logs/mod", IsAuthenticated, handlers.ModLogs) | 59 | v1.GET("/stats/scores", RateLimit, handlers.Scores) |
| 60 | } | 60 | } |
| 61 | } | 61 | } |
diff --git a/backend/docs/docs.go b/backend/docs/docs.go index 44d53e1..7ce9a8b 100644 --- a/backend/docs/docs.go +++ b/backend/docs/docs.go | |||
| @@ -250,37 +250,6 @@ const docTemplate = `{ | |||
| 250 | } | 250 | } |
| 251 | } | 251 | } |
| 252 | }, | 252 | }, |
| 253 | "/logs/score": { | ||
| 254 | "get": { | ||
| 255 | "description": "Get score logs of every player.", | ||
| 256 | "produces": [ | ||
| 257 | "application/json" | ||
| 258 | ], | ||
| 259 | "tags": [ | ||
| 260 | "logs" | ||
| 261 | ], | ||
| 262 | "responses": { | ||
| 263 | "200": { | ||
| 264 | "description": "OK", | ||
| 265 | "schema": { | ||
| 266 | "allOf": [ | ||
| 267 | { | ||
| 268 | "$ref": "#/definitions/models.Response" | ||
| 269 | }, | ||
| 270 | { | ||
| 271 | "type": "object", | ||
| 272 | "properties": { | ||
| 273 | "data": { | ||
| 274 | "$ref": "#/definitions/handlers.ScoreLogsResponse" | ||
| 275 | } | ||
| 276 | } | ||
| 277 | } | ||
| 278 | ] | ||
| 279 | } | ||
| 280 | } | ||
| 281 | } | ||
| 282 | } | ||
| 283 | }, | ||
| 284 | "/maps/{mapid}/discussions": { | 253 | "/maps/{mapid}/discussions": { |
| 285 | "get": { | 254 | "get": { |
| 286 | "description": "Get map discussions with specified map id.", | 255 | "description": "Get map discussions with specified map id.", |
| @@ -1220,6 +1189,68 @@ const docTemplate = `{ | |||
| 1220 | } | 1189 | } |
| 1221 | } | 1190 | } |
| 1222 | }, | 1191 | }, |
| 1192 | "/stats/scores": { | ||
| 1193 | "get": { | ||
| 1194 | "description": "Get score logs of every player.", | ||
| 1195 | "produces": [ | ||
| 1196 | "application/json" | ||
| 1197 | ], | ||
| 1198 | "tags": [ | ||
| 1199 | "stats" | ||
| 1200 | ], | ||
| 1201 | "responses": { | ||
| 1202 | "200": { | ||
| 1203 | "description": "OK", | ||
| 1204 | "schema": { | ||
| 1205 | "allOf": [ | ||
| 1206 | { | ||
| 1207 | "$ref": "#/definitions/models.Response" | ||
| 1208 | }, | ||
| 1209 | { | ||
| 1210 | "type": "object", | ||
| 1211 | "properties": { | ||
| 1212 | "data": { | ||
| 1213 | "$ref": "#/definitions/handlers.ScoresResponse" | ||
| 1214 | } | ||
| 1215 | } | ||
| 1216 | } | ||
| 1217 | ] | ||
| 1218 | } | ||
| 1219 | } | ||
| 1220 | } | ||
| 1221 | } | ||
| 1222 | }, | ||
| 1223 | "/stats/timeline": { | ||
| 1224 | "get": { | ||
| 1225 | "description": "Get the history of portal count world records over time.", | ||
| 1226 | "produces": [ | ||
| 1227 | "application/json" | ||
| 1228 | ], | ||
| 1229 | "tags": [ | ||
| 1230 | "stats" | ||
| 1231 | ], | ||
| 1232 | "responses": { | ||
| 1233 | "200": { | ||
| 1234 | "description": "OK", | ||
| 1235 | "schema": { | ||
| 1236 | "allOf": [ | ||
| 1237 | { | ||
| 1238 | "$ref": "#/definitions/models.Response" | ||
| 1239 | }, | ||
| 1240 | { | ||
| 1241 | "type": "object", | ||
| 1242 | "properties": { | ||
| 1243 | "data": { | ||
| 1244 | "$ref": "#/definitions/handlers.TimelineResponse" | ||
| 1245 | } | ||
| 1246 | } | ||
| 1247 | } | ||
| 1248 | ] | ||
| 1249 | } | ||
| 1250 | } | ||
| 1251 | } | ||
| 1252 | } | ||
| 1253 | }, | ||
| 1223 | "/token": { | 1254 | "/token": { |
| 1224 | "get": { | 1255 | "get": { |
| 1225 | "description": "Gets the token cookie value from the user.", | 1256 | "description": "Gets the token cookie value from the user.", |
| @@ -1774,18 +1805,7 @@ const docTemplate = `{ | |||
| 1774 | } | 1805 | } |
| 1775 | } | 1806 | } |
| 1776 | }, | 1807 | }, |
| 1777 | "handlers.ScoreLogsResponse": { | 1808 | "handlers.ScoresDetails": { |
| 1778 | "type": "object", | ||
| 1779 | "properties": { | ||
| 1780 | "scores": { | ||
| 1781 | "type": "array", | ||
| 1782 | "items": { | ||
| 1783 | "$ref": "#/definitions/handlers.ScoreLogsResponseDetails" | ||
| 1784 | } | ||
| 1785 | } | ||
| 1786 | } | ||
| 1787 | }, | ||
| 1788 | "handlers.ScoreLogsResponseDetails": { | ||
| 1789 | "type": "object", | 1809 | "type": "object", |
| 1790 | "properties": { | 1810 | "properties": { |
| 1791 | "date": { | 1811 | "date": { |
| @@ -1811,6 +1831,17 @@ const docTemplate = `{ | |||
| 1811 | } | 1831 | } |
| 1812 | } | 1832 | } |
| 1813 | }, | 1833 | }, |
| 1834 | "handlers.ScoresResponse": { | ||
| 1835 | "type": "object", | ||
| 1836 | "properties": { | ||
| 1837 | "scores": { | ||
| 1838 | "type": "array", | ||
| 1839 | "items": { | ||
| 1840 | "$ref": "#/definitions/handlers.ScoresDetails" | ||
| 1841 | } | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | }, | ||
| 1814 | "handlers.SearchResponse": { | 1845 | "handlers.SearchResponse": { |
| 1815 | "type": "object", | 1846 | "type": "object", |
| 1816 | "properties": { | 1847 | "properties": { |
| @@ -1860,6 +1891,34 @@ const docTemplate = `{ | |||
| 1860 | } | 1891 | } |
| 1861 | } | 1892 | } |
| 1862 | }, | 1893 | }, |
| 1894 | "handlers.TimelinePoint": { | ||
| 1895 | "type": "object", | ||
| 1896 | "properties": { | ||
| 1897 | "count": { | ||
| 1898 | "type": "integer" | ||
| 1899 | }, | ||
| 1900 | "date": { | ||
| 1901 | "type": "string" | ||
| 1902 | } | ||
| 1903 | } | ||
| 1904 | }, | ||
| 1905 | "handlers.TimelineResponse": { | ||
| 1906 | "type": "object", | ||
| 1907 | "properties": { | ||
| 1908 | "timeline_multiplayer": { | ||
| 1909 | "type": "array", | ||
| 1910 | "items": { | ||
| 1911 | "$ref": "#/definitions/handlers.TimelinePoint" | ||
| 1912 | } | ||
| 1913 | }, | ||
| 1914 | "timeline_singleplayer": { | ||
| 1915 | "type": "array", | ||
| 1916 | "items": { | ||
| 1917 | "$ref": "#/definitions/handlers.TimelinePoint" | ||
| 1918 | } | ||
| 1919 | } | ||
| 1920 | } | ||
| 1921 | }, | ||
| 1863 | "models.Category": { | 1922 | "models.Category": { |
| 1864 | "type": "object", | 1923 | "type": "object", |
| 1865 | "properties": { | 1924 | "properties": { |
| @@ -1945,6 +2004,9 @@ const docTemplate = `{ | |||
| 1945 | "chapter_name": { | 2004 | "chapter_name": { |
| 1946 | "type": "string" | 2005 | "type": "string" |
| 1947 | }, | 2006 | }, |
| 2007 | "difficulty": { | ||
| 2008 | "type": "integer" | ||
| 2009 | }, | ||
| 1948 | "game_name": { | 2010 | "game_name": { |
| 1949 | "type": "string" | 2011 | "type": "string" |
| 1950 | }, | 2012 | }, |
diff --git a/backend/docs/swagger.json b/backend/docs/swagger.json index 6c10cfc..981d017 100644 --- a/backend/docs/swagger.json +++ b/backend/docs/swagger.json | |||
| @@ -244,37 +244,6 @@ | |||
| 244 | } | 244 | } |
| 245 | } | 245 | } |
| 246 | }, | 246 | }, |
| 247 | "/logs/score": { | ||
| 248 | "get": { | ||
| 249 | "description": "Get score logs of every player.", | ||
| 250 | "produces": [ | ||
| 251 | "application/json" | ||
| 252 | ], | ||
| 253 | "tags": [ | ||
| 254 | "logs" | ||
| 255 | ], | ||
| 256 | "responses": { | ||
| 257 | "200": { | ||
| 258 | "description": "OK", | ||
| 259 | "schema": { | ||
| 260 | "allOf": [ | ||
| 261 | { | ||
| 262 | "$ref": "#/definitions/models.Response" | ||
| 263 | }, | ||
| 264 | { | ||
| 265 | "type": "object", | ||
| 266 | "properties": { | ||
| 267 | "data": { | ||
| 268 | "$ref": "#/definitions/handlers.ScoreLogsResponse" | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | ] | ||
| 273 | } | ||
| 274 | } | ||
| 275 | } | ||
| 276 | } | ||
| 277 | }, | ||
| 278 | "/maps/{mapid}/discussions": { | 247 | "/maps/{mapid}/discussions": { |
| 279 | "get": { | 248 | "get": { |
| 280 | "description": "Get map discussions with specified map id.", | 249 | "description": "Get map discussions with specified map id.", |
| @@ -1214,6 +1183,68 @@ | |||
| 1214 | } | 1183 | } |
| 1215 | } | 1184 | } |
| 1216 | }, | 1185 | }, |
| 1186 | "/stats/scores": { | ||
| 1187 | "get": { | ||
| 1188 | "description": "Get score logs of every player.", | ||
| 1189 | "produces": [ | ||
| 1190 | "application/json" | ||
| 1191 | ], | ||
| 1192 | "tags": [ | ||
| 1193 | "stats" | ||
| 1194 | ], | ||
| 1195 | "responses": { | ||
| 1196 | "200": { | ||
| 1197 | "description": "OK", | ||
| 1198 | "schema": { | ||
| 1199 | "allOf": [ | ||
| 1200 | { | ||
| 1201 | "$ref": "#/definitions/models.Response" | ||
| 1202 | }, | ||
| 1203 | { | ||
| 1204 | "type": "object", | ||
| 1205 | "properties": { | ||
| 1206 | "data": { | ||
| 1207 | "$ref": "#/definitions/handlers.ScoresResponse" | ||
| 1208 | } | ||
| 1209 | } | ||
| 1210 | } | ||
| 1211 | ] | ||
| 1212 | } | ||
| 1213 | } | ||
| 1214 | } | ||
| 1215 | } | ||
| 1216 | }, | ||
| 1217 | "/stats/timeline": { | ||
| 1218 | "get": { | ||
| 1219 | "description": "Get the history of portal count world records over time.", | ||
| 1220 | "produces": [ | ||
| 1221 | "application/json" | ||
| 1222 | ], | ||
| 1223 | "tags": [ | ||
| 1224 | "stats" | ||
| 1225 | ], | ||
| 1226 | "responses": { | ||
| 1227 | "200": { | ||
| 1228 | "description": "OK", | ||
| 1229 | "schema": { | ||
| 1230 | "allOf": [ | ||
| 1231 | { | ||
| 1232 | "$ref": "#/definitions/models.Response" | ||
| 1233 | }, | ||
| 1234 | { | ||
| 1235 | "type": "object", | ||
| 1236 | "properties": { | ||
| 1237 | "data": { | ||
| 1238 | "$ref": "#/definitions/handlers.TimelineResponse" | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | } | ||
| 1242 | ] | ||
| 1243 | } | ||
| 1244 | } | ||
| 1245 | } | ||
| 1246 | } | ||
| 1247 | }, | ||
| 1217 | "/token": { | 1248 | "/token": { |
| 1218 | "get": { | 1249 | "get": { |
| 1219 | "description": "Gets the token cookie value from the user.", | 1250 | "description": "Gets the token cookie value from the user.", |
| @@ -1768,18 +1799,7 @@ | |||
| 1768 | } | 1799 | } |
| 1769 | } | 1800 | } |
| 1770 | }, | 1801 | }, |
| 1771 | "handlers.ScoreLogsResponse": { | 1802 | "handlers.ScoresDetails": { |
| 1772 | "type": "object", | ||
| 1773 | "properties": { | ||
| 1774 | "scores": { | ||
| 1775 | "type": "array", | ||
| 1776 | "items": { | ||
| 1777 | "$ref": "#/definitions/handlers.ScoreLogsResponseDetails" | ||
| 1778 | } | ||
| 1779 | } | ||
| 1780 | } | ||
| 1781 | }, | ||
| 1782 | "handlers.ScoreLogsResponseDetails": { | ||
| 1783 | "type": "object", | 1803 | "type": "object", |
| 1784 | "properties": { | 1804 | "properties": { |
| 1785 | "date": { | 1805 | "date": { |
| @@ -1805,6 +1825,17 @@ | |||
| 1805 | } | 1825 | } |
| 1806 | } | 1826 | } |
| 1807 | }, | 1827 | }, |
| 1828 | "handlers.ScoresResponse": { | ||
| 1829 | "type": "object", | ||
| 1830 | "properties": { | ||
| 1831 | "scores": { | ||
| 1832 | "type": "array", | ||
| 1833 | "items": { | ||
| 1834 | "$ref": "#/definitions/handlers.ScoresDetails" | ||
| 1835 | } | ||
| 1836 | } | ||
| 1837 | } | ||
| 1838 | }, | ||
| 1808 | "handlers.SearchResponse": { | 1839 | "handlers.SearchResponse": { |
| 1809 | "type": "object", | 1840 | "type": "object", |
| 1810 | "properties": { | 1841 | "properties": { |
| @@ -1854,6 +1885,34 @@ | |||
| 1854 | } | 1885 | } |
| 1855 | } | 1886 | } |
| 1856 | }, | 1887 | }, |
| 1888 | "handlers.TimelinePoint": { | ||
| 1889 | "type": "object", | ||
| 1890 | "properties": { | ||
| 1891 | "count": { | ||
| 1892 | "type": "integer" | ||
| 1893 | }, | ||
| 1894 | "date": { | ||
| 1895 | "type": "string" | ||
| 1896 | } | ||
| 1897 | } | ||
| 1898 | }, | ||
| 1899 | "handlers.TimelineResponse": { | ||
| 1900 | "type": "object", | ||
| 1901 | "properties": { | ||
| 1902 | "timeline_multiplayer": { | ||
| 1903 | "type": "array", | ||
| 1904 | "items": { | ||
| 1905 | "$ref": "#/definitions/handlers.TimelinePoint" | ||
| 1906 | } | ||
| 1907 | }, | ||
| 1908 | "timeline_singleplayer": { | ||
| 1909 | "type": "array", | ||
| 1910 | "items": { | ||
| 1911 | "$ref": "#/definitions/handlers.TimelinePoint" | ||
| 1912 | } | ||
| 1913 | } | ||
| 1914 | } | ||
| 1915 | }, | ||
| 1857 | "models.Category": { | 1916 | "models.Category": { |
| 1858 | "type": "object", | 1917 | "type": "object", |
| 1859 | "properties": { | 1918 | "properties": { |
| @@ -1939,6 +1998,9 @@ | |||
| 1939 | "chapter_name": { | 1998 | "chapter_name": { |
| 1940 | "type": "string" | 1999 | "type": "string" |
| 1941 | }, | 2000 | }, |
| 2001 | "difficulty": { | ||
| 2002 | "type": "integer" | ||
| 2003 | }, | ||
| 1942 | "game_name": { | 2004 | "game_name": { |
| 1943 | "type": "string" | 2005 | "type": "string" |
| 1944 | }, | 2006 | }, |
diff --git a/backend/docs/swagger.yaml b/backend/docs/swagger.yaml index 8f33b94..0b3258c 100644 --- a/backend/docs/swagger.yaml +++ b/backend/docs/swagger.yaml | |||
| @@ -287,14 +287,7 @@ definitions: | |||
| 287 | score_time: | 287 | score_time: |
| 288 | type: integer | 288 | type: integer |
| 289 | type: object | 289 | type: object |
| 290 | handlers.ScoreLogsResponse: | 290 | handlers.ScoresDetails: |
| 291 | properties: | ||
| 292 | scores: | ||
| 293 | items: | ||
| 294 | $ref: '#/definitions/handlers.ScoreLogsResponseDetails' | ||
| 295 | type: array | ||
| 296 | type: object | ||
| 297 | handlers.ScoreLogsResponseDetails: | ||
| 298 | properties: | 291 | properties: |
| 299 | date: | 292 | date: |
| 300 | type: string | 293 | type: string |
| @@ -311,6 +304,13 @@ definitions: | |||
| 311 | user: | 304 | user: |
| 312 | $ref: '#/definitions/models.UserShort' | 305 | $ref: '#/definitions/models.UserShort' |
| 313 | type: object | 306 | type: object |
| 307 | handlers.ScoresResponse: | ||
| 308 | properties: | ||
| 309 | scores: | ||
| 310 | items: | ||
| 311 | $ref: '#/definitions/handlers.ScoresDetails' | ||
| 312 | type: array | ||
| 313 | type: object | ||
| 314 | handlers.SearchResponse: | 314 | handlers.SearchResponse: |
| 315 | properties: | 315 | properties: |
| 316 | maps: | 316 | maps: |
| @@ -343,6 +343,24 @@ definitions: | |||
| 343 | user_name: | 343 | user_name: |
| 344 | type: string | 344 | type: string |
| 345 | type: object | 345 | type: object |
| 346 | handlers.TimelinePoint: | ||
| 347 | properties: | ||
| 348 | count: | ||
| 349 | type: integer | ||
| 350 | date: | ||
| 351 | type: string | ||
| 352 | type: object | ||
| 353 | handlers.TimelineResponse: | ||
| 354 | properties: | ||
| 355 | timeline_multiplayer: | ||
| 356 | items: | ||
| 357 | $ref: '#/definitions/handlers.TimelinePoint' | ||
| 358 | type: array | ||
| 359 | timeline_singleplayer: | ||
| 360 | items: | ||
| 361 | $ref: '#/definitions/handlers.TimelinePoint' | ||
| 362 | type: array | ||
| 363 | type: object | ||
| 346 | models.Category: | 364 | models.Category: |
| 347 | properties: | 365 | properties: |
| 348 | id: | 366 | id: |
| @@ -398,6 +416,8 @@ definitions: | |||
| 398 | properties: | 416 | properties: |
| 399 | chapter_name: | 417 | chapter_name: |
| 400 | type: string | 418 | type: string |
| 419 | difficulty: | ||
| 420 | type: integer | ||
| 401 | game_name: | 421 | game_name: |
| 402 | type: string | 422 | type: string |
| 403 | id: | 423 | id: |
| @@ -672,23 +692,6 @@ paths: | |||
| 672 | type: object | 692 | type: object |
| 673 | tags: | 693 | tags: |
| 674 | - login | 694 | - login |
| 675 | /logs/score: | ||
| 676 | get: | ||
| 677 | description: Get score logs of every player. | ||
| 678 | produces: | ||
| 679 | - application/json | ||
| 680 | responses: | ||
| 681 | "200": | ||
| 682 | description: OK | ||
| 683 | schema: | ||
| 684 | allOf: | ||
| 685 | - $ref: '#/definitions/models.Response' | ||
| 686 | - properties: | ||
| 687 | data: | ||
| 688 | $ref: '#/definitions/handlers.ScoreLogsResponse' | ||
| 689 | type: object | ||
| 690 | tags: | ||
| 691 | - logs | ||
| 692 | /maps/{mapid}/discussions: | 695 | /maps/{mapid}/discussions: |
| 693 | get: | 696 | get: |
| 694 | description: Get map discussions with specified map id. | 697 | description: Get map discussions with specified map id. |
| @@ -1259,6 +1262,40 @@ paths: | |||
| 1259 | type: object | 1262 | type: object |
| 1260 | tags: | 1263 | tags: |
| 1261 | - search | 1264 | - search |
| 1265 | /stats/scores: | ||
| 1266 | get: | ||
| 1267 | description: Get score logs of every player. | ||
| 1268 | produces: | ||
| 1269 | - application/json | ||
| 1270 | responses: | ||
| 1271 | "200": | ||
| 1272 | description: OK | ||
| 1273 | schema: | ||
| 1274 | allOf: | ||
| 1275 | - $ref: '#/definitions/models.Response' | ||
| 1276 | - properties: | ||
| 1277 | data: | ||
| 1278 | $ref: '#/definitions/handlers.ScoresResponse' | ||
| 1279 | type: object | ||
| 1280 | tags: | ||
| 1281 | - stats | ||
| 1282 | /stats/timeline: | ||
| 1283 | get: | ||
| 1284 | description: Get the history of portal count world records over time. | ||
| 1285 | produces: | ||
| 1286 | - application/json | ||
| 1287 | responses: | ||
| 1288 | "200": | ||
| 1289 | description: OK | ||
| 1290 | schema: | ||
| 1291 | allOf: | ||
| 1292 | - $ref: '#/definitions/models.Response' | ||
| 1293 | - properties: | ||
| 1294 | data: | ||
| 1295 | $ref: '#/definitions/handlers.TimelineResponse' | ||
| 1296 | type: object | ||
| 1297 | tags: | ||
| 1298 | - stats | ||
| 1262 | /token: | 1299 | /token: |
| 1263 | delete: | 1300 | delete: |
| 1264 | description: Deletes the token cookie from the user. | 1301 | description: Deletes the token cookie from the user. |
diff --git a/backend/go.mod b/backend/go.mod index f9fe0db..df904e8 100644 --- a/backend/go.mod +++ b/backend/go.mod | |||
| @@ -3,7 +3,7 @@ module lphub | |||
| 3 | go 1.23.0 | 3 | go 1.23.0 |
| 4 | 4 | ||
| 5 | require ( | 5 | require ( |
| 6 | github.com/gin-gonic/gin v1.10.0 | 6 | github.com/gin-gonic/gin v1.10.1 |
| 7 | github.com/joho/godotenv v1.5.1 | 7 | github.com/joho/godotenv v1.5.1 |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| @@ -11,6 +11,8 @@ require ( | |||
| 11 | github.com/Backblaze/blazer v0.7.1 | 11 | github.com/Backblaze/blazer v0.7.1 |
| 12 | github.com/golang-jwt/jwt/v4 v4.5.0 | 12 | github.com/golang-jwt/jwt/v4 v4.5.0 |
| 13 | github.com/google/uuid v1.6.0 | 13 | github.com/google/uuid v1.6.0 |
| 14 | github.com/newrelic/go-agent/v3 v3.40.1 | ||
| 15 | github.com/newrelic/go-agent/v3/integrations/nrgin v1.4.1 | ||
| 14 | github.com/pektezol/steam_go v1.1.2 | 16 | github.com/pektezol/steam_go v1.1.2 |
| 15 | github.com/swaggo/files v1.0.1 | 17 | github.com/swaggo/files v1.0.1 |
| 16 | github.com/swaggo/gin-swagger v1.6.0 | 18 | github.com/swaggo/gin-swagger v1.6.0 |
| @@ -20,34 +22,31 @@ require ( | |||
| 20 | 22 | ||
| 21 | require ( | 23 | require ( |
| 22 | github.com/KyleBanks/depth v1.2.1 // indirect | 24 | github.com/KyleBanks/depth v1.2.1 // indirect |
| 23 | github.com/bytedance/sonic v1.12.2 // indirect | 25 | github.com/bytedance/sonic v1.13.3 // indirect |
| 24 | github.com/bytedance/sonic/loader v0.2.0 // indirect | 26 | github.com/bytedance/sonic/loader v0.2.4 // indirect |
| 25 | github.com/cloudwego/base64x v0.1.4 // indirect | 27 | github.com/cloudwego/base64x v0.1.5 // indirect |
| 26 | github.com/cloudwego/iasm v0.2.0 // indirect | 28 | github.com/gabriel-vasile/mimetype v1.4.9 // indirect |
| 27 | github.com/gabriel-vasile/mimetype v1.4.5 // indirect | ||
| 28 | github.com/go-openapi/jsonpointer v0.21.0 // indirect | 29 | github.com/go-openapi/jsonpointer v0.21.0 // indirect |
| 29 | github.com/go-openapi/jsonreference v0.21.0 // indirect | 30 | github.com/go-openapi/jsonreference v0.21.0 // indirect |
| 30 | github.com/go-openapi/spec v0.21.0 // indirect | 31 | github.com/go-openapi/spec v0.21.0 // indirect |
| 31 | github.com/go-openapi/swag v0.23.0 // indirect | 32 | github.com/go-openapi/swag v0.23.0 // indirect |
| 32 | github.com/josharian/intern v1.0.0 // indirect | 33 | github.com/josharian/intern v1.0.0 // indirect |
| 33 | github.com/klauspost/cpuid/v2 v2.2.8 // indirect | 34 | github.com/klauspost/cpuid/v2 v2.2.10 // indirect |
| 34 | github.com/mailru/easyjson v0.7.7 // indirect | 35 | 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 | ||
| 37 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | 36 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect |
| 38 | golang.org/x/arch v0.10.0 // indirect | 37 | golang.org/x/arch v0.18.0 // indirect |
| 39 | golang.org/x/tools v0.25.0 // indirect | 38 | golang.org/x/tools v0.33.0 // indirect |
| 40 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect | 39 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect |
| 41 | google.golang.org/grpc v1.65.0 // indirect | 40 | google.golang.org/grpc v1.65.0 // indirect |
| 42 | gopkg.in/yaml.v3 v3.0.1 // indirect | 41 | gopkg.in/yaml.v3 v3.0.1 // indirect |
| 43 | ) | 42 | ) |
| 44 | 43 | ||
| 45 | require ( | 44 | require ( |
| 46 | github.com/gin-contrib/sse v0.1.0 // indirect | 45 | github.com/gin-contrib/sse v1.1.0 // indirect |
| 47 | github.com/go-playground/locales v0.14.1 // indirect | 46 | github.com/go-playground/locales v0.14.1 // indirect |
| 48 | github.com/go-playground/universal-translator v0.18.1 // indirect | 47 | github.com/go-playground/universal-translator v0.18.1 // indirect |
| 49 | github.com/go-playground/validator/v10 v10.22.1 // indirect | 48 | github.com/go-playground/validator/v10 v10.26.0 // indirect |
| 50 | github.com/goccy/go-json v0.10.3 // indirect | 49 | github.com/goccy/go-json v0.10.5 // indirect |
| 51 | github.com/json-iterator/go v1.1.12 // indirect | 50 | github.com/json-iterator/go v1.1.12 // indirect |
| 52 | github.com/leodido/go-urn v1.4.0 // indirect | 51 | github.com/leodido/go-urn v1.4.0 // indirect |
| 53 | github.com/lib/pq v1.10.9 | 52 | github.com/lib/pq v1.10.9 |
| @@ -55,11 +54,11 @@ require ( | |||
| 55 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | 54 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect |
| 56 | github.com/modern-go/reflect2 v1.0.2 // indirect | 55 | github.com/modern-go/reflect2 v1.0.2 // indirect |
| 57 | github.com/pektezol/bitreader v1.4.3 | 56 | github.com/pektezol/bitreader v1.4.3 |
| 58 | github.com/pelletier/go-toml/v2 v2.2.3 // indirect | 57 | github.com/pelletier/go-toml/v2 v2.2.4 // indirect |
| 59 | github.com/ugorji/go/codec v1.2.12 // indirect | 58 | github.com/ugorji/go/codec v1.3.0 // indirect |
| 60 | golang.org/x/crypto v0.27.0 // indirect | 59 | golang.org/x/crypto v0.39.0 // indirect |
| 61 | golang.org/x/net v0.29.0 // indirect | 60 | golang.org/x/net v0.41.0 // indirect |
| 62 | golang.org/x/sys v0.25.0 // indirect | 61 | golang.org/x/sys v0.33.0 // indirect |
| 63 | golang.org/x/text v0.18.0 // indirect | 62 | golang.org/x/text v0.26.0 // indirect |
| 64 | google.golang.org/protobuf v1.34.2 // indirect | 63 | google.golang.org/protobuf v1.36.6 // indirect |
| 65 | ) | 64 | ) |
diff --git a/backend/go.sum b/backend/go.sum index f655023..b88dd43 100644 --- a/backend/go.sum +++ b/backend/go.sum | |||
| @@ -2,26 +2,25 @@ github.com/Backblaze/blazer v0.7.1 h1:J43PbFj6hXLg1jvCNr+rQoAsxzKK0IP7ftl1ReCwpc | |||
| 2 | github.com/Backblaze/blazer v0.7.1/go.mod h1:MhntL1nMpIuoqrPP6TnZu/xTydMgOAe/Xm6KongbjKs= | 2 | github.com/Backblaze/blazer v0.7.1/go.mod h1:MhntL1nMpIuoqrPP6TnZu/xTydMgOAe/Xm6KongbjKs= |
| 3 | github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= | 3 | github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= |
| 4 | github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= | 4 | github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= |
| 5 | github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg= | 5 | github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0= |
| 6 | github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= | 6 | github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= |
| 7 | github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= | 7 | github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= |
| 8 | github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= | 8 | github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= |
| 9 | github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= | 9 | github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= |
| 10 | github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= | 10 | github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= |
| 11 | github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= | 11 | github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= |
| 12 | github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= | ||
| 13 | github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= | 12 | github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= |
| 14 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | 13 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
| 15 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | 14 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
| 16 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | 15 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
| 17 | github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= | 16 | github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY= |
| 18 | github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= | 17 | github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok= |
| 19 | github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= | 18 | github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= |
| 20 | github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= | 19 | github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= |
| 21 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | 20 | github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= |
| 22 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | 21 | github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= |
| 23 | github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= | 22 | github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= |
| 24 | github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= | 23 | github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= |
| 25 | github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= | 24 | github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= |
| 26 | github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= | 25 | github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= |
| 27 | github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= | 26 | github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= |
| @@ -36,14 +35,14 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o | |||
| 36 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= | 35 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= |
| 37 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= | 36 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= |
| 38 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= | 37 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= |
| 39 | github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= | 38 | github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= |
| 40 | github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= | 39 | github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= |
| 41 | github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= | 40 | github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= |
| 42 | github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= | 41 | github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= |
| 43 | github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= | 42 | github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= |
| 44 | github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= | 43 | github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= |
| 45 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= | 44 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= |
| 46 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | 45 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= |
| 47 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | 46 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= |
| 48 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= | 47 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= |
| 49 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | 48 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
| @@ -54,8 +53,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF | |||
| 54 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | 53 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= |
| 55 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | 54 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= |
| 56 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | 55 | github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= |
| 57 | github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= | 56 | github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= |
| 58 | github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= | 57 | github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= |
| 59 | github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= | 58 | github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= |
| 60 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | 59 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= |
| 61 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | 60 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= |
| @@ -82,8 +81,8 @@ github.com/pektezol/bitreader v1.4.3 h1:+WjsD6qOAaI6Q1jOOlEJcnaEso8vPMKRZnnaDnZh | |||
| 82 | github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk= | 81 | github.com/pektezol/bitreader v1.4.3/go.mod h1:xBQEsQpOf8B5yPrnOTkirZGyVUV6Bqp0ups2RIlTskk= |
| 83 | github.com/pektezol/steam_go v1.1.2 h1:fta6SW+La8NfmCtR/Kn73bAmTBvCgUkkLCplsJGzx7g= | 82 | github.com/pektezol/steam_go v1.1.2 h1:fta6SW+La8NfmCtR/Kn73bAmTBvCgUkkLCplsJGzx7g= |
| 84 | github.com/pektezol/steam_go v1.1.2/go.mod h1:8dk95CLOQKRr0BA8ChnNbTEe0/f2Ibi5O4rmpS9oZCo= | 83 | github.com/pektezol/steam_go v1.1.2/go.mod h1:8dk95CLOQKRr0BA8ChnNbTEe0/f2Ibi5O4rmpS9oZCo= |
| 85 | github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= | 84 | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= |
| 86 | github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= | 85 | github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= |
| 87 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | 86 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
| 88 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | 87 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
| 89 | github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= | 88 | github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= |
| @@ -96,8 +95,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ | |||
| 96 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | 95 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
| 97 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | 96 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= |
| 98 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | 97 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= |
| 99 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | 98 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= |
| 100 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | 99 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= |
| 101 | github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= | 100 | github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= |
| 102 | github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= | 101 | github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= |
| 103 | github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= | 102 | github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= |
| @@ -106,28 +105,28 @@ github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= | |||
| 106 | github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= | 105 | github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= |
| 107 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= | 106 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= |
| 108 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= | 107 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= |
| 109 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= | 108 | github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= |
| 110 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= | 109 | github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= |
| 111 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | 110 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= |
| 112 | golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8= | 111 | golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc= |
| 113 | golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= | 112 | golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= |
| 114 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | 113 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
| 115 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | 114 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= |
| 116 | golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= | 115 | golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= |
| 117 | golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= | 116 | golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= |
| 118 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | 117 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= |
| 119 | golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= | 118 | golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= |
| 120 | golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= | 119 | golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= |
| 121 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | 120 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
| 122 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | 121 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= |
| 123 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | 122 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= |
| 124 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | 123 | golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= |
| 125 | golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= | 124 | golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= |
| 126 | golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= | 125 | golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= |
| 127 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | 126 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
| 128 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | 127 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
| 129 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= | 128 | golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= |
| 130 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | 129 | golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= |
| 131 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | 130 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
| 132 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | 131 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
| 133 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 132 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| @@ -135,8 +134,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc | |||
| 135 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 134 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 136 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 135 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 137 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 136 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 138 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= | 137 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= |
| 139 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | 138 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= |
| 140 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | 139 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
| 141 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | 140 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= |
| 142 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= | 141 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= |
| @@ -144,23 +143,22 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | |||
| 144 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | 143 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
| 145 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | 144 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= |
| 146 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | 145 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= |
| 147 | golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= | 146 | golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= |
| 148 | golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= | 147 | golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= |
| 149 | golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= | 148 | golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= |
| 150 | golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= | 149 | golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= |
| 151 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | 150 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
| 152 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | 151 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
| 153 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | 152 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= |
| 154 | golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= | 153 | golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= |
| 155 | golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= | 154 | golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= |
| 156 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | 155 | 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= | 156 | 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= | 157 | 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= | 158 | google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= |
| 161 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= | 159 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= |
| 162 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= | 160 | google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= |
| 163 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= | 161 | google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= |
| 164 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | 162 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
| 165 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | 163 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= |
| 166 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | 164 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= |
diff --git a/backend/handlers/logs.go b/backend/handlers/logs.go deleted file mode 100644 index 693c448..0000000 --- a/backend/handlers/logs.go +++ /dev/null | |||
| @@ -1,103 +0,0 @@ | |||
| 1 | package handlers | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "net/http" | ||
| 5 | "time" | ||
| 6 | |||
| 7 | "lphub/database" | ||
| 8 | "lphub/models" | ||
| 9 | |||
| 10 | "github.com/gin-gonic/gin" | ||
| 11 | ) | ||
| 12 | |||
| 13 | type Log struct { | ||
| 14 | User models.UserShort `json:"user"` | ||
| 15 | Type string `json:"type"` | ||
| 16 | Description string `json:"description"` | ||
| 17 | Message string `json:"message"` | ||
| 18 | Date time.Time `json:"date"` | ||
| 19 | } | ||
| 20 | |||
| 21 | type LogsResponse struct { | ||
| 22 | Logs []LogsResponseDetails `json:"logs"` | ||
| 23 | } | ||
| 24 | |||
| 25 | type LogsResponseDetails struct { | ||
| 26 | User models.UserShort `json:"user"` | ||
| 27 | Log string `json:"detail"` | ||
| 28 | Message string `json:"message"` | ||
| 29 | Date time.Time `json:"date"` | ||
| 30 | } | ||
| 31 | |||
| 32 | type ScoreLogsResponse struct { | ||
| 33 | Logs []ScoreLogsResponseDetails `json:"scores"` | ||
| 34 | } | ||
| 35 | |||
| 36 | type ScoreLogsResponseDetails struct { | ||
| 37 | Game models.Game `json:"game"` | ||
| 38 | User models.UserShort `json:"user"` | ||
| 39 | Map models.MapShort `json:"map"` | ||
| 40 | ScoreCount int `json:"score_count"` | ||
| 41 | ScoreTime int `json:"score_time"` | ||
| 42 | DemoID string `json:"demo_id"` | ||
| 43 | Date time.Time `json:"date"` | ||
| 44 | } | ||
| 45 | |||
| 46 | // GET Score Logs | ||
| 47 | // | ||
| 48 | // @Description Get score logs of every player. | ||
| 49 | // @Tags logs | ||
| 50 | // @Produce json | ||
| 51 | // @Success 200 {object} models.Response{data=ScoreLogsResponse} | ||
| 52 | // @Router /logs/score [get] | ||
| 53 | func ScoreLogs(c *gin.Context) { | ||
| 54 | response := ScoreLogsResponse{Logs: []ScoreLogsResponseDetails{}} | ||
| 55 | sql := `SELECT g.id, | ||
| 56 | g."name", | ||
| 57 | g.is_coop, | ||
| 58 | rs.map_id, | ||
| 59 | m.name AS map_name, | ||
| 60 | u.steam_id, | ||
| 61 | u.user_name, | ||
| 62 | rs.score_count, | ||
| 63 | rs.score_time, | ||
| 64 | rs.demo_id, | ||
| 65 | rs.record_date | ||
| 66 | FROM ( | ||
| 67 | SELECT id, map_id, user_id, score_count, score_time, demo_id, record_date | ||
| 68 | FROM records_sp WHERE is_deleted = false | ||
| 69 | |||
| 70 | UNION ALL | ||
| 71 | |||
| 72 | SELECT id, map_id, host_id AS user_id, score_count, score_time, host_demo_id AS demo_id, record_date | ||
| 73 | FROM records_mp WHERE is_deleted = false | ||
| 74 | |||
| 75 | UNION ALL | ||
| 76 | |||
| 77 | SELECT id, map_id, partner_id AS user_id, score_count, score_time, partner_demo_id AS demo_id, record_date | ||
| 78 | FROM records_mp WHERE is_deleted = false | ||
| 79 | ) AS rs | ||
| 80 | JOIN users u ON rs.user_id = u.steam_id | ||
| 81 | JOIN maps m ON rs.map_id = m.id | ||
| 82 | JOIN games g ON m.game_id = g.id | ||
| 83 | ORDER BY rs.record_date DESC LIMIT 100;` | ||
| 84 | rows, err := database.DB.Query(sql) | ||
| 85 | if err != nil { | ||
| 86 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | ||
| 87 | return | ||
| 88 | } | ||
| 89 | for rows.Next() { | ||
| 90 | score := ScoreLogsResponseDetails{} | ||
| 91 | err = rows.Scan(&score.Game.ID, &score.Game.Name, &score.Game.IsCoop, &score.Map.ID, &score.Map.Name, &score.User.SteamID, &score.User.UserName, &score.ScoreCount, &score.ScoreTime, &score.DemoID, &score.Date) | ||
| 92 | if err != nil { | ||
| 93 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | ||
| 94 | return | ||
| 95 | } | ||
| 96 | response.Logs = append(response.Logs, score) | ||
| 97 | } | ||
| 98 | c.JSON(http.StatusOK, models.Response{ | ||
| 99 | Success: true, | ||
| 100 | Message: "Successfully retrieved score logs.", | ||
| 101 | Data: response, | ||
| 102 | }) | ||
| 103 | } | ||
diff --git a/backend/handlers/record.go b/backend/handlers/record.go index 25a6c6d..07ae5a8 100644 --- a/backend/handlers/record.go +++ b/backend/handlers/record.go | |||
| @@ -35,11 +35,11 @@ type RecordResponse struct { | |||
| 35 | // @Tags maps / leaderboards | 35 | // @Tags maps / leaderboards |
| 36 | // @Accept mpfd | 36 | // @Accept mpfd |
| 37 | // @Produce json | 37 | // @Produce json |
| 38 | // @Param mapid path int true "Map ID" | 38 | // @Param mapid path int true "Map ID" |
| 39 | // @Param Authorization header string true "JWT Token" | 39 | // @Param Authorization header string true "JWT Token" |
| 40 | // @Param host_demo formData file true "Host Demo" | 40 | // @Param host_demo formData file true "Host Demo" |
| 41 | // @Param partner_demo formData file false "Partner Demo" | 41 | // @Param partner_demo formData file false "Partner Demo" |
| 42 | // @Success 200 {object} models.Response{data=RecordResponse} | 42 | // @Success 200 {object} models.Response{data=RecordResponse} |
| 43 | // @Router /maps/{mapid}/record [post] | 43 | // @Router /maps/{mapid}/record [post] |
| 44 | func CreateRecordWithDemo(c *gin.Context) { | 44 | func CreateRecordWithDemo(c *gin.Context) { |
| 45 | id := c.Param("mapid") | 45 | id := c.Param("mapid") |
diff --git a/backend/handlers/stats.go b/backend/handlers/stats.go new file mode 100644 index 0000000..8fe98f9 --- /dev/null +++ b/backend/handlers/stats.go | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | package handlers | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "net/http" | ||
| 5 | "time" | ||
| 6 | |||
| 7 | "lphub/database" | ||
| 8 | "lphub/models" | ||
| 9 | |||
| 10 | "github.com/gin-gonic/gin" | ||
| 11 | ) | ||
| 12 | |||
| 13 | type ScoresResponse struct { | ||
| 14 | Logs []ScoresDetails `json:"scores"` | ||
| 15 | } | ||
| 16 | |||
| 17 | type ScoresDetails struct { | ||
| 18 | Game models.Game `json:"game"` | ||
| 19 | User models.UserShort `json:"user"` | ||
| 20 | Map models.MapShort `json:"map"` | ||
| 21 | ScoreCount int `json:"score_count"` | ||
| 22 | ScoreTime int `json:"score_time"` | ||
| 23 | DemoID string `json:"demo_id"` | ||
| 24 | Date time.Time `json:"date"` | ||
| 25 | } | ||
| 26 | |||
| 27 | type TimelinePoint struct { | ||
| 28 | Date string `json:"date"` | ||
| 29 | Count int `json:"count"` | ||
| 30 | } | ||
| 31 | |||
| 32 | type TimelineResponse struct { | ||
| 33 | Singleplayer []TimelinePoint `json:"timeline_singleplayer"` | ||
| 34 | Multiplayer []TimelinePoint `json:"timeline_multiplayer"` | ||
| 35 | } | ||
| 36 | |||
| 37 | // GET Scores | ||
| 38 | // | ||
| 39 | // @Description Get score logs of every player. | ||
| 40 | // @Tags stats | ||
| 41 | // @Produce json | ||
| 42 | // @Success 200 {object} models.Response{data=ScoresResponse} | ||
| 43 | // @Router /stats/scores [get] | ||
| 44 | func Scores(c *gin.Context) { | ||
| 45 | response := ScoresResponse{Logs: []ScoresDetails{}} | ||
| 46 | sql := `SELECT g.id, | ||
| 47 | g."name", | ||
| 48 | g.is_coop, | ||
| 49 | rs.map_id, | ||
| 50 | m.name AS map_name, | ||
| 51 | u.steam_id, | ||
| 52 | u.user_name, | ||
| 53 | rs.score_count, | ||
| 54 | rs.score_time, | ||
| 55 | rs.demo_id, | ||
| 56 | rs.record_date | ||
| 57 | FROM ( | ||
| 58 | SELECT id, map_id, user_id, score_count, score_time, demo_id, record_date | ||
| 59 | FROM records_sp WHERE is_deleted = false | ||
| 60 | |||
| 61 | UNION ALL | ||
| 62 | |||
| 63 | SELECT id, map_id, host_id AS user_id, score_count, score_time, host_demo_id AS demo_id, record_date | ||
| 64 | FROM records_mp WHERE is_deleted = false | ||
| 65 | |||
| 66 | UNION ALL | ||
| 67 | |||
| 68 | SELECT id, map_id, partner_id AS user_id, score_count, score_time, partner_demo_id AS demo_id, record_date | ||
| 69 | FROM records_mp WHERE is_deleted = false | ||
| 70 | ) AS rs | ||
| 71 | JOIN users u ON rs.user_id = u.steam_id | ||
| 72 | JOIN maps m ON rs.map_id = m.id | ||
| 73 | JOIN games g ON m.game_id = g.id | ||
| 74 | ORDER BY rs.record_date DESC LIMIT 100;` | ||
| 75 | rows, err := database.DB.Query(sql) | ||
| 76 | if err != nil { | ||
| 77 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | ||
| 78 | return | ||
| 79 | } | ||
| 80 | for rows.Next() { | ||
| 81 | score := ScoresDetails{} | ||
| 82 | err = rows.Scan(&score.Game.ID, &score.Game.Name, &score.Game.IsCoop, &score.Map.ID, &score.Map.Name, &score.User.SteamID, &score.User.UserName, &score.ScoreCount, &score.ScoreTime, &score.DemoID, &score.Date) | ||
| 83 | if err != nil { | ||
| 84 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | ||
| 85 | return | ||
| 86 | } | ||
| 87 | response.Logs = append(response.Logs, score) | ||
| 88 | } | ||
| 89 | c.JSON(http.StatusOK, models.Response{ | ||
| 90 | Success: true, | ||
| 91 | Message: "Successfully retrieved score logs.", | ||
| 92 | Data: response, | ||
| 93 | }) | ||
| 94 | } | ||
| 95 | |||
| 96 | // GET Timeline | ||
| 97 | // | ||
| 98 | // @Description Get the history of portal count world records over time. | ||
| 99 | // @Tags stats | ||
| 100 | // @Produce json | ||
| 101 | // @Success 200 {object} models.Response{data=TimelineResponse} | ||
| 102 | // @Router /stats/timeline [get] | ||
| 103 | func Timeline(c *gin.Context) { | ||
| 104 | result := TimelineResponse{ | ||
| 105 | Singleplayer: []TimelinePoint{}, | ||
| 106 | Multiplayer: []TimelinePoint{}, | ||
| 107 | } | ||
| 108 | spQuery := ` | ||
| 109 | WITH date_series AS ( | ||
| 110 | SELECT DISTINCT record_date as date | ||
| 111 | FROM map_history | ||
| 112 | WHERE category_id = 1 AND map_id <= 60 AND record_date >= '2013-01-31' | ||
| 113 | ORDER BY record_date | ||
| 114 | ), | ||
| 115 | map_best_at_date AS ( | ||
| 116 | SELECT | ||
| 117 | ds.date, | ||
| 118 | mh.map_id, | ||
| 119 | MIN(mh.score_count) as best_count | ||
| 120 | FROM date_series ds | ||
| 121 | CROSS JOIN (SELECT DISTINCT map_id FROM map_history WHERE category_id = 1 AND map_id <= 60) maps | ||
| 122 | LEFT JOIN map_history mh ON mh.map_id = maps.map_id | ||
| 123 | AND mh.category_id = 1 | ||
| 124 | AND mh.record_date <= ds.date | ||
| 125 | GROUP BY ds.date, mh.map_id | ||
| 126 | ) | ||
| 127 | SELECT | ||
| 128 | date, | ||
| 129 | SUM(best_count) as total_count | ||
| 130 | FROM map_best_at_date | ||
| 131 | GROUP BY date | ||
| 132 | ORDER BY date ASC; | ||
| 133 | ` | ||
| 134 | |||
| 135 | mpQuery := ` | ||
| 136 | WITH date_series AS ( | ||
| 137 | SELECT DISTINCT record_date as date | ||
| 138 | FROM map_history | ||
| 139 | WHERE category_id = 1 AND map_id > 60 AND record_date >= '2011-12-21' | ||
| 140 | ORDER BY record_date | ||
| 141 | ), | ||
| 142 | map_best_at_date AS ( | ||
| 143 | SELECT | ||
| 144 | ds.date, | ||
| 145 | mh.map_id, | ||
| 146 | MIN(mh.score_count) as best_count | ||
| 147 | FROM date_series ds | ||
| 148 | CROSS JOIN (SELECT DISTINCT map_id FROM map_history WHERE category_id = 1 AND map_id > 60) maps | ||
| 149 | LEFT JOIN map_history mh ON mh.map_id = maps.map_id | ||
| 150 | AND mh.category_id = 1 | ||
| 151 | AND mh.record_date <= ds.date | ||
| 152 | GROUP BY ds.date, mh.map_id | ||
| 153 | ) | ||
| 154 | SELECT | ||
| 155 | date, | ||
| 156 | SUM(best_count) as total_count | ||
| 157 | FROM map_best_at_date | ||
| 158 | GROUP BY date | ||
| 159 | ORDER BY date ASC; | ||
| 160 | ` | ||
| 161 | |||
| 162 | rows, err := database.DB.Query(spQuery) | ||
| 163 | if err != nil { | ||
| 164 | return | ||
| 165 | } | ||
| 166 | defer rows.Close() | ||
| 167 | |||
| 168 | for rows.Next() { | ||
| 169 | var dateTime time.Time | ||
| 170 | var count int | ||
| 171 | if err := rows.Scan(&dateTime, &count); err != nil { | ||
| 172 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | ||
| 173 | return | ||
| 174 | } | ||
| 175 | result.Singleplayer = append(result.Singleplayer, TimelinePoint{ | ||
| 176 | Date: dateTime.Format("2006-01-02"), | ||
| 177 | Count: count, | ||
| 178 | }) | ||
| 179 | } | ||
| 180 | |||
| 181 | rows, err = database.DB.Query(mpQuery) | ||
| 182 | if err != nil { | ||
| 183 | return | ||
| 184 | } | ||
| 185 | defer rows.Close() | ||
| 186 | |||
| 187 | for rows.Next() { | ||
| 188 | var dateTime time.Time | ||
| 189 | var count int | ||
| 190 | if err := rows.Scan(&dateTime, &count); err != nil { | ||
| 191 | c.JSON(http.StatusOK, models.ErrorResponse(err.Error())) | ||
| 192 | return | ||
| 193 | } | ||
| 194 | result.Multiplayer = append(result.Multiplayer, TimelinePoint{ | ||
| 195 | Date: dateTime.Format("2006-01-02"), | ||
| 196 | Count: count, | ||
| 197 | }) | ||
| 198 | } | ||
| 199 | c.JSON(http.StatusOK, models.Response{ | ||
| 200 | Success: true, | ||
| 201 | Message: "Successfully retrieved portal count timeline.", | ||
| 202 | Data: result, | ||
| 203 | }) | ||
| 204 | } | ||
diff --git a/backend/main.go b/backend/main.go index e422359..2147be8 100644 --- a/backend/main.go +++ b/backend/main.go | |||
| @@ -29,35 +29,25 @@ func main() { | |||
| 29 | if err != nil { | 29 | if err != nil { |
| 30 | log.Fatal("Error loading .env file") | 30 | log.Fatal("Error loading .env file") |
| 31 | } | 31 | } |
| 32 | var app *newrelic.Application | ||
| 32 | if os.Getenv("ENV") == "PROD" { | 33 | if os.Getenv("ENV") == "PROD" { |
| 33 | gin.SetMode(gin.ReleaseMode) | 34 | gin.SetMode(gin.ReleaseMode) |
| 34 | } | 35 | app, err = newrelic.NewApplication( |
| 35 | app, err := newrelic.NewApplication( | 36 | newrelic.ConfigAppName("lphub"), |
| 36 | newrelic.ConfigAppName("lphub"), | 37 | newrelic.ConfigLicense(os.Getenv("NEWRELIC_LICENSE_KEY")), |
| 37 | newrelic.ConfigLicense(os.Getenv("NEWRELIC_LICENSE_KEY")), | 38 | newrelic.ConfigAppLogForwardingEnabled(true), |
| 38 | newrelic.ConfigAppLogForwardingEnabled(true), | 39 | ) |
| 39 | ) | 40 | if err != nil { |
| 40 | if err != nil { | 41 | log.Fatal("Error instrumenting newrelic") |
| 41 | log.Fatal("Error instrumenting newrelic") | 42 | } |
| 42 | } | 43 | } |
| 43 | router := gin.Default() | 44 | router := gin.Default() |
| 44 | router.Use(nrgin.Middleware(app)) | 45 | if app != nil { |
| 46 | router.Use(nrgin.Middleware(app)) | ||
| 47 | } | ||
| 48 | // router.Use(cors.Default()) // ONLY FOR DEV | ||
| 45 | database.ConnectDB() | 49 | database.ConnectDB() |
| 46 | api.InitRoutes(router) | 50 | api.InitRoutes(router) |
| 47 | // for debugging | ||
| 48 | // router.Use(cors.New(cors.Config{ | ||
| 49 | // AllowOrigins: []string{"*"}, | ||
| 50 | // AllowMethods: []string{"GET", "POST", "DELETE", "PUT", "PATCH"}, | ||
| 51 | // AllowHeaders: []string{"Origin"}, | ||
| 52 | // ExposeHeaders: []string{"Content-Length"}, | ||
| 53 | // AllowCredentials: true, | ||
| 54 | // MaxAge: 12 * time.Hour, | ||
| 55 | // })) | ||
| 56 | // router.Static("/static", "../frontend/build/static") | ||
| 57 | // router.StaticFile("/", "../frontend/build/index.html") | ||
| 58 | // router.NoRoute(func(c *gin.Context) { | ||
| 59 | // c.File("../frontend/build/index.html") | ||
| 60 | // }) | ||
| 61 | router.MaxMultipartMemory = 250 << 20 // 250 mb limit for demos | 51 | router.MaxMultipartMemory = 250 << 20 // 250 mb limit for demos |
| 62 | router.Run(fmt.Sprintf(":%s", os.Getenv("PORT"))) | 52 | router.Run(fmt.Sprintf(":%s", os.Getenv("PORT"))) |
| 63 | } | 53 | } |