From 345fa5d06a47837fca48137163f8a7bdae33cebf Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Sun, 18 Jun 2023 17:08:27 +0300 Subject: feat: improved map summary response (#43) --- backend/controllers/mapController.go | 79 ++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 44 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index d8783b7..37b8e9b 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -3,10 +3,8 @@ package controllers import ( "net/http" "strconv" - "time" "github.com/gin-gonic/gin" - "github.com/lib/pq" "github.com/pektezol/leastportals/backend/database" "github.com/pektezol/leastportals/backend/models" ) @@ -17,37 +15,20 @@ import ( // @Tags maps // @Produce json // @Param id path int true "Map ID" -// @Success 200 {object} models.Response{data=models.Map{data=models.MapSummary}} +// @Success 200 {object} models.Response{data=models.MapSummaryResponse} // @Failure 400 {object} models.Response // @Router /maps/{id}/summary [get] func FetchMapSummary(c *gin.Context) { id := c.Param("id") // Get map data - var mapData models.Map - var mapSummaryData models.MapSummary - var mapHistoryData []models.MapHistory + response := models.MapSummaryResponse{Map: models.Map{}, Summary: models.MapSummary{History: []models.MapHistory{}, Routes: []models.MapRoute{}}} intID, err := strconv.Atoi(id) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - mapData.ID = intID - var routers pq.StringArray - sql := `SELECT g.name, c.name, m.name, m.description, m.showcase, - ( - SELECT array_agg(user_name) - FROM map_routers - WHERE map_id = $1 - AND score_count = ( - SELECT score_count - FROM map_history - WHERE map_id = $1 - ORDER BY score_count - LIMIT 1 - ) - GROUP BY map_routers.user_name - ORDER BY user_name - ), + response.Map.ID = intID + sql := `SELECT m.id, g.name, c.name, m.name, ( SELECT COALESCE(avg(rating), 0.0) FROM map_ratings @@ -57,44 +38,53 @@ func FetchMapSummary(c *gin.Context) { INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id WHERE m.id = $1` - // TODO: CategoryScores - err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &mapSummaryData.Description, &mapSummaryData.Showcase, &routers, &mapSummaryData.Rating) + err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName, &response.Summary.Rating) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - var historyNames pq.StringArray - var historyScores pq.Int32Array - var historyDates pq.StringArray - sql = `SELECT array_agg(user_name), array_agg(score_count), array_agg(record_date) + sql = `SELECT user_name, score_count, record_date FROM map_history - WHERE map_id = $1` - err = database.DB.QueryRow(sql, id).Scan(&historyNames, &historyScores, &historyDates) + WHERE map_id = $1 + ORDER BY record_date ASC` + rows, err := database.DB.Query(sql, id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + for rows.Next() { + history := models.MapHistory{} + err = rows.Scan(&history.RunnerName, &history.ScoreCount, &history.Date) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + response.Summary.History = append(response.Summary.History, history) + } + sql = `SELECT c.id, c.name, mr.score_count, mr.description, mr.showcase + FROM map_routes mr + INNER JOIN categories c ON mr.category_id = c.id + WHERE mr.map_id = $1 + ORDER BY mr.score_count DESC` + rows, err = database.DB.Query(sql, id) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - for i := 0; i < len(historyNames); i++ { - var history models.MapHistory - history.RunnerName = historyNames[i] - history.ScoreCount = int(historyScores[i]) - layout := "2006-01-02 15:04:05" - date, err := time.Parse(layout, historyDates[i]) + for rows.Next() { + route := models.MapRoute{} + err = rows.Scan(&route.Category.ID, &route.Category.Name, &route.ScoreCount, &route.Description, &route.Showcase) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - history.Date = date - mapHistoryData = append(mapHistoryData, history) + response.Summary.Routes = append(response.Summary.Routes, route) } - mapSummaryData.History = mapHistoryData - mapSummaryData.Routers = routers - mapData.Data = mapSummaryData // Return response c.JSON(http.StatusOK, models.Response{ Success: true, Message: "Successfully retrieved map summary.", - Data: mapData, + Data: response, }) } @@ -108,6 +98,7 @@ func FetchMapSummary(c *gin.Context) { // @Failure 400 {object} models.Response // @Router /maps/{id}/leaderboards [get] func FetchMapLeaderboards(c *gin.Context) { + // TODO: make new response type id := c.Param("id") // Get map data var mapData models.Map @@ -205,7 +196,7 @@ func FetchMapLeaderboards(c *gin.Context) { } mapRecordsData.Records = records } - mapData.Data = mapRecordsData + // mapData.Data = mapRecordsData // Return response c.JSON(http.StatusOK, models.Response{ Success: true, -- cgit v1.2.3 From 40537dace937fc96c851c56f0cb629f36dddfd03 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Tue, 20 Jun 2023 19:55:31 +0300 Subject: feat: improved map summary response, all routes init (#43, #46) --- backend/controllers/mapController.go | 52 ++-- backend/database/history.sql | 524 +++++++++++++++++------------------ backend/database/init.sql | 4 + backend/database/route.sql | 279 +++++++++++++++++++ backend/models/models.go | 14 +- 5 files changed, 570 insertions(+), 303 deletions(-) create mode 100644 backend/database/route.sql (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 37b8e9b..e46b766 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -20,60 +20,44 @@ import ( // @Router /maps/{id}/summary [get] func FetchMapSummary(c *gin.Context) { id := c.Param("id") - // Get map data - response := models.MapSummaryResponse{Map: models.Map{}, Summary: models.MapSummary{History: []models.MapHistory{}, Routes: []models.MapRoute{}}} + response := models.MapSummaryResponse{Map: models.Map{}, Summary: models.MapSummary{Routes: []models.MapRoute{}}} intID, err := strconv.Atoi(id) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } + // ( + // SELECT COALESCE(avg(rating), 0.0) + // FROM route_ratings + // WHERE map_id = $1 + // ) + // Get map data response.Map.ID = intID - sql := `SELECT m.id, g.name, c.name, m.name, - ( - SELECT COALESCE(avg(rating), 0.0) - FROM map_ratings - WHERE map_id = $1 - ) + sql := `SELECT m.id, g.name, c.name, m.name FROM maps m INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id WHERE m.id = $1` - err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName, &response.Summary.Rating) + err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - sql = `SELECT user_name, score_count, record_date - FROM map_history - WHERE map_id = $1 - ORDER BY record_date ASC` + // Get map routes and histories + sql = `SELECT c.id, c.name, h.user_name, h.score_count, h.record_date, r.score_count, r.description, r.showcase, COALESCE(avg(rating), 0.0) FROM map_routes r + INNER JOIN categories c ON r.category_id = c.id + INNER JOIN map_history h ON r.map_id = h.map_id AND r.category_id = h.category_id + LEFT JOIN map_ratings rt ON r.map_id = rt.map_id AND r.category_id = rt.category_id + WHERE r.map_id = $1 AND h.score_count = r.score_count GROUP BY c.id, h.user_name, h.score_count, h.record_date, r.score_count, r.description, r.showcase + ORDER BY h.record_date ASC;` rows, err := database.DB.Query(sql, id) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } for rows.Next() { - history := models.MapHistory{} - err = rows.Scan(&history.RunnerName, &history.ScoreCount, &history.Date) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - response.Summary.History = append(response.Summary.History, history) - } - sql = `SELECT c.id, c.name, mr.score_count, mr.description, mr.showcase - FROM map_routes mr - INNER JOIN categories c ON mr.category_id = c.id - WHERE mr.map_id = $1 - ORDER BY mr.score_count DESC` - rows, err = database.DB.Query(sql, id) - if err != nil { - c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) - return - } - for rows.Next() { - route := models.MapRoute{} - err = rows.Scan(&route.Category.ID, &route.Category.Name, &route.ScoreCount, &route.Description, &route.Showcase) + route := models.MapRoute{Category: models.Category{}, History: models.MapHistory{}} + err = rows.Scan(&route.Category.ID, &route.Category.Name, &route.History.RunnerName, &route.History.ScoreCount, &route.History.Date, &route.ScoreCount, &route.Description, &route.Showcase, &route.Rating) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return diff --git a/backend/database/history.sql b/backend/database/history.sql index 0840bf3..d7c4999 100644 --- a/backend/database/history.sql +++ b/backend/database/history.sql @@ -1,279 +1,279 @@ -INSERT INTO map_history(map_id,user_name,score_count,record_date) VALUES +INSERT INTO map_history(map_id,category_id,user_name,score_count,record_date) VALUES -- Portal 2 Singleplayer -- 1 -(3,'slmid1995',3,'2011-10-05 00:00:00'), -(3,'LookLikeAKango',1,'2011-10-06 00:00:00'), -(3,'Bananasaurus Rex',0,'2011-10-24 00:00:00'), -(4,'Tyronis',1,'2011-10-05 00:00:00'), -(4,'Krzyhau',0,'2019-05-10 00:00:00'), -(5,'LookLikeAKango',2,'2011-10-05 00:00:00'), -(5,'Jetwash',1,'2013-12-03 00:00:00'), -(6,'Stimich',4,'2011-10-08 00:00:00'), -(6,'aepaePolakrn',3,'2011-10-19 00:00:00'), -(6,'Krzyhau',2,'2020-10-10 00:00:00'), -(9,'slmid1995',4,'2011-10-05 00:00:00'), -(9,'Jokie',3,'2011-10-05 00:00:00'), -(9,'Tyronis',2,'2011-10-05 00:00:00'), -(9,'sicklebrick',0,'2013-03-13 00:00:00'), +(3,1,'slmid1995',3,'2011-10-05 00:00:00'), +(3,1,'LookLikeAKango',1,'2011-10-06 00:00:00'), +(3,1,'Bananasaurus Rex',0,'2011-10-24 00:00:00'), +(4,1,'Tyronis',1,'2011-10-05 00:00:00'), +(4,1,'Krzyhau',0,'2019-05-10 00:00:00'), +(5,1,'LookLikeAKango',2,'2011-10-05 00:00:00'), +(5,1,'Jetwash',1,'2013-12-03 00:00:00'), +(6,1,'Stimich',4,'2011-10-08 00:00:00'), +(6,1,'aepaePolakrn',3,'2011-10-19 00:00:00'), +(6,1,'Krzyhau',2,'2020-10-10 00:00:00'), +(9,1,'slmid1995',4,'2011-10-05 00:00:00'), +(9,1,'Jokie',3,'2011-10-05 00:00:00'), +(9,1,'Tyronis',2,'2011-10-05 00:00:00'), +(9,1,'sicklebrick',0,'2013-03-13 00:00:00'), -- 2 -(10,'Paraxade0',2,'2011-04-21 00:00:00'), -(10,'PerOculos',0,'2011-04-21 00:00:00'), -(11,'Tyronis',2,'2011-10-05 00:00:00'), -(11,'Krzyhau',0,'2018-06-09 00:00:00'), -(12,'slmid1995',2,'2011-10-04 00:00:00'), -(13,'LookLikeAKango',3,'2011-10-05 00:00:00'), -(13,'Imanex',2,'2011-12-08 00:00:00'), -(13,'jyjey',0,'2012-08-22 00:00:00'), -(15,'Tyronis',2,'2011-10-05 00:00:00'), -(16,'LookLikeAKango',2,'2011-10-05 00:00:00'), -(16,'jyjey',0,'2012-08-25 00:00:00'), -(17,'rocoty',0,'2011-10-05 00:00:00'), -(17,'Nidboj132',0,'2023-02-05 00:00:00'), +(10,1,'Paraxade0',2,'2011-04-21 00:00:00'), +(10,1,'PerOculos',0,'2011-04-21 00:00:00'), +(11,1,'Tyronis',2,'2011-10-05 00:00:00'), +(11,1,'Krzyhau',0,'2018-06-09 00:00:00'), +(12,1,'slmid1995',2,'2011-10-04 00:00:00'), +(13,1,'LookLikeAKango',3,'2011-10-05 00:00:00'), +(13,1,'Imanex',2,'2011-12-08 00:00:00'), +(13,1,'jyjey',0,'2012-08-22 00:00:00'), +(15,1,'Tyronis',2,'2011-10-05 00:00:00'), +(16,1,'LookLikeAKango',2,'2011-10-05 00:00:00'), +(16,1,'jyjey',0,'2012-08-25 00:00:00'), +(17,1,'rocoty',0,'2011-10-05 00:00:00'), +(17,1,'Nidboj132',0,'2023-02-05 00:00:00'), -- 3 -(18,'The Last Tofus',5,'2011-05-08 00:00:00'), -(18,'Schlepian',4,'2011-10-08 00:00:00'), -(18,'szeimartin',3,'2013-10-08 00:00:00'), -(18,'Krzyhau',2,'2020-05-15 00:00:00'), -(18,'Krzyhau',0,'2022-07-02 00:00:00'), -(19,'LookLikeAKango',2,'2011-10-06 00:00:00'), -(20,'Djinndrache',5,'2011-10-20 00:00:00'), -(20,'Schlepian',4,'2011-10-30 00:00:00'), -(20,'Jetwash',3,'2014-09-04 00:00:00'), -(20,'Krzyhau',2,'2022-04-24 00:00:00'), -(21,'LookLikeAKango',4,'2011-10-06 00:00:00'), -(21,'ncla',2,'2011-10-30 00:00:00'), -(21,'PerOculos',0,'2019-07-08 00:00:00'), -(22,'Tyronis',0,'2011-10-05 00:00:00'), -(23,'LookLikeAKango',2,'2011-10-06 00:00:00'), -(23,'Krzyhau',0,'2018-08-01 00:00:00'), -(24,'LeviHB',0,'2011-04-30 00:00:00'), -(25,'Tyronis',0,'2011-10-06 00:00:00'), -(26,'Schlepian',3,'2011-10-30 00:00:00'), -(26,'Tyronis',2,'2012-01-08 00:00:00'), -(26,'PerOculos',0,'2016-06-08 00:00:00'), +(18,1,'The Last Tofus',5,'2011-05-08 00:00:00'), +(18,1,'Schlepian',4,'2011-10-08 00:00:00'), +(18,1,'szeimartin',3,'2013-10-08 00:00:00'), +(18,1,'Krzyhau',2,'2020-05-15 00:00:00'), +(18,1,'Krzyhau',0,'2022-07-02 00:00:00'), +(19,1,'LookLikeAKango',2,'2011-10-06 00:00:00'), +(20,1,'Djinndrache',5,'2011-10-20 00:00:00'), +(20,1,'Schlepian',4,'2011-10-30 00:00:00'), +(20,1,'Jetwash',3,'2014-09-04 00:00:00'), +(20,1,'Krzyhau',2,'2022-04-24 00:00:00'), +(21,1,'LookLikeAKango',4,'2011-10-06 00:00:00'), +(21,1,'ncla',2,'2011-10-30 00:00:00'), +(21,1,'PerOculos',0,'2019-07-08 00:00:00'), +(22,1,'Tyronis',0,'2011-10-05 00:00:00'), +(23,1,'LookLikeAKango',2,'2011-10-06 00:00:00'), +(23,1,'Krzyhau',0,'2018-08-01 00:00:00'), +(24,1,'LeviHB',0,'2011-04-30 00:00:00'), +(25,1,'Tyronis',0,'2011-10-06 00:00:00'), +(26,1,'Schlepian',3,'2011-10-30 00:00:00'), +(26,1,'Tyronis',2,'2012-01-08 00:00:00'), +(26,1,'PerOculos',0,'2016-06-08 00:00:00'), -- 4 -(27,'LeviHB',2,'2011-05-01 00:00:00'), -(27,'PerOculos',0,'2020-07-13 00:00:00'), -(28,'LeviHB',7,'2011-05-01 00:00:00'), -(28,'Andy M.J.',2,'2011-10-07 00:00:00'), -(28,'Krzyhau',0,'2018-05-19 00:00:00'), -(29,'LeviHB',0,'2011-05-01 00:00:00'), -(30,'Schlepian',2,'2011-10-30 00:00:00'), -(31,'Tyronis',0,'2011-10-06 00:00:00'), +(27,1,'LeviHB',2,'2011-05-01 00:00:00'), +(27,1,'PerOculos',0,'2020-07-13 00:00:00'), +(28,1,'LeviHB',7,'2011-05-01 00:00:00'), +(28,1,'Andy M.J.',2,'2011-10-07 00:00:00'), +(28,1,'Krzyhau',0,'2018-05-19 00:00:00'), +(29,1,'LeviHB',0,'2011-05-01 00:00:00'), +(30,1,'Schlepian',2,'2011-10-30 00:00:00'), +(31,1,'Tyronis',0,'2011-10-06 00:00:00'), -- 5 -(32,'Tyronis',6,'2011-10-21 00:00:00'), -(32,'Nidboj132',5,'2022-04-24 00:00:00'), -(33,'Tyronis',7,'2011-10-06 00:00:00'), -(33,'ISimmo',5,'2011-11-02 00:00:00'), -(33,'PerOculos',4,'2017-05-30 00:00:00'), -(34,'Schlepian',3,'2011-11-01 00:00:00'), -(34,'Krzyhau',2,'2020-10-14 00:00:00'), -(34,'zach',0,'2022-11-02 00:00:00'), -(35,'Krank',2,'2012-07-28 00:00:00'), +(32,1,'Tyronis',6,'2011-10-21 00:00:00'), +(32,1,'Nidboj132',5,'2022-04-24 00:00:00'), +(33,1,'Tyronis',7,'2011-10-06 00:00:00'), +(33,1,'ISimmo',5,'2011-11-02 00:00:00'), +(33,1,'PerOculos',4,'2017-05-30 00:00:00'), +(34,1,'Schlepian',3,'2011-11-01 00:00:00'), +(34,1,'Krzyhau',2,'2020-10-14 00:00:00'), +(34,1,'zach',0,'2022-11-02 00:00:00'), +(35,1,'Krank',2,'2012-07-28 00:00:00'), -- 6 -(36,'Tyronis',6,'2011-10-06 00:00:00'), -(36,'CalmlyFrenetic',5,'2011-10-09 00:00:00'), -(36,'sicklebrick',4,'2012-09-13 00:00:00'), -(36,'Nidboj132',2,'2023-03-04 00:00:00'), -(37,'LookLikeAKango',7,'2011-10-06 00:00:00'), -(37,'Schlepian',6,'2011-11-01 00:00:00'), -(37,'Tyronis',5,'2012-01-28 00:00:00'), -(37,'Nidboj132',4,'2021-08-22 00:00:00'), -(38,'Andy M.J.',2,'2011-10-06 00:00:00'), -(38,'Sanguine Dagger',0,'2012-03-19 00:00:00'), -(39,'Lambda Core',6,'2011-05-13 00:00:00'), -(39,'The Last Tofus',5,'2011-05-13 00:00:00'), -(39,'LookLikeAKango',4,'2011-10-16 00:00:00'), -(39,'Kittaye',3,'2013-03-25 00:00:00'), -(40,'LookLikeAKango',7,'2011-10-07 00:00:00'), -(40,'Schlepian',6,'2011-11-05 00:00:00'), -(40,'Kittaye',4,'2013-04-01 00:00:00'), -(40,'Kittaye',3,'2014-09-13 00:00:00'), -(40,'szeimartin',2,'2014-09-13 00:00:00'), -(40,'Kittaye',0,'2014-09-15 00:00:00'), -(41,'CalmlyFrenetic',7,'2011-10-09 00:00:00'), -(41,'Jaso',6,'2011-10-11 00:00:00'), -(41,'Krank',5,'2012-07-17 00:00:00'), +(36,1,'Tyronis',6,'2011-10-06 00:00:00'), +(36,1,'CalmlyFrenetic',5,'2011-10-09 00:00:00'), +(36,1,'sicklebrick',4,'2012-09-13 00:00:00'), +(36,1,'Nidboj132',2,'2023-03-04 00:00:00'), +(37,1,'LookLikeAKango',7,'2011-10-06 00:00:00'), +(37,1,'Schlepian',6,'2011-11-01 00:00:00'), +(37,1,'Tyronis',5,'2012-01-28 00:00:00'), +(37,1,'Nidboj132',4,'2021-08-22 00:00:00'), +(38,1,'Andy M.J.',2,'2011-10-06 00:00:00'), +(38,1,'Sanguine Dagger',0,'2012-03-19 00:00:00'), +(39,1,'Lambda Core',6,'2011-05-13 00:00:00'), +(39,1,'The Last Tofus',5,'2011-05-13 00:00:00'), +(39,1,'LookLikeAKango',4,'2011-10-16 00:00:00'), +(39,1,'Kittaye',3,'2013-03-25 00:00:00'), +(40,1,'LookLikeAKango',7,'2011-10-07 00:00:00'), +(40,1,'Schlepian',6,'2011-11-05 00:00:00'), +(40,1,'Kittaye',4,'2013-04-01 00:00:00'), +(40,1,'Kittaye',3,'2014-09-13 00:00:00'), +(40,1,'szeimartin',2,'2014-09-13 00:00:00'), +(40,1,'Kittaye',0,'2014-09-15 00:00:00'), +(41,1,'CalmlyFrenetic',7,'2011-10-09 00:00:00'), +(41,1,'Jaso',6,'2011-10-11 00:00:00'), +(41,1,'Krank',5,'2012-07-17 00:00:00'), -- 7 -(42,'LookLikeAKango',4,'2011-05-17 00:00:00'), -(42,'ISimmo',2,'2011-11-07 00:00:00'), -(43,'lmao4ever',5,'2011-10-30 00:00:00'), -(43,'Jaso',2,'2011-11-09 00:00:00'), -(43,'feliser',0,'2022-06-26 00:00:00'), -(44,'LookLikeAKango',18,'2011-10-07 00:00:00'), -(44,'Tyronis',13,'2011-10-30 00:00:00'), -(44,'Tyronis',12,'2011-11-10 00:00:00'), -(44,'Jetwash',11,'2017-06-12 00:00:00'), -(44,'Krzyhau',9,'2022-01-02 00:00:00'), -(45,'LookLikeAKango',23,'2011-10-08 00:00:00'), -(45,'CalmlyFrenetic',22,'2011-10-09 00:00:00'), -(45,'cgreactor',17,'2011-10-09 00:00:00'), -(45,'CalmlyFrenetic',16,'2011-10-10 00:00:00'), -(45,'LookLikeAKango',15,'2011-10-19 00:00:00'), -(45,'Jaso',12,'2012-07-19 00:00:00'), -(45,'Krank',10,'2013-01-31 00:00:00'), -(45,'Kittaye',7,'2013-04-04 00:00:00'), -(45,'PerOculos',4,'2014-09-13 00:00:00'), +(42,1,'LookLikeAKango',4,'2011-05-17 00:00:00'), +(42,1,'ISimmo',2,'2011-11-07 00:00:00'), +(43,1,'lmao4ever',5,'2011-10-30 00:00:00'), +(43,1,'Jaso',2,'2011-11-09 00:00:00'), +(43,1,'feliser',0,'2022-06-26 00:00:00'), +(44,1,'LookLikeAKango',18,'2011-10-07 00:00:00'), +(44,1,'Tyronis',13,'2011-10-30 00:00:00'), +(44,1,'Tyronis',12,'2011-11-10 00:00:00'), +(44,1,'Jetwash',11,'2017-06-12 00:00:00'), +(44,1,'Krzyhau',9,'2022-01-02 00:00:00'), +(45,1,'LookLikeAKango',23,'2011-10-08 00:00:00'), +(45,1,'CalmlyFrenetic',22,'2011-10-09 00:00:00'), +(45,1,'cgreactor',17,'2011-10-09 00:00:00'), +(45,1,'CalmlyFrenetic',16,'2011-10-10 00:00:00'), +(45,1,'LookLikeAKango',15,'2011-10-19 00:00:00'), +(45,1,'Jaso',12,'2012-07-19 00:00:00'), +(45,1,'Krank',10,'2013-01-31 00:00:00'), +(45,1,'Kittaye',7,'2013-04-04 00:00:00'), +(45,1,'PerOculos',4,'2014-09-13 00:00:00'), -- 8 -(46,'sparkle1princess',6,'2012-03-24 00:00:00'), -(46,'Krzyhau',2,'2019-11-21 00:00:00'), -(47,'holydevel',2,'2011-10-06 00:00:00'), -(47,'JesusCatFace',0,'2015-01-16 00:00:00'), -(48,'LookLikeAKango',5,'2011-10-08 00:00:00'), -(48,'Tyronis',2,'2011-10-08 00:00:00'), -(48,'adzicents',0,'2011-10-09 00:00:00'), -(49,'adzicents',4,'2011-10-07 00:00:00'), -(49,'Schlepian',2,'2011-10-08 00:00:00'), -(49,'Nidboj132',0,'2022-09-26 00:00:00'), -(50,'LookLikeAKango',4,'2011-10-08 00:00:00'), -(50,'Tyronis',2,'2011-10-11 00:00:00'), -(50,'sicklebrick',0,'2013-03-20 00:00:00'), -(51,'Andy M.J.',3,'2011-10-08 00:00:00'), -(51,'LookLikeAKango',2,'2011-10-20 00:00:00'), -(52,'Jaso',0,'2011-10-10 00:00:00'), -(53,'LookLikeAKango',9,'2011-10-08 00:00:00'), -(53,'LookLikeAKango',2,'2011-10-20 00:00:00'), -(53,'Schlepian',0,'2011-11-06 00:00:00'), -(54,'LookLikeAKango',7,'2011-06-01 00:00:00'), -(54,'Jaso',6,'2011-10-09 00:00:00'), -(54,'Schlepian',5,'2011-11-06 00:00:00'), -(54,'Spyrunite',4,'2012-08-30 00:00:00'), -(54,'Krzyhau',3,'2019-04-22 00:00:00'), -(55,'LookLikeAKango',7,'2011-10-08 00:00:00'), -(55,'CalmlyFrenetic',3,'2011-10-09 00:00:00'), -(55,'Jaso',2,'2011-11-26 00:00:00'), -(55,'PerOculos',0,'2021-02-06 00:00:00'), -(56,'CalmlyFrenetic',9,'2011-10-08 00:00:00'), -(56,'LookLikeAKango',5,'2011-10-09 00:00:00'), -(56,'CalmlyFrenetic',4,'2011-10-09 00:00:00'), -(56,'Jetwash',2,'2014-09-05 00:00:00'), +(46,1,'sparkle1princess',6,'2012-03-24 00:00:00'), +(46,1,'Krzyhau',2,'2019-11-21 00:00:00'), +(47,1,'holydevel',2,'2011-10-06 00:00:00'), +(47,1,'JesusCatFace',0,'2015-01-16 00:00:00'), +(48,1,'LookLikeAKango',5,'2011-10-08 00:00:00'), +(48,1,'Tyronis',2,'2011-10-08 00:00:00'), +(48,1,'adzicents',0,'2011-10-09 00:00:00'), +(49,1,'adzicents',4,'2011-10-07 00:00:00'), +(49,1,'Schlepian',2,'2011-10-08 00:00:00'), +(49,1,'Nidboj132',0,'2022-09-26 00:00:00'), +(50,1,'LookLikeAKango',4,'2011-10-08 00:00:00'), +(50,1,'Tyronis',2,'2011-10-11 00:00:00'), +(50,1,'sicklebrick',0,'2013-03-20 00:00:00'), +(51,1,'Andy M.J.',3,'2011-10-08 00:00:00'), +(51,1,'LookLikeAKango',2,'2011-10-20 00:00:00'), +(52,1,'Jaso',0,'2011-10-10 00:00:00'), +(53,1,'LookLikeAKango',9,'2011-10-08 00:00:00'), +(53,1,'LookLikeAKango',2,'2011-10-20 00:00:00'), +(53,1,'Schlepian',0,'2011-11-06 00:00:00'), +(54,1,'LookLikeAKango',7,'2011-06-01 00:00:00'), +(54,1,'Jaso',6,'2011-10-09 00:00:00'), +(54,1,'Schlepian',5,'2011-11-06 00:00:00'), +(54,1,'Spyrunite',4,'2012-08-30 00:00:00'), +(54,1,'Krzyhau',3,'2019-04-22 00:00:00'), +(55,1,'LookLikeAKango',7,'2011-10-08 00:00:00'), +(55,1,'CalmlyFrenetic',3,'2011-10-09 00:00:00'), +(55,1,'Jaso',2,'2011-11-26 00:00:00'), +(55,1,'PerOculos',0,'2021-02-06 00:00:00'), +(56,1,'CalmlyFrenetic',9,'2011-10-08 00:00:00'), +(56,1,'LookLikeAKango',5,'2011-10-09 00:00:00'), +(56,1,'CalmlyFrenetic',4,'2011-10-09 00:00:00'), +(56,1,'Jetwash',2,'2014-09-05 00:00:00'), -- 9 -(57,'JNS',7,'2011-07-21 00:00:00'), -(57,'Krank',5,'2012-07-29 00:00:00'), -(57,'Krzyhau',0,'2017-10-29 00:00:00'), -(58,'Stimich',2,'2011-10-11 00:00:00'), -(59,'Isimmo',7,'2011-11-04 00:00:00'), -(59,'sicklebrick',6,'2013-03-20 00:00:00'), -(60,'CalmlyFrenetic',7,'2011-10-19 00:00:00'), -(60,'Tyronis',6,'2011-11-01 00:00:00'), +(57,1,'JNS',7,'2011-07-21 00:00:00'), +(57,1,'Krank',5,'2012-07-29 00:00:00'), +(57,1,'Krzyhau',0,'2017-10-29 00:00:00'), +(58,1,'Stimich',2,'2011-10-11 00:00:00'), +(59,1,'Isimmo',7,'2011-11-04 00:00:00'), +(59,1,'sicklebrick',6,'2013-03-20 00:00:00'), +(60,1,'CalmlyFrenetic',7,'2011-10-19 00:00:00'), +(60,1,'Tyronis',6,'2011-11-01 00:00:00'), -- Portal 2 Cooperative -- 1 -(63,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), -(64,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(64,'Chubfish & Exhale',2,'2011-11-01 00:00:00'), -(65,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(65,'Nidboj132 & Oryn',3,'2022-02-03 00:00:00'), -(66,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(66,'Schlepian & Chubfish',2,'2011-10-01 00:00:00'), -(67,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), -(68,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), +(63,1,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), +(64,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(64,1,'Chubfish & Exhale',2,'2011-11-01 00:00:00'), +(65,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(65,1,'Nidboj132 & Oryn',3,'2022-02-03 00:00:00'), +(66,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(66,1,'Schlepian & Chubfish',2,'2011-10-01 00:00:00'), +(67,1,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), +(68,1,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), -- 2 -(69,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(70,'Mathias123961 & Sir Spawn Alot',6,'2011-08-01 00:00:00'), -(70,'Schlepian & Chubfish',4,'2011-10-01 00:00:00'), -(70,'Gocnak & z1mb0bw4y',2,'2012-08-03 00:00:00'), -(70,'DM_ & VEGA',0,'2017-10-01 00:00:00'), -(71,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(71,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), -(72,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(72,'Schlepian & LongJohnDickWeed',2,'2011-10-01 00:00:00'), -(73,'Stimich & HiTMaRkS',9,'2011-05-09 00:00:00'), -(73,'Mathias123961 & Sir Spawn Alot',8,'2011-08-01 00:00:00'), -(73,'Schlepian & Lemonsunshine',7,'2011-11-01 00:00:00'), -(73,'DM_ & LsDK_',6,'2018-01-01 00:00:00'), -(73,'Krzyhau & Klooger',4,'2018-11-01 00:00:00'), -(74,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), -(74,'Stimich & Pitkakorva',7,'2011-10-11 00:00:00'), -(74,'Schlepian & Isimmo',3,'2011-10-28 00:00:00'), -(74,'Zypeh & szeimartin',2,'2013-11-01 00:00:00'), -(75,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), -(75,'Schlepian & Urination',4,'2011-10-01 00:00:00'), -(75,'Schlepian & Lemonsunshine',2,'2012-02-01 00:00:00'), -(75,'DM_ & follon',0,'2015-04-01 00:00:00'), -(76,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(76,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), +(69,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(70,1,'Mathias123961 & Sir Spawn Alot',6,'2011-08-01 00:00:00'), +(70,1,'Schlepian & Chubfish',4,'2011-10-01 00:00:00'), +(70,1,'Gocnak & z1mb0bw4y',2,'2012-08-03 00:00:00'), +(70,1,'DM_ & VEGA',0,'2017-10-01 00:00:00'), +(71,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(71,1,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), +(72,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(72,1,'Schlepian & LongJohnDickWeed',2,'2011-10-01 00:00:00'), +(73,1,'Stimich & HiTMaRkS',9,'2011-05-09 00:00:00'), +(73,1,'Mathias123961 & Sir Spawn Alot',8,'2011-08-01 00:00:00'), +(73,1,'Schlepian & Lemonsunshine',7,'2011-11-01 00:00:00'), +(73,1,'DM_ & LsDK_',6,'2018-01-01 00:00:00'), +(73,1,'Krzyhau & Klooger',4,'2018-11-01 00:00:00'), +(74,1,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), +(74,1,'Stimich & Pitkakorva',7,'2011-10-11 00:00:00'), +(74,1,'Schlepian & Isimmo',3,'2011-10-28 00:00:00'), +(74,1,'Zypeh & szeimartin',2,'2013-11-01 00:00:00'), +(75,1,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), +(75,1,'Schlepian & Urination',4,'2011-10-01 00:00:00'), +(75,1,'Schlepian & Lemonsunshine',2,'2012-02-01 00:00:00'), +(75,1,'DM_ & follon',0,'2015-04-01 00:00:00'), +(76,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(76,1,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), -- 3 -(77,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(78,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(78,'DM_ & marK',3,'2016-11-01 00:00:00'), -(78,'Nidboj132 & Oryn',2,'2021-09-04 00:00:00'), -(79,'ganonscrub & ?',5,'2011-04-01 00:00:00'), -(79,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(79,'Chubfish & Exhale',2,'2012-08-04 00:00:00'), -(80,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), -(80,'Chubfish & Exhale',4,'2011-12-01 00:00:00'), -(81,'Mathias123961 & Sir Spawn Alot',7,'2011-08-01 00:00:00'), -(81,'Schlepian & Lemonsunshine',6,'2011-10-01 00:00:00'), -(81,'takz & dawn',5,'2011-11-01 00:00:00'), -(81,'Nidboj132 & Oryn',4,'2021-03-25 00:00:00'), -(82,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(83,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), -(83,'Schlepian & Lemonsunshine',2,'2011-10-01 00:00:00'), -(83,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), -(84,'Mathias123961 & Sir Spawn Alot',6,'2011-08-01 00:00:00'), -(84,'Schlepian & Chubfish',4,'2011-10-01 00:00:00'), -(84,'Chubfish & Exhale',2,'2012-01-01 00:00:00'), -(84,'DM_ & wS',0,'2015-05-01 00:00:00'), +(77,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(78,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(78,1,'DM_ & marK',3,'2016-11-01 00:00:00'), +(78,1,'Nidboj132 & Oryn',2,'2021-09-04 00:00:00'), +(79,1,'ganonscrub & ?',5,'2011-04-01 00:00:00'), +(79,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(79,1,'Chubfish & Exhale',2,'2012-08-04 00:00:00'), +(80,1,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), +(80,1,'Chubfish & Exhale',4,'2011-12-01 00:00:00'), +(81,1,'Mathias123961 & Sir Spawn Alot',7,'2011-08-01 00:00:00'), +(81,1,'Schlepian & Lemonsunshine',6,'2011-10-01 00:00:00'), +(81,1,'takz & dawn',5,'2011-11-01 00:00:00'), +(81,1,'Nidboj132 & Oryn',4,'2021-03-25 00:00:00'), +(82,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(83,1,'Mathias123961 & Sir Spawn Alot',5,'2011-08-01 00:00:00'), +(83,1,'Schlepian & Lemonsunshine',2,'2011-10-01 00:00:00'), +(83,1,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), +(84,1,'Mathias123961 & Sir Spawn Alot',6,'2011-08-01 00:00:00'), +(84,1,'Schlepian & Chubfish',4,'2011-10-01 00:00:00'), +(84,1,'Chubfish & Exhale',2,'2012-01-01 00:00:00'), +(84,1,'DM_ & wS',0,'2015-05-01 00:00:00'), -- 4 -(85,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(85,'Chubfish & Exhale',0,'2011-10-01 00:00:00'), -(86,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(86,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), -(87,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), -(87,'Schlepian & Gopherdude',2,'2011-10-01 00:00:00'), -(87,'DM_ & follon',0,'2015-04-01 00:00:00'), -(88,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(88,'Schlepian & Gopherdude',0,'2011-10-01 00:00:00'), -(89,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), -(90,'Mathias123961 & Sir Spawn Alot',4,'2011-09-01 00:00:00'), -(90,'Schlepian & Urination',2,'2011-10-01 00:00:00'), -(90,'Klooger & Jetwash',0,'2016-08-01 00:00:00'), -(91,'Mathias123961 & Sir Spawn Alot',2,'2011-08-01 00:00:00'), -(91,'Undead & Zypeh',0,'2013-05-19 00:00:00'), -(92,'txx478 & ?',5,'2011-05-01 00:00:00'), -(92,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), -(92,'Schlepian & Gopherdude',2,'2011-10-01 00:00:00'), -(92,'ncla & takz',0,'2012-02-01 00:00:00'), -(93,'Mathias123961 & Sir Spawn Alot',2,'2011-08-01 00:00:00'), -(93,'Schlepian & Gopherdude',0,'2011-10-01 00:00:00'), +(85,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(85,1,'Chubfish & Exhale',0,'2011-10-01 00:00:00'), +(86,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(86,1,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), +(87,1,'Mathias123961 & Sir Spawn Alot',3,'2011-08-01 00:00:00'), +(87,1,'Schlepian & Gopherdude',2,'2011-10-01 00:00:00'), +(87,1,'DM_ & follon',0,'2015-04-01 00:00:00'), +(88,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(88,1,'Schlepian & Gopherdude',0,'2011-10-01 00:00:00'), +(89,1,'Mathias123961 & Sir Spawn Alot',0,'2011-08-01 00:00:00'), +(90,1,'Mathias123961 & Sir Spawn Alot',4,'2011-09-01 00:00:00'), +(90,1,'Schlepian & Urination',2,'2011-10-01 00:00:00'), +(90,1,'Klooger & Jetwash',0,'2016-08-01 00:00:00'), +(91,1,'Mathias123961 & Sir Spawn Alot',2,'2011-08-01 00:00:00'), +(91,1,'Undead & Zypeh',0,'2013-05-19 00:00:00'), +(92,1,'txx478 & ?',5,'2011-05-01 00:00:00'), +(92,1,'Mathias123961 & Sir Spawn Alot',4,'2011-08-01 00:00:00'), +(92,1,'Schlepian & Gopherdude',2,'2011-10-01 00:00:00'), +(92,1,'ncla & takz',0,'2012-02-01 00:00:00'), +(93,1,'Mathias123961 & Sir Spawn Alot',2,'2011-08-01 00:00:00'), +(93,1,'Schlepian & Gopherdude',0,'2011-10-01 00:00:00'), -- 5 -(94,'Chubfish & Exhale',2,'2011-10-01 00:00:00'), -(94,'Klooger & Imanex',0,'2013-08-01 00:00:00'), -(95,'Schlepian & Issimoi',2,'2011-10-01 00:00:00'), -(96,'ThePortalPatrol & ?',4,'2011-04-01 00:00:00'), -(96,'sparkle1princess & Zypeh',2,'2014-01-01 00:00:00'), -(97,'Stimich & HiTMaRkS',7,'2011-05-13 00:00:00'), -(97,'Schlepian & Lemonsunshine',4,'2011-10-01 00:00:00'), -(97,'DM_ & wS',2,'2014-05-01 00:00:00'), -(98,'Imanex & 00svo',0,'2011-11-01 00:00:00'), -(99,'Schlepian & Gopherdude',3,'2011-10-01 00:00:00'), -(99,'Imanex & Klooger',2,'2013-08-01 00:00:00'), -(99,'DM_ & wS',0,'2015-05-01 00:00:00'), -(100,'Schlepian & Bananasaurus Rex',0,'2011-10-01 00:00:00'), -(101,'Chubfish & Exhale',2,'2011-12-01 00:00:00'), -(101,'DM_ & follon',0,'2015-04-01 00:00:00'), +(94,1,'Chubfish & Exhale',2,'2011-10-01 00:00:00'), +(94,1,'Klooger & Imanex',0,'2013-08-01 00:00:00'), +(95,1,'Schlepian & Issimoi',2,'2011-10-01 00:00:00'), +(96,1,'ThePortalPatrol & ?',4,'2011-04-01 00:00:00'), +(96,1,'sparkle1princess & Zypeh',2,'2014-01-01 00:00:00'), +(97,1,'Stimich & HiTMaRkS',7,'2011-05-13 00:00:00'), +(97,1,'Schlepian & Lemonsunshine',4,'2011-10-01 00:00:00'), +(97,1,'DM_ & wS',2,'2014-05-01 00:00:00'), +(98,1,'Imanex & 00svo',0,'2011-11-01 00:00:00'), +(99,1,'Schlepian & Gopherdude',3,'2011-10-01 00:00:00'), +(99,1,'Imanex & Klooger',2,'2013-08-01 00:00:00'), +(99,1,'DM_ & wS',0,'2015-05-01 00:00:00'), +(100,1,'Schlepian & Bananasaurus Rex',0,'2011-10-01 00:00:00'), +(101,1,'Chubfish & Exhale',2,'2011-12-01 00:00:00'), +(101,1,'DM_ & follon',0,'2015-04-01 00:00:00'), -- 6 -(102,'dawn & takz',3,'2011-11-18 00:00:00'), -(102,'Chubfish & Exhale',2,'2012-01-01 00:00:00'), -(102,'Imanex & Klooger',0,'2013-08-01 00:00:00'), -(103,'Schlepian & Lemonsunshine',0,'2011-10-01 00:00:00'), -(104,'Schlepian & Lemonsunshine',0,'2011-10-01 00:00:00'), -(105,'Blaizerazer & ?',8,'2011-10-01 00:00:00'), -(105,'Schlepian & Lemonsunshine',5,'2011-11-01 00:00:00'), -(105,'Imanex & Klooger',4,'2013-08-01 00:00:00'), -(105,'DM_ & wS',3,'2014-05-01 00:00:00'), -(105,'DM_ & follon',2,'2015-04-01 00:00:00'), -(106,'Schlepian & Bananasaurus Rex',4,'2011-10-01 00:00:00'), -(106,'Gig & takz',3,'2012-06-01 00:00:00'), -(106,'Imanex & Klooger',0,'2013-06-01 00:00:00'), -(107,'Chubfish & Exhale',2,'2011-10-01 00:00:00'), -(107,'DM_ & follon',0,'2015-04-01 00:00:00'), -(108,'DaFox & P',0,'2011-12-01 00:00:00'), -(109,'Schlepian & Tyronis',5,'2011-10-01 00:00:00'), -(109,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), -(110,'Tyronis & mr.bob806',15,'2011-10-01 00:00:00'), -(110,'Schlepian & Chubfish',6,'2011-11-01 00:00:00'), -(110,'00svo & z1mb0bw4y',5,'2012-08-08 00:00:00'), -(110,'00svo & z1mb0bw4y',4,'2012-08-10 00:00:00'), -(110,'Klooger & z1mb0bw4y',2,'2014-02-01 00:00:00'), -(110,'DM_ & follon',0,'2015-04-01 00:00:00'); \ No newline at end of file +(102,1,'dawn & takz',3,'2011-11-18 00:00:00'), +(102,1,'Chubfish & Exhale',2,'2012-01-01 00:00:00'), +(102,1,'Imanex & Klooger',0,'2013-08-01 00:00:00'), +(103,1,'Schlepian & Lemonsunshine',0,'2011-10-01 00:00:00'), +(104,1,'Schlepian & Lemonsunshine',0,'2011-10-01 00:00:00'), +(105,1,'Blaizerazer & ?',8,'2011-10-01 00:00:00'), +(105,1,'Schlepian & Lemonsunshine',5,'2011-11-01 00:00:00'), +(105,1,'Imanex & Klooger',4,'2013-08-01 00:00:00'), +(105,1,'DM_ & wS',3,'2014-05-01 00:00:00'), +(105,1,'DM_ & follon',2,'2015-04-01 00:00:00'), +(106,1,'Schlepian & Bananasaurus Rex',4,'2011-10-01 00:00:00'), +(106,1,'Gig & takz',3,'2012-06-01 00:00:00'), +(106,1,'Imanex & Klooger',0,'2013-06-01 00:00:00'), +(107,1,'Chubfish & Exhale',2,'2011-10-01 00:00:00'), +(107,1,'DM_ & follon',0,'2015-04-01 00:00:00'), +(108,1,'DaFox & P',0,'2011-12-01 00:00:00'), +(109,1,'Schlepian & Tyronis',5,'2011-10-01 00:00:00'), +(109,1,'Chubfish & Exhale',0,'2011-12-01 00:00:00'), +(110,1,'Tyronis & mr.bob806',15,'2011-10-01 00:00:00'), +(110,1,'Schlepian & Chubfish',6,'2011-11-01 00:00:00'), +(110,1,'00svo & z1mb0bw4y',5,'2012-08-08 00:00:00'), +(110,1,'00svo & z1mb0bw4y',4,'2012-08-10 00:00:00'), +(110,1,'Klooger & z1mb0bw4y',2,'2014-02-01 00:00:00'), +(110,1,'DM_ & follon',0,'2015-04-01 00:00:00'); \ No newline at end of file diff --git a/backend/database/init.sql b/backend/database/init.sql index 871aba2..76c3aa6 100644 --- a/backend/database/init.sql +++ b/backend/database/init.sql @@ -54,20 +54,24 @@ CREATE TABLE map_routes ( CREATE TABLE map_history ( id SMALLSERIAL, map_id SMALLINT NOT NULL, + category_id SMALLINT NOT NULL, user_name TEXT NOT NULL, score_count SMALLINT NOT NULL, record_date TIMESTAMP NOT NULL, PRIMARY KEY (id), + FOREIGN KEY (category_id) REFERENCES categories(id), FOREIGN KEY (map_id) REFERENCES maps(id) ); CREATE TABLE map_ratings ( id SERIAL, map_id SMALLINT NOT NULL, + category_id SMALLINT NOT NULL, user_id TEXT NOT NULL, rating SMALLINT NOT NULL, PRIMARY KEY (id), FOREIGN KEY (map_id) REFERENCES maps(id), + FOREIGN KEY (category_id) REFERENCES categories(id), FOREIGN KEY (user_id) REFERENCES users(steam_id) ); diff --git a/backend/database/route.sql b/backend/database/route.sql new file mode 100644 index 0000000..6f090c7 --- /dev/null +++ b/backend/database/route.sql @@ -0,0 +1,279 @@ +INSERT INTO map_routes(map_id,category_id,score_count,description,showcase) VALUES +-- Portal 2 Singleplayer +-- 1 +(3,1,3,'',''), +(3,1,1,'',''), +(3,1,0,'',''), +(4,1,1,'',''), +(4,1,0,'',''), +(5,1,2,'',''), +(5,1,1,'',''), +(6,1,4,'',''), +(6,1,3,'',''), +(6,1,2,'',''), +(9,1,4,'',''), +(9,1,3,'',''), +(9,1,2,'',''), +(9,1,0,'',''), +-- 2 +(10,1,2,'',''), +(10,1,0,'',''), +(11,1,2,'',''), +(11,1,0,'',''), +(12,1,2,'',''), +(13,1,3,'',''), +(13,1,2,'',''), +(13,1,0,'',''), +(15,1,2,'',''), +(16,1,2,'',''), +(16,1,0,'',''), +(17,1,0,'',''), +(17,1,0,'',''), +-- 3 +(18,1,5,'',''), +(18,1,4,'',''), +(18,1,3,'',''), +(18,1,2,'',''), +(18,1,0,'',''), +(19,1,2,'',''), +(20,1,5,'',''), +(20,1,4,'',''), +(20,1,3,'',''), +(20,1,2,'',''), +(21,1,4,'',''), +(21,1,2,'',''), +(21,1,0,'',''), +(22,1,0,'',''), +(23,1,2,'',''), +(23,1,0,'',''), +(24,1,0,'',''), +(25,1,0,'',''), +(26,1,3,'',''), +(26,1,2,'',''), +(26,1,0,'',''), +-- 4 +(27,1,2,'',''), +(27,1,0,'',''), +(28,1,7,'',''), +(28,1,2,'',''), +(28,1,0,'',''), +(29,1,0,'',''), +(30,1,2,'',''), +(31,1,0,'',''), +-- 5 +(32,1,6,'',''), +(32,1,5,'',''), +(33,1,7,'',''), +(33,1,5,'',''), +(33,1,4,'',''), +(34,1,3,'',''), +(34,1,2,'',''), +(34,1,0,'',''), +(35,1,2,'',''), +-- 6 +(36,1,6,'',''), +(36,1,5,'',''), +(36,1,4,'',''), +(36,1,2,'',''), +(37,1,7,'',''), +(37,1,6,'',''), +(37,1,5,'',''), +(37,1,4,'',''), +(38,1,2,'',''), +(38,1,0,'',''), +(39,1,6,'',''), +(39,1,5,'',''), +(39,1,4,'',''), +(39,1,3,'',''), +(40,1,7,'',''), +(40,1,6,'',''), +(40,1,4,'',''), +(40,1,3,'',''), +(40,1,2,'',''), +(40,1,0,'',''), +(41,1,7,'',''), +(41,1,6,'',''), +(41,1,5,'',''), +-- 7 +(42,1,4,'',''), +(42,1,2,'',''), +(43,1,5,'',''), +(43,1,2,'',''), +(43,1,0,'',''), +(44,1,18,'',''), +(44,1,13,'',''), +(44,1,12,'',''), +(44,1,11,'',''), +(44,1,9,'',''), +(45,1,23,'',''), +(45,1,22,'',''), +(45,1,17,'',''), +(45,1,16,'',''), +(45,1,15,'',''), +(45,1,12,'',''), +(45,1,10,'',''), +(45,1,7,'',''), +(45,1,4,'',''), +-- 8 +(46,1,6,'',''), +(46,1,2,'',''), +(47,1,2,'',''), +(47,1,0,'',''), +(48,1,5,'',''), +(48,1,2,'',''), +(48,1,0,'',''), +(49,1,4,'',''), +(49,1,2,'',''), +(49,1,0,'',''), +(50,1,4,'',''), +(50,1,2,'',''), +(50,1,0,'',''), +(51,1,3,'',''), +(51,1,2,'',''), +(52,1,0,'',''), +(53,1,9,'',''), +(53,1,2,'',''), +(53,1,0,'',''), +(54,1,7,'',''), +(54,1,6,'',''), +(54,1,5,'',''), +(54,1,4,'',''), +(54,1,3,'',''), +(55,1,7,'',''), +(55,1,3,'',''), +(55,1,2,'',''), +(55,1,0,'',''), +(56,1,9,'',''), +(56,1,5,'',''), +(56,1,4,'',''), +(56,1,2,'',''), +-- 9 +(57,1,7,'',''), +(57,1,5,'',''), +(57,1,0,'',''), +(58,1,2,'',''), +(59,1,7,'',''), +(59,1,6,'',''), +(60,1,7,'',''), +(60,1,6,'',''), +-- Portal 2 Cooperative +-- 1 +(63,1,0,'',''), +(64,1,3,'',''), +(64,1,2,'',''), +(65,1,4,'',''), +(65,1,3,'',''), +(66,1,3,'',''), +(66,1,2,'',''), +(67,1,0,'',''), +(68,1,0,'',''), +-- 2 +(69,1,4,'',''), +(70,1,6,'',''), +(70,1,4,'',''), +(70,1,2,'',''), +(70,1,0,'',''), +(71,1,3,'',''), +(71,1,0,'',''), +(72,1,4,'',''), +(72,1,2,'',''), +(73,1,9,'',''), +(73,1,8,'',''), +(73,1,7,'',''), +(73,1,6,'',''), +(73,1,4,'',''), +(74,1,5,'',''), +(74,1,7,'',''), +(74,1,3,'',''), +(74,1,2,'',''), +(75,1,5,'',''), +(75,1,4,'',''), +(75,1,2,'',''), +(75,1,0,'',''), +(76,1,3,'',''), +(76,1,0,'',''), +-- 3 +(77,1,3,'',''), +(78,1,4,'',''), +(78,1,3,'',''), +(78,1,2,'',''), +(79,1,5,'',''), +(79,1,4,'',''), +(79,1,2,'',''), +(80,1,5,'',''), +(80,1,4,'',''), +(81,1,7,'',''), +(81,1,6,'',''), +(81,1,5,'',''), +(81,1,4,'',''), +(82,1,4,'',''), +(83,1,5,'',''), +(83,1,2,'',''), +(83,1,0,'',''), +(84,1,6,'',''), +(84,1,4,'',''), +(84,1,2,'',''), +(84,1,0,'',''), +-- 4 +(85,1,3,'',''), +(85,1,0,'',''), +(86,1,3,'',''), +(86,1,0,'',''), +(87,1,3,'',''), +(87,1,2,'',''), +(87,1,0,'',''), +(88,1,4,'',''), +(88,1,0,'',''), +(89,1,0,'',''), +(90,1,4,'',''), +(90,1,2,'',''), +(90,1,0,'',''), +(91,1,2,'',''), +(91,1,0,'',''), +(92,1,5,'',''), +(92,1,4,'',''), +(92,1,2,'',''), +(92,1,0,'',''), +(93,1,2,'',''), +(93,1,0,'',''), +-- 5 +(94,1,2,'',''), +(94,1,0,'',''), +(95,1,2,'',''), +(96,1,4,'',''), +(96,1,2,'',''), +(97,1,7,'',''), +(97,1,4,'',''), +(97,1,2,'',''), +(98,1,0,'',''), +(99,1,3,'',''), +(99,1,2,'',''), +(99,1,0,'',''), +(100,1,0,'',''), +(101,1,2,'',''), +(101,1,0,'',''), +-- 6 +(102,1,3,'',''), +(102,1,2,'',''), +(102,1,0,'',''), +(103,1,0,'',''), +(104,1,0,'',''), +(105,1,8,'',''), +(105,1,5,'',''), +(105,1,4,'',''), +(105,1,3,'',''), +(105,1,2,'',''), +(106,1,4,'',''), +(106,1,3,'',''), +(106,1,0,'',''), +(107,1,2,'',''), +(107,1,0,'',''), +(108,1,0,'',''), +(109,1,5,'',''), +(109,1,0,'',''), +(110,1,15,'',''), +(110,1,6,'',''), +(110,1,5,'',''), +(110,1,4,'',''), +(110,1,2,'',''), +(110,1,0,'',''); \ No newline at end of file diff --git a/backend/models/models.go b/backend/models/models.go index 5c9b8f8..783c339 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -31,9 +31,7 @@ type MapShort struct { } type MapSummary struct { - Rating float32 `json:"rating"` - History []MapHistory `json:"history"` - Routes []MapRoute `json:"routes"` + Routes []MapRoute `json:"routes"` } type MapHistory struct { @@ -43,10 +41,12 @@ type MapHistory struct { } type MapRoute struct { - Category Category `json:"category"` - ScoreCount int `json:"score_count"` - Description string `json:"description"` - Showcase string `json:"showcase"` + Category Category `json:"category"` + History MapHistory `json:"history"` + Rating float32 `json:"rating"` + ScoreCount int `json:"score_count"` + Description string `json:"description"` + Showcase string `json:"showcase"` } type MapRecords struct { -- cgit v1.2.3 From 9af2c7d17f02be98998d388b421b3d055a96f83e Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Tue, 20 Jun 2023 20:57:10 +0300 Subject: fix: remove duplicate score count in routes (#46) --- backend/controllers/mapController.go | 11 +++-------- backend/models/models.go | 1 - docs/docs.go | 3 --- docs/swagger.json | 3 --- docs/swagger.yaml | 2 -- 5 files changed, 3 insertions(+), 17 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index e46b766..b5984dc 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -26,11 +26,6 @@ func FetchMapSummary(c *gin.Context) { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } - // ( - // SELECT COALESCE(avg(rating), 0.0) - // FROM route_ratings - // WHERE map_id = $1 - // ) // Get map data response.Map.ID = intID sql := `SELECT m.id, g.name, c.name, m.name @@ -44,11 +39,11 @@ func FetchMapSummary(c *gin.Context) { return } // Get map routes and histories - sql = `SELECT c.id, c.name, h.user_name, h.score_count, h.record_date, r.score_count, r.description, r.showcase, COALESCE(avg(rating), 0.0) FROM map_routes r + sql = `SELECT c.id, c.name, h.user_name, h.score_count, h.record_date, r.description, r.showcase, COALESCE(avg(rating), 0.0) FROM map_routes r INNER JOIN categories c ON r.category_id = c.id INNER JOIN map_history h ON r.map_id = h.map_id AND r.category_id = h.category_id LEFT JOIN map_ratings rt ON r.map_id = rt.map_id AND r.category_id = rt.category_id - WHERE r.map_id = $1 AND h.score_count = r.score_count GROUP BY c.id, h.user_name, h.score_count, h.record_date, r.score_count, r.description, r.showcase + WHERE r.map_id = $1 AND h.score_count = r.score_count GROUP BY c.id, h.user_name, h.score_count, h.record_date, r.description, r.showcase ORDER BY h.record_date ASC;` rows, err := database.DB.Query(sql, id) if err != nil { @@ -57,7 +52,7 @@ func FetchMapSummary(c *gin.Context) { } for rows.Next() { route := models.MapRoute{Category: models.Category{}, History: models.MapHistory{}} - err = rows.Scan(&route.Category.ID, &route.Category.Name, &route.History.RunnerName, &route.History.ScoreCount, &route.History.Date, &route.ScoreCount, &route.Description, &route.Showcase, &route.Rating) + err = rows.Scan(&route.Category.ID, &route.Category.Name, &route.History.RunnerName, &route.History.ScoreCount, &route.History.Date, &route.Description, &route.Showcase, &route.Rating) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return diff --git a/backend/models/models.go b/backend/models/models.go index 783c339..0727468 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -44,7 +44,6 @@ type MapRoute struct { Category Category `json:"category"` History MapHistory `json:"history"` Rating float32 `json:"rating"` - ScoreCount int `json:"score_count"` Description string `json:"description"` Showcase string `json:"showcase"` } diff --git a/docs/docs.go b/docs/docs.go index b7dc7ab..a0aad6f 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -914,9 +914,6 @@ const docTemplate = `{ "rating": { "type": "number" }, - "score_count": { - "type": "integer" - }, "showcase": { "type": "string" } diff --git a/docs/swagger.json b/docs/swagger.json index ffcf55a..2279ff6 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -907,9 +907,6 @@ "rating": { "type": "number" }, - "score_count": { - "type": "integer" - }, "showcase": { "type": "string" } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 3dfe421..ba4775a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -78,8 +78,6 @@ definitions: $ref: '#/definitions/models.MapHistory' rating: type: number - score_count: - type: integer showcase: type: string type: object -- cgit v1.2.3 From 1d69debc7a54360b4682af43a5ad93420f5649ba Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 28 Jun 2023 13:24:15 +0300 Subject: feat: image field for maps Former-commit-id: 374fecd1ef73854c96dd4b80c584ddb823e6e1ba --- backend/controllers/mapController.go | 8 ++++---- backend/models/models.go | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index b5984dc..77f8e10 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -28,12 +28,12 @@ func FetchMapSummary(c *gin.Context) { } // Get map data response.Map.ID = intID - sql := `SELECT m.id, g.name, c.name, m.name + sql := `SELECT m.id, g.name, c.name, m.name, m.image FROM maps m INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id WHERE m.id = $1` - err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName) + err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName, &response.Map.Image) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return @@ -89,12 +89,12 @@ func FetchMapLeaderboards(c *gin.Context) { return } mapData.ID = intID - sql := `SELECT g.name, c.name, m.name, is_disabled + sql := `SELECT g.name, c.name, m.name, is_disabled, m.image FROM maps m INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id WHERE m.id = $1` - err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &isDisabled) + err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &isDisabled, &mapData.Image) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return diff --git a/backend/models/models.go b/backend/models/models.go index 0727468..7b8cbc4 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -23,6 +23,7 @@ type Map struct { GameName string `json:"game_name"` ChapterName string `json:"chapter_name"` MapName string `json:"map_name"` + Image string `json:"image"` } type MapShort struct { -- cgit v1.2.3 From 85c6da965ec401dabb162df09160b4ce9dc28413 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 29 Jun 2023 11:57:53 +0300 Subject: feat: route id in map summary, update docs Former-commit-id: f8db004d2c17f09f665e51ec4e730418248bfd07 --- backend/controllers/mapController.go | 4 ++-- backend/controllers/modController.go | 7 ++++--- backend/controllers/recordController.go | 5 ++--- backend/models/models.go | 1 + docs/docs.go | 9 +++++++++ docs/swagger.json | 9 +++++++++ docs/swagger.yaml | 6 ++++++ 7 files changed, 33 insertions(+), 8 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 77f8e10..7dfd2be 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -39,7 +39,7 @@ func FetchMapSummary(c *gin.Context) { return } // Get map routes and histories - sql = `SELECT c.id, c.name, h.user_name, h.score_count, h.record_date, r.description, r.showcase, COALESCE(avg(rating), 0.0) FROM map_routes r + sql = `SELECT r.id, c.id, c.name, h.user_name, h.score_count, h.record_date, r.description, r.showcase, COALESCE(avg(rating), 0.0) FROM map_routes r INNER JOIN categories c ON r.category_id = c.id INNER JOIN map_history h ON r.map_id = h.map_id AND r.category_id = h.category_id LEFT JOIN map_ratings rt ON r.map_id = rt.map_id AND r.category_id = rt.category_id @@ -52,7 +52,7 @@ func FetchMapSummary(c *gin.Context) { } for rows.Next() { route := models.MapRoute{Category: models.Category{}, History: models.MapHistory{}} - err = rows.Scan(&route.Category.ID, &route.Category.Name, &route.History.RunnerName, &route.History.ScoreCount, &route.History.Date, &route.Description, &route.Showcase, &route.Rating) + err = rows.Scan(&route.RouteID, &route.Category.ID, &route.Category.Name, &route.History.RunnerName, &route.History.ScoreCount, &route.History.Date, &route.Description, &route.Showcase, &route.Rating) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index ebf1cb7..9d14f92 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -14,9 +14,10 @@ import ( // @Summary Edit map summary with specified map id. // @Tags maps // @Produce json -// @Param id path int true "Map ID" -// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} -// @Failure 400 {object} models.Response +// @Param id path int true "Map ID" +// @Param request body models.EditMapSummaryRequest true "Body" +// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} +// @Failure 400 {object} models.Response // @Router /maps/{id}/summary [put] func EditMapSummary(c *gin.Context) { // Check if user exists diff --git a/backend/controllers/recordController.go b/backend/controllers/recordController.go index aec31bb..c865bfb 100644 --- a/backend/controllers/recordController.go +++ b/backend/controllers/recordController.go @@ -30,7 +30,7 @@ import ( // @Param partner_demo formData file true "Partner Demo" // @Param is_partner_orange formData boolean true "Is Partner Orange" // @Param partner_id formData string true "Partner ID" -// @Success 200 {object} models.Response{data=models.RecordRequest} +// @Success 200 {object} models.Response // @Failure 400 {object} models.Response // @Failure 401 {object} models.Response // @Router /maps/{id}/record [post] @@ -179,9 +179,8 @@ func CreateRecordWithDemo(c *gin.Context) { c.JSON(http.StatusOK, models.Response{ Success: true, Message: "Successfully created record.", - Data: record, + Data: nil, }) - return } // GET Demo diff --git a/backend/models/models.go b/backend/models/models.go index 5355a9f..2524935 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -43,6 +43,7 @@ type MapHistory struct { } type MapRoute struct { + RouteID int `json:"route_id"` Category Category `json:"category"` History MapHistory `json:"history"` Rating float32 `json:"rating"` diff --git a/docs/docs.go b/docs/docs.go index 090d3e8..91f91ef 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -467,6 +467,15 @@ const docTemplate = `{ "name": "id", "in": "path", "required": true + }, + { + "description": "Body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.EditMapSummaryRequest" + } } ], "responses": { diff --git a/docs/swagger.json b/docs/swagger.json index 62079b1..c6bbfbc 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -460,6 +460,15 @@ "name": "id", "in": "path", "required": true + }, + { + "description": "Body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.EditMapSummaryRequest" + } } ], "responses": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 9d58620..4291cfc 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -480,6 +480,12 @@ paths: name: id required: true type: integer + - description: Body + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.EditMapSummaryRequest' produces: - application/json responses: -- cgit v1.2.3 From 211f1b48372c0c1885141d1ab214ab7418520008 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:41:47 +0300 Subject: fix: map summary sql Former-commit-id: 3edddea55add68a877d2dbdfcaf3e83f774da775 --- backend/controllers/mapController.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 7dfd2be..7a26554 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -43,7 +43,7 @@ func FetchMapSummary(c *gin.Context) { INNER JOIN categories c ON r.category_id = c.id INNER JOIN map_history h ON r.map_id = h.map_id AND r.category_id = h.category_id LEFT JOIN map_ratings rt ON r.map_id = rt.map_id AND r.category_id = rt.category_id - WHERE r.map_id = $1 AND h.score_count = r.score_count GROUP BY c.id, h.user_name, h.score_count, h.record_date, r.description, r.showcase + WHERE r.map_id = $1 AND h.score_count = r.score_count GROUP BY r.id, c.id, h.user_name, h.score_count, h.record_date, r.description, r.showcase ORDER BY h.record_date ASC;` rows, err := database.DB.Query(sql, id) if err != nil { -- cgit v1.2.3 From c071eeca829a18941fc29f4e4eb8b8f93a65b5c4 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Mon, 3 Jul 2023 23:16:42 +0300 Subject: docs: refactor docs Former-commit-id: 3f3833af352d8758ca509a4fe3badedd5250b1ba --- backend/controllers/homeController.go | 26 ++++---- backend/controllers/loginController.go | 38 +++++------ backend/controllers/mapController.go | 68 +++++++++---------- backend/controllers/modController.go | 54 +++++++-------- backend/controllers/recordController.go | 44 ++++++------- backend/controllers/userController.go | 74 ++++++++++----------- docs/docs.go | 112 ++++++++++++++++---------------- docs/swagger.json | 112 ++++++++++++++++---------------- docs/swagger.yaml | 80 +++++++++++------------ 9 files changed, 304 insertions(+), 304 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/homeController.go b/backend/controllers/homeController.go index b5c6b60..2780e63 100644 --- a/backend/controllers/homeController.go +++ b/backend/controllers/homeController.go @@ -23,12 +23,12 @@ func Home(c *gin.Context) { // GET Rankings // -// @Summary Get rankings of every player. -// @Tags rankings -// @Produce json -// @Success 200 {object} models.Response{data=models.RankingsResponse} -// @Failure 400 {object} models.Response -// @Router /demo [get] +// @Description Get rankings of every player. +// @Tags rankings +// @Produce json +// @Success 200 {object} models.Response{data=models.RankingsResponse} +// @Failure 400 {object} models.Response +// @Router /rankings [get] func Rankings(c *gin.Context) { rows, err := database.DB.Query(`SELECT steam_id, user_name FROM users`) if err != nil { @@ -125,13 +125,13 @@ func Rankings(c *gin.Context) { // GET Search With Query // -// @Summary Get all user and map data matching to the query. -// @Tags search -// @Produce json -// @Param q query string false "Search user or map name." -// @Success 200 {object} models.Response{data=models.SearchResponse} -// @Failure 400 {object} models.Response -// @Router /search [get] +// @Description Get all user and map data matching to the query. +// @Tags search +// @Produce json +// @Param q query string false "Search user or map name." +// @Success 200 {object} models.Response{data=models.SearchResponse} +// @Failure 400 {object} models.Response +// @Router /search [get] func SearchWithQuery(c *gin.Context) { query := c.Query("q") query = strings.ToLower(query) diff --git a/backend/controllers/loginController.go b/backend/controllers/loginController.go index b30d26e..ae6e957 100644 --- a/backend/controllers/loginController.go +++ b/backend/controllers/loginController.go @@ -17,13 +17,13 @@ import ( // Login // -// @Summary Get (redirect) login page for Steam auth. -// @Tags login -// @Accept json -// @Produce json -// @Success 200 {object} models.Response{data=models.LoginResponse} -// @Failure 400 {object} models.Response -// @Router /login [get] +// @Description Get (redirect) login page for Steam auth. +// @Tags login +// @Accept json +// @Produce json +// @Success 200 {object} models.Response{data=models.LoginResponse} +// @Failure 400 {object} models.Response +// @Router /login [get] func Login(c *gin.Context) { openID := steam_go.NewOpenId(c.Request) switch openID.Mode() { @@ -95,13 +95,13 @@ func Login(c *gin.Context) { // GET Token // -// @Summary Gets the token cookie value from the user. -// @Tags auth -// @Produce json +// @Description Gets the token cookie value from the user. +// @Tags auth +// @Produce json // -// @Success 200 {object} models.Response{data=models.LoginResponse} -// @Failure 404 {object} models.Response -// @Router /token [get] +// @Success 200 {object} models.Response{data=models.LoginResponse} +// @Failure 404 {object} models.Response +// @Router /token [get] func GetCookie(c *gin.Context) { cookie, err := c.Cookie("token") if err != nil { @@ -119,13 +119,13 @@ func GetCookie(c *gin.Context) { // DELETE Token // -// @Summary Deletes the token cookie from the user. -// @Tags auth -// @Produce json +// @Description Deletes the token cookie from the user. +// @Tags auth +// @Produce json // -// @Success 200 {object} models.Response{data=models.LoginResponse} -// @Failure 404 {object} models.Response -// @Router /token [delete] +// @Success 200 {object} models.Response{data=models.LoginResponse} +// @Failure 404 {object} models.Response +// @Router /token [delete] func DeleteCookie(c *gin.Context) { cookie, err := c.Cookie("token") if err != nil { diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 7a26554..52b6623 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -11,13 +11,13 @@ import ( // GET Map Summary // -// @Summary Get map summary with specified id. -// @Tags maps -// @Produce json -// @Param id path int true "Map ID" -// @Success 200 {object} models.Response{data=models.MapSummaryResponse} -// @Failure 400 {object} models.Response -// @Router /maps/{id}/summary [get] +// @Description Get map summary with specified id. +// @Tags maps +// @Produce json +// @Param id path int true "Map ID" +// @Success 200 {object} models.Response{data=models.MapSummaryResponse} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [get] func FetchMapSummary(c *gin.Context) { id := c.Param("id") response := models.MapSummaryResponse{Map: models.Map{}, Summary: models.MapSummary{Routes: []models.MapRoute{}}} @@ -69,13 +69,13 @@ func FetchMapSummary(c *gin.Context) { // GET Map Leaderboards // -// @Summary Get map leaderboards with specified id. -// @Tags maps -// @Produce json -// @Param id path int true "Map ID" -// @Success 200 {object} models.Response{data=models.Map{data=models.MapRecords}} -// @Failure 400 {object} models.Response -// @Router /maps/{id}/leaderboards [get] +// @Description Get map leaderboards with specified id. +// @Tags maps +// @Produce json +// @Param id path int true "Map ID" +// @Success 200 {object} models.Response{data=models.Map{data=models.MapRecords}} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/leaderboards [get] func FetchMapLeaderboards(c *gin.Context) { // TODO: make new response type id := c.Param("id") @@ -186,12 +186,12 @@ func FetchMapLeaderboards(c *gin.Context) { // GET Games // -// @Summary Get games from the leaderboards. -// @Tags games & chapters -// @Produce json -// @Success 200 {object} models.Response{data=[]models.Game} -// @Failure 400 {object} models.Response -// @Router /games [get] +// @Description Get games from the leaderboards. +// @Tags games & chapters +// @Produce json +// @Success 200 {object} models.Response{data=[]models.Game} +// @Failure 400 {object} models.Response +// @Router /games [get] func FetchGames(c *gin.Context) { rows, err := database.DB.Query(`SELECT id, name FROM games`) if err != nil { @@ -216,13 +216,13 @@ func FetchGames(c *gin.Context) { // GET Chapters of a Game // -// @Summary Get chapters from the specified game id. -// @Tags games & chapters -// @Produce json -// @Param id path int true "Game ID" -// @Success 200 {object} models.Response{data=models.ChaptersResponse} -// @Failure 400 {object} models.Response -// @Router /games/{id} [get] +// @Description Get chapters from the specified game id. +// @Tags games & chapters +// @Produce json +// @Param id path int true "Game ID" +// @Success 200 {object} models.Response{data=models.ChaptersResponse} +// @Failure 400 {object} models.Response +// @Router /games/{id} [get] func FetchChapters(c *gin.Context) { gameID := c.Param("id") intID, err := strconv.Atoi(gameID) @@ -258,13 +258,13 @@ func FetchChapters(c *gin.Context) { // GET Maps of a Chapter // -// @Summary Get maps from the specified chapter id. -// @Tags games & chapters -// @Produce json -// @Param id path int true "Chapter ID" -// @Success 200 {object} models.Response{data=models.ChapterMapsResponse} -// @Failure 400 {object} models.Response -// @Router /chapters/{id} [get] +// @Description Get maps from the specified chapter id. +// @Tags games & chapters +// @Produce json +// @Param id path int true "Chapter ID" +// @Success 200 {object} models.Response{data=models.ChapterMapsResponse} +// @Failure 400 {object} models.Response +// @Router /chapters/{id} [get] func FetchChapterMaps(c *gin.Context) { chapterID := c.Param("id") intID, err := strconv.Atoi(chapterID) diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index f1874f7..d6dc4d4 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go @@ -11,15 +11,15 @@ import ( // POST Map Summary // -// @Summary Create map summary with specified map id. -// @Tags maps -// @Produce json -// @Param Authorization header string true "JWT Token" -// @Param id path int true "Map ID" -// @Param request body models.CreateMapSummaryRequest true "Body" -// @Success 200 {object} models.Response{data=models.CreateMapSummaryRequest} -// @Failure 400 {object} models.Response -// @Router /maps/{id}/summary [post] +// @Description Create map summary with specified map id. +// @Tags maps +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param id path int true "Map ID" +// @Param request body models.CreateMapSummaryRequest true "Body" +// @Success 200 {object} models.Response{data=models.CreateMapSummaryRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [post] func CreateMapSummary(c *gin.Context) { // Check if user exists user, exists := c.Get("user") @@ -97,15 +97,15 @@ func CreateMapSummary(c *gin.Context) { // PUT Map Summary // -// @Summary Edit map summary with specified map id. -// @Tags maps -// @Produce json -// @Param Authorization header string true "JWT Token" -// @Param id path int true "Map ID" -// @Param request body models.EditMapSummaryRequest true "Body" -// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} -// @Failure 400 {object} models.Response -// @Router /maps/{id}/summary [put] +// @Description Edit map summary with specified map id. +// @Tags maps +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param id path int true "Map ID" +// @Param request body models.EditMapSummaryRequest true "Body" +// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [put] func EditMapSummary(c *gin.Context) { // Check if user exists user, exists := c.Get("user") @@ -180,15 +180,15 @@ func EditMapSummary(c *gin.Context) { // DELETE Map Summary // -// @Summary Delete map summary with specified map id. -// @Tags maps -// @Produce json -// @Param Authorization header string true "JWT Token" -// @Param id path int true "Map ID" -// @Param request body models.DeleteMapSummaryRequest true "Body" -// @Success 200 {object} models.Response{data=models.DeleteMapSummaryRequest} -// @Failure 400 {object} models.Response -// @Router /maps/{id}/summary [delete] +// @Description Delete map summary with specified map id. +// @Tags maps +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param id path int true "Map ID" +// @Param request body models.DeleteMapSummaryRequest true "Body" +// @Success 200 {object} models.Response{data=models.DeleteMapSummaryRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [delete] func DeleteMapSummary(c *gin.Context) { // Check if user exists user, exists := c.Get("user") diff --git a/backend/controllers/recordController.go b/backend/controllers/recordController.go index 409a2e7..af8eb63 100644 --- a/backend/controllers/recordController.go +++ b/backend/controllers/recordController.go @@ -21,20 +21,20 @@ import ( // POST Record // -// @Summary Post record with demo of a specific map. -// @Tags maps -// @Accept mpfd -// @Produce json -// @Param id path int true "Map ID" -// @Param Authorization header string true "JWT Token" -// @Param host_demo formData file true "Host Demo" -// @Param partner_demo formData file false "Partner Demo" -// @Param is_partner_orange formData boolean false "Is Partner Orange" -// @Param partner_id formData string false "Partner ID" -// @Success 200 {object} models.Response -// @Failure 400 {object} models.Response -// @Failure 401 {object} models.Response -// @Router /maps/{id}/record [post] +// @Description Post record with demo of a specific map. +// @Tags maps +// @Accept mpfd +// @Produce json +// @Param id path int true "Map ID" +// @Param Authorization header string true "JWT Token" +// @Param host_demo formData file true "Host Demo" +// @Param partner_demo formData file false "Partner Demo" +// @Param is_partner_orange formData boolean false "Is Partner Orange" +// @Param partner_id formData string false "Partner ID" +// @Success 200 {object} models.Response +// @Failure 400 {object} models.Response +// @Failure 401 {object} models.Response +// @Router /maps/{id}/record [post] func CreateRecordWithDemo(c *gin.Context) { mapId := c.Param("id") // Check if user exists @@ -189,14 +189,14 @@ func CreateRecordWithDemo(c *gin.Context) { // GET Demo // -// @Summary Get demo with specified demo uuid. -// @Tags demo -// @Accept json -// @Produce octet-stream -// @Param uuid query int true "Demo UUID" -// @Success 200 {file} binary "Demo File" -// @Failure 400 {object} models.Response -// @Router /demos [get] +// @Description Get demo with specified demo uuid. +// @Tags demo +// @Accept json +// @Produce octet-stream +// @Param uuid query string true "Demo UUID" +// @Success 200 {file} binary "Demo File" +// @Failure 400 {object} models.Response +// @Router /demos [get] func DownloadDemoWithID(c *gin.Context) { uuid := c.Query("uuid") var locationID string diff --git a/backend/controllers/userController.go b/backend/controllers/userController.go index cbce0fe..e73b1fe 100644 --- a/backend/controllers/userController.go +++ b/backend/controllers/userController.go @@ -13,15 +13,15 @@ import ( // GET Profile // -// @Summary Get profile page of session user. -// @Tags users -// @Accept json -// @Produce json -// @Param Authorization header string true "JWT Token" -// @Success 200 {object} models.Response{data=models.ProfileResponse} -// @Failure 400 {object} models.Response -// @Failure 401 {object} models.Response -// @Router /profile [get] +// @Description Get profile page of session user. +// @Tags users +// @Accept json +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Success 200 {object} models.Response{data=models.ProfileResponse} +// @Failure 400 {object} models.Response +// @Failure 401 {object} models.Response +// @Router /profile [get] func Profile(c *gin.Context) { // Check if user exists user, exists := c.Get("user") @@ -100,15 +100,15 @@ func Profile(c *gin.Context) { // GET User // -// @Summary Get profile page of another user. -// @Tags users -// @Accept json -// @Produce json -// @Param id path int true "User ID" -// @Success 200 {object} models.Response{data=models.ProfileResponse} -// @Failure 400 {object} models.Response -// @Failure 404 {object} models.Response -// @Router /users/{id} [get] +// @Description Get profile page of another user. +// @Tags users +// @Accept json +// @Produce json +// @Param id path int true "User ID" +// @Success 200 {object} models.Response{data=models.ProfileResponse} +// @Failure 400 {object} models.Response +// @Failure 404 {object} models.Response +// @Router /users/{id} [get] func FetchUser(c *gin.Context) { id := c.Param("id") // Check if id is all numbers and 17 length @@ -202,15 +202,15 @@ func FetchUser(c *gin.Context) { // PUT Profile // -// @Summary Update profile page of session user. -// @Tags users -// @Accept json -// @Produce json -// @Param Authorization header string true "JWT Token" -// @Success 200 {object} models.Response{data=models.ProfileResponse} -// @Failure 400 {object} models.Response -// @Failure 401 {object} models.Response -// @Router /profile [post] +// @Description Update profile page of session user. +// @Tags users +// @Accept json +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Success 200 {object} models.Response{data=models.ProfileResponse} +// @Failure 400 {object} models.Response +// @Failure 401 {object} models.Response +// @Router /profile [post] func UpdateUser(c *gin.Context) { // Check if user exists user, exists := c.Get("user") @@ -245,16 +245,16 @@ func UpdateUser(c *gin.Context) { // PUT Profile/CountryCode // -// @Summary Update country code of session user. -// @Tags users -// @Accept json -// @Produce json -// @Param Authorization header string true "JWT Token" -// @Param country_code query string true "Country Code [XX]" -// @Success 200 {object} models.Response -// @Failure 400 {object} models.Response -// @Failure 401 {object} models.Response -// @Router /profile [put] +// @Description Update country code of session user. +// @Tags users +// @Accept json +// @Produce json +// @Param Authorization header string true "JWT Token" +// @Param country_code query string true "Country Code [XX]" +// @Success 200 {object} models.Response +// @Failure 400 {object} models.Response +// @Failure 401 {object} models.Response +// @Router /profile [put] func UpdateCountryCode(c *gin.Context) { // Check if user exists user, exists := c.Get("user") diff --git a/docs/docs.go b/docs/docs.go index bb14382..57984f4 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -22,13 +22,13 @@ const docTemplate = `{ "paths": { "/chapters/{id}": { "get": { + "description": "Get maps from the specified chapter id.", "produces": [ "application/json" ], "tags": [ "games \u0026 chapters" ], - "summary": "Get maps from the specified chapter id.", "parameters": [ { "type": "integer", @@ -66,45 +66,9 @@ const docTemplate = `{ } } }, - "/demo": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "rankings" - ], - "summary": "Get rankings of every player.", - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/models.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.RankingsResponse" - } - } - } - ] - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - }, "/demos": { "get": { + "description": "Get demo with specified demo uuid.", "consumes": [ "application/json" ], @@ -114,10 +78,9 @@ const docTemplate = `{ "tags": [ "demo" ], - "summary": "Get demo with specified demo uuid.", "parameters": [ { - "type": "integer", + "type": "string", "description": "Demo UUID", "name": "uuid", "in": "query", @@ -142,13 +105,13 @@ const docTemplate = `{ }, "/games": { "get": { + "description": "Get games from the leaderboards.", "produces": [ "application/json" ], "tags": [ "games \u0026 chapters" ], - "summary": "Get games from the leaderboards.", "responses": { "200": { "description": "OK", @@ -182,13 +145,13 @@ const docTemplate = `{ }, "/games/{id}": { "get": { + "description": "Get chapters from the specified game id.", "produces": [ "application/json" ], "tags": [ "games \u0026 chapters" ], - "summary": "Get chapters from the specified game id.", "parameters": [ { "type": "integer", @@ -228,6 +191,7 @@ const docTemplate = `{ }, "/login": { "get": { + "description": "Get (redirect) login page for Steam auth.", "consumes": [ "application/json" ], @@ -237,7 +201,6 @@ const docTemplate = `{ "tags": [ "login" ], - "summary": "Get (redirect) login page for Steam auth.", "responses": { "200": { "description": "OK", @@ -268,13 +231,13 @@ const docTemplate = `{ }, "/maps/{id}/leaderboards": { "get": { + "description": "Get map leaderboards with specified id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Get map leaderboards with specified id.", "parameters": [ { "type": "integer", @@ -326,6 +289,7 @@ const docTemplate = `{ }, "/maps/{id}/record": { "post": { + "description": "Post record with demo of a specific map.", "consumes": [ "multipart/form-data" ], @@ -335,7 +299,6 @@ const docTemplate = `{ "tags": [ "maps" ], - "summary": "Post record with demo of a specific map.", "parameters": [ { "type": "integer", @@ -401,13 +364,13 @@ const docTemplate = `{ }, "/maps/{id}/summary": { "get": { + "description": "Get map summary with specified id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Get map summary with specified id.", "parameters": [ { "type": "integer", @@ -445,13 +408,13 @@ const docTemplate = `{ } }, "put": { + "description": "Edit map summary with specified map id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Edit map summary with specified map id.", "parameters": [ { "type": "string", @@ -505,13 +468,13 @@ const docTemplate = `{ } }, "post": { + "description": "Create map summary with specified map id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Create map summary with specified map id.", "parameters": [ { "type": "string", @@ -565,13 +528,13 @@ const docTemplate = `{ } }, "delete": { + "description": "Delete map summary with specified map id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Delete map summary with specified map id.", "parameters": [ { "type": "string", @@ -627,6 +590,7 @@ const docTemplate = `{ }, "/profile": { "get": { + "description": "Get profile page of session user.", "consumes": [ "application/json" ], @@ -636,7 +600,6 @@ const docTemplate = `{ "tags": [ "users" ], - "summary": "Get profile page of session user.", "parameters": [ { "type": "string", @@ -680,6 +643,7 @@ const docTemplate = `{ } }, "put": { + "description": "Update country code of session user.", "consumes": [ "application/json" ], @@ -689,7 +653,6 @@ const docTemplate = `{ "tags": [ "users" ], - "summary": "Update country code of session user.", "parameters": [ { "type": "string", @@ -728,6 +691,7 @@ const docTemplate = `{ } }, "post": { + "description": "Update profile page of session user.", "consumes": [ "application/json" ], @@ -737,7 +701,6 @@ const docTemplate = `{ "tags": [ "users" ], - "summary": "Update profile page of session user.", "parameters": [ { "type": "string", @@ -781,15 +744,52 @@ const docTemplate = `{ } } }, + "/rankings": { + "get": { + "description": "Get rankings of every player.", + "produces": [ + "application/json" + ], + "tags": [ + "rankings" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.RankingsResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/search": { "get": { + "description": "Get all user and map data matching to the query.", "produces": [ "application/json" ], "tags": [ "search" ], - "summary": "Get all user and map data matching to the query.", "parameters": [ { "type": "string", @@ -828,13 +828,13 @@ const docTemplate = `{ }, "/token": { "get": { + "description": "Gets the token cookie value from the user.", "produces": [ "application/json" ], "tags": [ "auth" ], - "summary": "Gets the token cookie value from the user.", "responses": { "200": { "description": "OK", @@ -863,13 +863,13 @@ const docTemplate = `{ } }, "delete": { + "description": "Deletes the token cookie from the user.", "produces": [ "application/json" ], "tags": [ "auth" ], - "summary": "Deletes the token cookie from the user.", "responses": { "200": { "description": "OK", @@ -900,6 +900,7 @@ const docTemplate = `{ }, "/users/{id}": { "get": { + "description": "Get profile page of another user.", "consumes": [ "application/json" ], @@ -909,7 +910,6 @@ const docTemplate = `{ "tags": [ "users" ], - "summary": "Get profile page of another user.", "parameters": [ { "type": "integer", diff --git a/docs/swagger.json b/docs/swagger.json index 3530d2c..ef422ab 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -15,13 +15,13 @@ "paths": { "/chapters/{id}": { "get": { + "description": "Get maps from the specified chapter id.", "produces": [ "application/json" ], "tags": [ "games \u0026 chapters" ], - "summary": "Get maps from the specified chapter id.", "parameters": [ { "type": "integer", @@ -59,45 +59,9 @@ } } }, - "/demo": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "rankings" - ], - "summary": "Get rankings of every player.", - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/models.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/models.RankingsResponse" - } - } - } - ] - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/models.Response" - } - } - } - } - }, "/demos": { "get": { + "description": "Get demo with specified demo uuid.", "consumes": [ "application/json" ], @@ -107,10 +71,9 @@ "tags": [ "demo" ], - "summary": "Get demo with specified demo uuid.", "parameters": [ { - "type": "integer", + "type": "string", "description": "Demo UUID", "name": "uuid", "in": "query", @@ -135,13 +98,13 @@ }, "/games": { "get": { + "description": "Get games from the leaderboards.", "produces": [ "application/json" ], "tags": [ "games \u0026 chapters" ], - "summary": "Get games from the leaderboards.", "responses": { "200": { "description": "OK", @@ -175,13 +138,13 @@ }, "/games/{id}": { "get": { + "description": "Get chapters from the specified game id.", "produces": [ "application/json" ], "tags": [ "games \u0026 chapters" ], - "summary": "Get chapters from the specified game id.", "parameters": [ { "type": "integer", @@ -221,6 +184,7 @@ }, "/login": { "get": { + "description": "Get (redirect) login page for Steam auth.", "consumes": [ "application/json" ], @@ -230,7 +194,6 @@ "tags": [ "login" ], - "summary": "Get (redirect) login page for Steam auth.", "responses": { "200": { "description": "OK", @@ -261,13 +224,13 @@ }, "/maps/{id}/leaderboards": { "get": { + "description": "Get map leaderboards with specified id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Get map leaderboards with specified id.", "parameters": [ { "type": "integer", @@ -319,6 +282,7 @@ }, "/maps/{id}/record": { "post": { + "description": "Post record with demo of a specific map.", "consumes": [ "multipart/form-data" ], @@ -328,7 +292,6 @@ "tags": [ "maps" ], - "summary": "Post record with demo of a specific map.", "parameters": [ { "type": "integer", @@ -394,13 +357,13 @@ }, "/maps/{id}/summary": { "get": { + "description": "Get map summary with specified id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Get map summary with specified id.", "parameters": [ { "type": "integer", @@ -438,13 +401,13 @@ } }, "put": { + "description": "Edit map summary with specified map id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Edit map summary with specified map id.", "parameters": [ { "type": "string", @@ -498,13 +461,13 @@ } }, "post": { + "description": "Create map summary with specified map id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Create map summary with specified map id.", "parameters": [ { "type": "string", @@ -558,13 +521,13 @@ } }, "delete": { + "description": "Delete map summary with specified map id.", "produces": [ "application/json" ], "tags": [ "maps" ], - "summary": "Delete map summary with specified map id.", "parameters": [ { "type": "string", @@ -620,6 +583,7 @@ }, "/profile": { "get": { + "description": "Get profile page of session user.", "consumes": [ "application/json" ], @@ -629,7 +593,6 @@ "tags": [ "users" ], - "summary": "Get profile page of session user.", "parameters": [ { "type": "string", @@ -673,6 +636,7 @@ } }, "put": { + "description": "Update country code of session user.", "consumes": [ "application/json" ], @@ -682,7 +646,6 @@ "tags": [ "users" ], - "summary": "Update country code of session user.", "parameters": [ { "type": "string", @@ -721,6 +684,7 @@ } }, "post": { + "description": "Update profile page of session user.", "consumes": [ "application/json" ], @@ -730,7 +694,6 @@ "tags": [ "users" ], - "summary": "Update profile page of session user.", "parameters": [ { "type": "string", @@ -774,15 +737,52 @@ } } }, + "/rankings": { + "get": { + "description": "Get rankings of every player.", + "produces": [ + "application/json" + ], + "tags": [ + "rankings" + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/models.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/models.RankingsResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Response" + } + } + } + } + }, "/search": { "get": { + "description": "Get all user and map data matching to the query.", "produces": [ "application/json" ], "tags": [ "search" ], - "summary": "Get all user and map data matching to the query.", "parameters": [ { "type": "string", @@ -821,13 +821,13 @@ }, "/token": { "get": { + "description": "Gets the token cookie value from the user.", "produces": [ "application/json" ], "tags": [ "auth" ], - "summary": "Gets the token cookie value from the user.", "responses": { "200": { "description": "OK", @@ -856,13 +856,13 @@ } }, "delete": { + "description": "Deletes the token cookie from the user.", "produces": [ "application/json" ], "tags": [ "auth" ], - "summary": "Deletes the token cookie from the user.", "responses": { "200": { "description": "OK", @@ -893,6 +893,7 @@ }, "/users/{id}": { "get": { + "description": "Get profile page of another user.", "consumes": [ "application/json" ], @@ -902,7 +903,6 @@ "tags": [ "users" ], - "summary": "Get profile page of another user.", "parameters": [ { "type": "integer", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index d4420e2..2fed413 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -242,6 +242,7 @@ info: paths: /chapters/{id}: get: + description: Get maps from the specified chapter id. parameters: - description: Chapter ID in: path @@ -264,40 +265,19 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get maps from the specified chapter id. tags: - games & chapters - /demo: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - allOf: - - $ref: '#/definitions/models.Response' - - properties: - data: - $ref: '#/definitions/models.RankingsResponse' - type: object - "400": - description: Bad Request - schema: - $ref: '#/definitions/models.Response' - summary: Get rankings of every player. - tags: - - rankings /demos: get: consumes: - application/json + description: Get demo with specified demo uuid. parameters: - description: Demo UUID in: query name: uuid required: true - type: integer + type: string produces: - application/octet-stream responses: @@ -309,11 +289,11 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get demo with specified demo uuid. tags: - demo /games: get: + description: Get games from the leaderboards. produces: - application/json responses: @@ -332,11 +312,11 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get games from the leaderboards. tags: - games & chapters /games/{id}: get: + description: Get chapters from the specified game id. parameters: - description: Game ID in: path @@ -359,13 +339,13 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get chapters from the specified game id. tags: - games & chapters /login: get: consumes: - application/json + description: Get (redirect) login page for Steam auth. produces: - application/json responses: @@ -382,11 +362,11 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get (redirect) login page for Steam auth. tags: - login /maps/{id}/leaderboards: get: + description: Get map leaderboards with specified id. parameters: - description: Map ID in: path @@ -414,13 +394,13 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get map leaderboards with specified id. tags: - maps /maps/{id}/record: post: consumes: - multipart/form-data + description: Post record with demo of a specific map. parameters: - description: Map ID in: path @@ -464,11 +444,11 @@ paths: description: Unauthorized schema: $ref: '#/definitions/models.Response' - summary: Post record with demo of a specific map. tags: - maps /maps/{id}/summary: delete: + description: Delete map summary with specified map id. parameters: - description: JWT Token in: header @@ -502,10 +482,10 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Delete map summary with specified map id. tags: - maps get: + description: Get map summary with specified id. parameters: - description: Map ID in: path @@ -528,10 +508,10 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get map summary with specified id. tags: - maps post: + description: Create map summary with specified map id. parameters: - description: JWT Token in: header @@ -565,10 +545,10 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Create map summary with specified map id. tags: - maps put: + description: Edit map summary with specified map id. parameters: - description: JWT Token in: header @@ -602,13 +582,13 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Edit map summary with specified map id. tags: - maps /profile: get: consumes: - application/json + description: Get profile page of session user. parameters: - description: JWT Token in: header @@ -635,12 +615,12 @@ paths: description: Unauthorized schema: $ref: '#/definitions/models.Response' - summary: Get profile page of session user. tags: - users post: consumes: - application/json + description: Update profile page of session user. parameters: - description: JWT Token in: header @@ -667,12 +647,12 @@ paths: description: Unauthorized schema: $ref: '#/definitions/models.Response' - summary: Update profile page of session user. tags: - users put: consumes: - application/json + description: Update country code of session user. parameters: - description: JWT Token in: header @@ -699,11 +679,32 @@ paths: description: Unauthorized schema: $ref: '#/definitions/models.Response' - summary: Update country code of session user. tags: - users + /rankings: + get: + description: Get rankings of every player. + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/models.Response' + - properties: + data: + $ref: '#/definitions/models.RankingsResponse' + type: object + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Response' + tags: + - rankings /search: get: + description: Get all user and map data matching to the query. parameters: - description: Search user or map name. in: query @@ -725,11 +726,11 @@ paths: description: Bad Request schema: $ref: '#/definitions/models.Response' - summary: Get all user and map data matching to the query. tags: - search /token: delete: + description: Deletes the token cookie from the user. produces: - application/json responses: @@ -746,10 +747,10 @@ paths: description: Not Found schema: $ref: '#/definitions/models.Response' - summary: Deletes the token cookie from the user. tags: - auth get: + description: Gets the token cookie value from the user. produces: - application/json responses: @@ -766,13 +767,13 @@ paths: description: Not Found schema: $ref: '#/definitions/models.Response' - summary: Gets the token cookie value from the user. tags: - auth /users/{id}: get: consumes: - application/json + description: Get profile page of another user. parameters: - description: User ID in: path @@ -799,7 +800,6 @@ paths: description: Not Found schema: $ref: '#/definitions/models.Response' - summary: Get profile page of another user. tags: - users swagger: "2.0" -- cgit v1.2.3 From 3ad53aeeffec00f85bf1f3168d0e9d61c65eecb7 Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Mon, 10 Jul 2023 16:06:29 +0300 Subject: feat: is_coop field on games Former-commit-id: bf3a5a262557ade646ce8e59db152be8c521ac06 --- backend/controllers/mapController.go | 4 ++-- backend/database/games.sql | 6 +++--- backend/database/init.sql | 1 + backend/models/models.go | 5 +++-- 4 files changed, 9 insertions(+), 7 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 52b6623..11e56f6 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -193,7 +193,7 @@ func FetchMapLeaderboards(c *gin.Context) { // @Failure 400 {object} models.Response // @Router /games [get] func FetchGames(c *gin.Context) { - rows, err := database.DB.Query(`SELECT id, name FROM games`) + rows, err := database.DB.Query(`SELECT id, name, is_coop FROM games`) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return @@ -201,7 +201,7 @@ func FetchGames(c *gin.Context) { var games []models.Game for rows.Next() { var game models.Game - if err := rows.Scan(&game.ID, &game.Name); err != nil { + if err := rows.Scan(&game.ID, &game.Name, &game.IsCoop); err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return } diff --git a/backend/database/games.sql b/backend/database/games.sql index 5e2f4ee..0c2374c 100644 --- a/backend/database/games.sql +++ b/backend/database/games.sql @@ -1,3 +1,3 @@ -INSERT INTO games(id, name) VALUES -(1, 'Portal 2 - Singleplayer'), -(2, 'Portal 2 - Cooperative'); \ No newline at end of file +INSERT INTO games(id, name, is_coop) VALUES +(1, 'Portal 2 - Singleplayer', false), +(2, 'Portal 2 - Cooperative', true); \ No newline at end of file diff --git a/backend/database/init.sql b/backend/database/init.sql index 76c3aa6..c7d098c 100644 --- a/backend/database/init.sql +++ b/backend/database/init.sql @@ -11,6 +11,7 @@ CREATE TABLE users ( CREATE TABLE games ( id SMALLSERIAL, name TEXT NOT NULL, + is_coop BOOLEAN NOT NULL, PRIMARY KEY (id) ); diff --git a/backend/models/models.go b/backend/models/models.go index 2524935..e63ff91 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -62,8 +62,9 @@ type UserRanking struct { } type Game struct { - ID int `json:"id"` - Name string `json:"name"` + ID int `json:"id"` + Name string `json:"name"` + IsCoop bool `json:"is_coop"` } type Chapter struct { -- cgit v1.2.3 From a8023ad4949649623c6c2bbe694ce6fc2a26e4dc Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:35:47 +0300 Subject: feat: is_coop field on map summary Former-commit-id: f780291d97e9df9f0d0743b06cedae7345308887 --- backend/controllers/mapController.go | 4 ++-- backend/models/models.go | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'backend/controllers/mapController.go') diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go index 11e56f6..e7c5566 100644 --- a/backend/controllers/mapController.go +++ b/backend/controllers/mapController.go @@ -28,12 +28,12 @@ func FetchMapSummary(c *gin.Context) { } // Get map data response.Map.ID = intID - sql := `SELECT m.id, g.name, c.name, m.name, m.image + sql := `SELECT m.id, g.name, c.name, m.name, m.image, g.is_coop FROM maps m INNER JOIN games g ON m.game_id = g.id INNER JOIN chapters c ON m.chapter_id = c.id WHERE m.id = $1` - err = database.DB.QueryRow(sql, id).Scan(&response.Map.ID, &response.Map.GameName, &response.Map.ChapterName, &response.Map.MapName, &response.Map.Image) + 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) if err != nil { c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) return diff --git a/backend/models/models.go b/backend/models/models.go index e63ff91..1231cb1 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -25,6 +25,7 @@ type Map struct { ChapterName string `json:"chapter_name"` MapName string `json:"map_name"` Image string `json:"image"` + IsCoop bool `json:"is_coop"` } type MapShort struct { -- cgit v1.2.3