aboutsummaryrefslogtreecommitdiff
path: root/backend/controllers/mapController.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/controllers/mapController.go')
-rw-r--r--backend/controllers/mapController.go130
1 files changed, 112 insertions, 18 deletions
diff --git a/backend/controllers/mapController.go b/backend/controllers/mapController.go
index 16dd669..bd85a97 100644
--- a/backend/controllers/mapController.go
+++ b/backend/controllers/mapController.go
@@ -3,26 +3,117 @@ package controllers
3import ( 3import (
4 "net/http" 4 "net/http"
5 "strconv" 5 "strconv"
6 "time"
6 7
7 "github.com/gin-gonic/gin" 8 "github.com/gin-gonic/gin"
9 "github.com/lib/pq"
8 "github.com/pektezol/leastportals/backend/database" 10 "github.com/pektezol/leastportals/backend/database"
9 "github.com/pektezol/leastportals/backend/models" 11 "github.com/pektezol/leastportals/backend/models"
10) 12)
11 13
12// GET Map 14// GET Map Summary
13// 15//
14// @Summary Get map page with specified id. 16// @Summary Get map summary with specified id.
15// @Tags maps 17// @Tags maps
16// @Accept json 18// @Accept json
17// @Produce json 19// @Produce json
18// @Param id path int true "Map ID" 20// @Param id path int true "Map ID"
19// @Success 200 {object} models.Response{data=models.Map} 21// @Success 200 {object} models.Response{data=models.Map{data=models.MapSummary}}
20// @Failure 400 {object} models.Response 22// @Failure 400 {object} models.Response
21// @Router /maps/{id} [get] 23// @Router /maps/{id}/summary [get]
22func FetchMap(c *gin.Context) { 24func FetchMapSummary(c *gin.Context) {
23 id := c.Param("id") 25 id := c.Param("id")
24 // Get map data 26 // Get map data
25 var mapData models.Map 27 var mapData models.Map
28 var mapSummaryData models.MapSummary
29 var mapHistoryData []models.MapHistory
30 intID, err := strconv.Atoi(id)
31 if err != nil {
32 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
33 return
34 }
35 mapData.ID = intID
36 var routers pq.StringArray
37 sql := `SELECT g.name, c.name, m.name, m.description, m.showcase,
38 (
39 SELECT array_agg(user_name)
40 FROM map_routers
41 WHERE map_id = $1
42 AND score_count = (
43 SELECT score_count
44 FROM map_history
45 WHERE map_id = $1
46 ORDER BY score_count
47 LIMIT 1
48 )
49 GROUP BY map_routers.user_name
50 ORDER BY user_name
51 ),
52 (
53 SELECT COALESCE(avg(rating), 0.0)
54 FROM map_ratings
55 WHERE map_id = $1
56 )
57 FROM maps m
58 INNER JOIN games g ON m.game_id = g.id
59 INNER JOIN chapters c ON m.chapter_id = c.id
60 WHERE m.id = $1;`
61 // TODO: CategoryScores
62 err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &mapSummaryData.Description, &mapSummaryData.Showcase, &routers, &mapSummaryData.Rating)
63 if err != nil {
64 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
65 return
66 }
67 var historyNames pq.StringArray
68 var historyScores pq.Int32Array
69 var historyDates pq.StringArray
70 sql = `SELECT array_agg(user_name), array_agg(score_count), array_agg(record_date)
71 FROM map_history
72 WHERE map_id = $1;`
73 err = database.DB.QueryRow(sql, id).Scan(&historyNames, &historyScores, &historyDates)
74 if err != nil {
75 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
76 return
77 }
78 for i := 0; i < len(historyNames); i++ {
79 var history models.MapHistory
80 history.RunnerName = historyNames[i]
81 history.ScoreCount = int(historyScores[i])
82 layout := "2006-01-02 15:04:05"
83 date, err := time.Parse(layout, historyDates[i])
84 if err != nil {
85 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
86 return
87 }
88 history.Date = date
89 mapHistoryData = append(mapHistoryData, history)
90 }
91 mapSummaryData.History = mapHistoryData
92 mapSummaryData.Routers = routers
93 mapData.Data = mapSummaryData
94 // Return response
95 c.JSON(http.StatusOK, models.Response{
96 Success: true,
97 Message: "Successfully retrieved map summary.",
98 Data: mapData,
99 })
100}
101
102// GET Map Leaderboards
103//
104// @Summary Get map leaderboards with specified id.
105// @Tags maps
106// @Accept json
107// @Produce json
108// @Param id path int true "Map ID"
109// @Success 200 {object} models.Response{data=models.Map{data=models.MapRecords}}
110// @Failure 400 {object} models.Response
111// @Router /maps/{id}/leaderboards [get]
112func FetchMapLeaderboards(c *gin.Context) {
113 id := c.Param("id")
114 // Get map data
115 var mapData models.Map
116 var mapRecordsData models.MapRecords
26 var isDisabled bool 117 var isDisabled bool
27 intID, err := strconv.Atoi(id) 118 intID, err := strconv.Atoi(id)
28 if err != nil { 119 if err != nil {
@@ -30,8 +121,12 @@ func FetchMap(c *gin.Context) {
30 return 121 return
31 } 122 }
32 mapData.ID = intID 123 mapData.ID = intID
33 sql := `SELECT map_name, wr_score, wr_time, is_coop, is_disabled FROM maps WHERE id = $1;` 124 sql := `SELECT g.name, c.name, m.name, is_disabled
34 err = database.DB.QueryRow(sql, id).Scan(&mapData.Name, &mapData.ScoreWR, &mapData.TimeWR, &mapData.IsCoop, &isDisabled) 125 FROM maps m
126 INNER JOIN games g ON m.game_id = g.id
127 INNER JOIN chapters c ON m.chapter_id = c.id
128 WHERE m.id = $1;`
129 err = database.DB.QueryRow(sql, id).Scan(&mapData.GameName, &mapData.ChapterName, &mapData.MapName, &isDisabled)
35 if err != nil { 130 if err != nil {
36 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 131 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
37 return 132 return
@@ -40,13 +135,14 @@ func FetchMap(c *gin.Context) {
40 c.JSON(http.StatusBadRequest, models.ErrorResponse("Map is not available for competitive boards.")) 135 c.JSON(http.StatusBadRequest, models.ErrorResponse("Map is not available for competitive boards."))
41 return 136 return
42 } 137 }
138 // TODO: avatar and names for host & partner
43 // Get records from the map 139 // Get records from the map
44 if mapData.IsCoop { 140 if mapData.GameName == "Portal 2 - Cooperative" {
45 var records []models.RecordMP 141 var records []models.RecordMP
46 sql = `SELECT id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date 142 sql = `SELECT id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date
47 FROM ( 143 FROM (
48 SELECT id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date, 144 SELECT id, host_id, partner_id, score_count, score_time, host_demo_id, partner_demo_id, record_date,
49 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY score_count, score_time) AS rn 145 ROW_NUMBER() OVER (PARTITION BY host_id, partner_id ORDER BY score_count, score_time) AS rn
50 FROM records_mp 146 FROM records_mp
51 WHERE map_id = $1 147 WHERE map_id = $1
52 ) sub 148 ) sub
@@ -74,16 +170,17 @@ func FetchMap(c *gin.Context) {
74 records = append(records, record) 170 records = append(records, record)
75 placement++ 171 placement++
76 } 172 }
77 mapData.Records = records 173 mapRecordsData.Records = records
78 } else { 174 } else {
79 var records []models.RecordSP 175 var records []models.RecordSP
80 sql = `SELECT id, user_id, score_count, score_time, demo_id, record_date 176 sql = `SELECT id, user_id, users.user_name, users.avatar_link, score_count, score_time, demo_id, record_date
81 FROM ( 177 FROM (
82 SELECT id, user_id, score_count, score_time, demo_id, record_date, 178 SELECT id, user_id, score_count, score_time, demo_id, record_date,
83 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY score_count, score_time) AS rn 179 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY score_count, score_time) AS rn
84 FROM records_sp 180 FROM records_sp
85 WHERE map_id = $1 181 WHERE map_id = $1
86 ) sub 182 ) sub
183 INNER JOIN users ON user_id = users.steam_id
87 WHERE rn = 1;` 184 WHERE rn = 1;`
88 rows, err := database.DB.Query(sql, id) 185 rows, err := database.DB.Query(sql, id)
89 if err != nil { 186 if err != nil {
@@ -94,7 +191,7 @@ func FetchMap(c *gin.Context) {
94 ties := 0 191 ties := 0
95 for rows.Next() { 192 for rows.Next() {
96 var record models.RecordSP 193 var record models.RecordSP
97 err := rows.Scan(&record.RecordID, &record.UserID, &record.ScoreCount, &record.ScoreTime, &record.DemoID, &record.RecordDate) 194 err := rows.Scan(&record.RecordID, &record.UserID, &record.UserName, &record.UserAvatar, &record.ScoreCount, &record.ScoreTime, &record.DemoID, &record.RecordDate)
98 if err != nil { 195 if err != nil {
99 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 196 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
100 return 197 return
@@ -108,16 +205,13 @@ func FetchMap(c *gin.Context) {
108 records = append(records, record) 205 records = append(records, record)
109 placement++ 206 placement++
110 } 207 }
111 mapData.Records = records 208 mapRecordsData.Records = records
112 } 209 }
210 mapData.Data = mapRecordsData
113 // Return response 211 // Return response
114 c.JSON(http.StatusOK, models.Response{ 212 c.JSON(http.StatusOK, models.Response{
115 Success: true, 213 Success: true,
116 Message: "Successfully retrieved map data.", 214 Message: "Successfully retrieved map leaderboards.",
117 Data: mapData, 215 Data: mapData,
118 }) 216 })
119} 217}
120
121func CreateMapCommunity(c *gin.Context) {
122
123}