aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-08-25 22:58:52 +0300
committerArda Serdar Pektezol <1669855+pektezol@users.noreply.github.com>2023-08-25 22:58:52 +0300
commitaa93b382722cc34f63666dc56d68b53e86ce5394 (patch)
tree41356cdf1e132349da5bdfa25691a13836572957 /backend
parentfeat: profile cleanup before rework (#51) (diff)
downloadlphub-aa93b382722cc34f63666dc56d68b53e86ce5394.tar.gz
lphub-aa93b382722cc34f63666dc56d68b53e86ce5394.tar.bz2
lphub-aa93b382722cc34f63666dc56d68b53e86ce5394.zip
feat: better score handling in profiles (#51)
Former-commit-id: 9d30f4ad6e9e077259868e7f05fbe7ac1f65229c
Diffstat (limited to 'backend')
-rw-r--r--backend/controllers/userController.go174
1 files changed, 147 insertions, 27 deletions
diff --git a/backend/controllers/userController.go b/backend/controllers/userController.go
index 960ecb4..84d589a 100644
--- a/backend/controllers/userController.go
+++ b/backend/controllers/userController.go
@@ -36,13 +36,14 @@ type ProfileRankingsDetails struct {
36} 36}
37 37
38type ProfileRecords struct { 38type ProfileRecords struct {
39 P2Singleplayer ProfileRecordsDetails `json:"portal2_singleplayer"` 39 P2Singleplayer []ProfileRecordsDetails `json:"portal2_singleplayer"`
40 P2Cooperative ProfileRecordsDetails `json:"portal2_cooperative"` 40 P2Cooperative []ProfileRecordsDetails `json:"portal2_cooperative"`
41} 41}
42 42
43type ProfileRecordsDetails struct { 43type ProfileRecordsDetails struct {
44 MapID int `json:"map_id"` 44 MapID int `json:"map_id"`
45 Scores []ProfileScores `json:"scores"` 45 MapName string `json:"map_name"`
46 Scores []ProfileScores `json:"scores"`
46} 47}
47 48
48type ProfileScores struct { 49type ProfileScores struct {
@@ -75,22 +76,78 @@ func Profile(c *gin.Context) {
75 c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) 76 c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in."))
76 return 77 return
77 } 78 }
78 // Get user titles 79 // Get user links
79 titles := []models.Title{} 80 links := models.Links{}
80 sql := `SELECT t.title_name, t.title_color FROM titles t 81 sql := `SELECT u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1`
81 INNER JOIN user_titles ut ON t.id=ut.title_id WHERE ut.user_id = $1` 82 err := database.DB.QueryRow(sql, user.(models.User).SteamID).Scan(&links.P2SR, &links.Steam, &links.YouTube, &links.Twitch)
83 if err != nil {
84 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
85 return
86 }
87 // TODO: Get rankings (all maps done in one game)
88 records := ProfileRecords{
89 P2Singleplayer: []ProfileRecordsDetails{},
90 P2Cooperative: []ProfileRecordsDetails{},
91 }
92 // Get singleplayer records
93 sql = `SELECT m.game_id, sp.map_id, m."name", sp.score_count, sp.score_time, sp.demo_id, sp.record_date
94 FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 ORDER BY sp.map_id, sp.score_count, sp.score_time;`
82 rows, err := database.DB.Query(sql, user.(models.User).SteamID) 95 rows, err := database.DB.Query(sql, user.(models.User).SteamID)
83 if err != nil { 96 if err != nil {
84 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 97 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
85 return 98 return
86 } 99 }
87 for rows.Next() { 100 for rows.Next() {
88 var title models.Title 101 var mapID int
89 if err := rows.Scan(&title.Name, &title.Color); err != nil { 102 var mapName string
90 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 103 var gameID int
91 return 104 score := ProfileScores{}
105 rows.Scan(&gameID, &mapID, &mapName, &score.ScoreCount, &score.ScoreTime, &score.DemoID, &score.Date)
106 if gameID != 1 {
107 continue
108 }
109 // More than one record in one map
110 if len(records.P2Singleplayer) != 0 && mapID == records.P2Singleplayer[len(records.P2Singleplayer)-1].MapID {
111 records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores = append(records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores, score)
112 continue
92 } 113 }
93 titles = append(titles, title) 114 // New map
115 records.P2Singleplayer = append(records.P2Singleplayer, ProfileRecordsDetails{
116 MapID: mapID,
117 MapName: mapName,
118 Scores: []ProfileScores{},
119 })
120 records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores = append(records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores, score)
121 }
122 // Get multiplayer records
123 sql = `SELECT m.game_id, mp.map_id, m."name", mp.score_count, mp.score_time, CASE WHEN host_id = $1 THEN mp.host_demo_id WHEN partner_id = $1 THEN mp.partner_demo_id END demo_id, mp.record_date
124 FROM records_mp mp INNER JOIN maps m ON mp.map_id = m.id WHERE mp.host_id = $1 OR mp.partner_id = $1 ORDER BY mp.map_id, mp.score_count, mp.score_time;`
125 rows, err = database.DB.Query(sql, user.(models.User).SteamID)
126 if err != nil {
127 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
128 return
129 }
130 for rows.Next() {
131 var mapID int
132 var mapName string
133 var gameID int
134 score := ProfileScores{}
135 rows.Scan(&gameID, &mapID, &mapName, &score.ScoreCount, &score.ScoreTime, &score.DemoID, &score.Date)
136 if gameID != 1 {
137 continue
138 }
139 // More than one record in one map
140 if len(records.P2Cooperative) != 0 && mapID == records.P2Cooperative[len(records.P2Cooperative)-1].MapID {
141 records.P2Cooperative[len(records.P2Cooperative)-1].Scores = append(records.P2Cooperative[len(records.P2Cooperative)-1].Scores, score)
142 continue
143 }
144 // New map
145 records.P2Cooperative = append(records.P2Cooperative, ProfileRecordsDetails{
146 MapID: mapID,
147 MapName: mapName,
148 Scores: []ProfileScores{},
149 })
150 records.P2Cooperative[len(records.P2Cooperative)-1].Scores = append(records.P2Cooperative[len(records.P2Cooperative)-1].Scores, score)
94 } 151 }
95 c.JSON(http.StatusOK, models.Response{ 152 c.JSON(http.StatusOK, models.Response{
96 Success: true, 153 Success: true,
@@ -102,12 +159,11 @@ func Profile(c *gin.Context) {
102 AvatarLink: user.(models.User).AvatarLink, 159 AvatarLink: user.(models.User).AvatarLink,
103 CountryCode: user.(models.User).CountryCode, 160 CountryCode: user.(models.User).CountryCode,
104 Titles: user.(models.User).Titles, 161 Titles: user.(models.User).Titles,
105 Links: models.Links{}, 162 Links: links,
106 Rankings: ProfileRankings{}, 163 Rankings: ProfileRankings{},
107 Records: ProfileRecords{}, 164 Records: records,
108 }, 165 },
109 }) 166 })
110 return
111} 167}
112 168
113// GET User 169// GET User
@@ -131,20 +187,20 @@ func FetchUser(c *gin.Context) {
131 } 187 }
132 // Check if user exists 188 // Check if user exists
133 var user models.User 189 var user models.User
134 err := database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1`, id).Scan( 190 links := models.Links{}
135 &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, 191 sql := `SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, u.p2sr, u.steam, u.youtube, u.twitch FROM users u WHERE u.steam_id = $1`
136 &user.CreatedAt, &user.UpdatedAt) 192 err := database.DB.QueryRow(sql, id).Scan(&user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt, &links.P2SR, &links.Steam, &links.YouTube, &links.Twitch)
193 if err != nil {
194 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
195 return
196 }
137 if user.SteamID == "" { 197 if user.SteamID == "" {
138 // User does not exist 198 // User does not exist
139 c.JSON(http.StatusNotFound, models.ErrorResponse("User not found.")) 199 c.JSON(http.StatusNotFound, models.ErrorResponse("User not found."))
140 return 200 return
141 } 201 }
142 if err != nil {
143 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
144 return
145 }
146 // Get user titles 202 // Get user titles
147 sql := `SELECT t.title_name, t.title_color FROM titles t 203 sql = `SELECT t.title_name, t.title_color FROM titles t
148 INNER JOIN user_titles ut ON t.id=ut.title_id WHERE ut.user_id = $1` 204 INNER JOIN user_titles ut ON t.id=ut.title_id WHERE ut.user_id = $1`
149 rows, err := database.DB.Query(sql, user.SteamID) 205 rows, err := database.DB.Query(sql, user.SteamID)
150 if err != nil { 206 if err != nil {
@@ -159,6 +215,71 @@ func FetchUser(c *gin.Context) {
159 } 215 }
160 user.Titles = append(user.Titles, title) 216 user.Titles = append(user.Titles, title)
161 } 217 }
218 // TODO: Get rankings (all maps done in one game)
219 records := ProfileRecords{
220 P2Singleplayer: []ProfileRecordsDetails{},
221 P2Cooperative: []ProfileRecordsDetails{},
222 }
223 // Get singleplayer records
224 sql = `SELECT m.game_id, sp.map_id, m."name", sp.score_count, sp.score_time, sp.demo_id, sp.record_date
225 FROM records_sp sp INNER JOIN maps m ON sp.map_id = m.id WHERE sp.user_id = $1 ORDER BY sp.map_id, sp.score_count, sp.score_time;`
226 rows, err = database.DB.Query(sql, user.SteamID)
227 if err != nil {
228 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
229 return
230 }
231 for rows.Next() {
232 var mapID int
233 var mapName string
234 var gameID int
235 score := ProfileScores{}
236 rows.Scan(&gameID, &mapID, &mapName, &score.ScoreCount, &score.ScoreTime, &score.DemoID, &score.Date)
237 if gameID != 1 {
238 continue
239 }
240 // More than one record in one map
241 if len(records.P2Singleplayer) != 0 && mapID == records.P2Singleplayer[len(records.P2Singleplayer)-1].MapID {
242 records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores = append(records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores, score)
243 continue
244 }
245 // New map
246 records.P2Singleplayer = append(records.P2Singleplayer, ProfileRecordsDetails{
247 MapID: mapID,
248 MapName: mapName,
249 Scores: []ProfileScores{},
250 })
251 records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores = append(records.P2Singleplayer[len(records.P2Singleplayer)-1].Scores, score)
252 }
253 // Get multiplayer records
254 sql = `SELECT m.game_id, mp.map_id, m."name", mp.score_count, mp.score_time, CASE WHEN host_id = $1 THEN mp.host_demo_id WHEN partner_id = $1 THEN mp.partner_demo_id END demo_id, mp.record_date
255 FROM records_mp mp INNER JOIN maps m ON mp.map_id = m.id WHERE mp.host_id = $1 OR mp.partner_id = $1 ORDER BY mp.map_id, mp.score_count, mp.score_time;`
256 rows, err = database.DB.Query(sql, user.SteamID)
257 if err != nil {
258 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
259 return
260 }
261 for rows.Next() {
262 var mapID int
263 var mapName string
264 var gameID int
265 score := ProfileScores{}
266 rows.Scan(&gameID, &mapID, &mapName, &score.ScoreCount, &score.ScoreTime, &score.DemoID, &score.Date)
267 if gameID != 1 {
268 continue
269 }
270 // More than one record in one map
271 if len(records.P2Cooperative) != 0 && mapID == records.P2Cooperative[len(records.P2Cooperative)-1].MapID {
272 records.P2Cooperative[len(records.P2Cooperative)-1].Scores = append(records.P2Cooperative[len(records.P2Cooperative)-1].Scores, score)
273 continue
274 }
275 // New map
276 records.P2Cooperative = append(records.P2Cooperative, ProfileRecordsDetails{
277 MapID: mapID,
278 MapName: mapName,
279 Scores: []ProfileScores{},
280 })
281 records.P2Cooperative[len(records.P2Cooperative)-1].Scores = append(records.P2Cooperative[len(records.P2Cooperative)-1].Scores, score)
282 }
162 c.JSON(http.StatusOK, models.Response{ 283 c.JSON(http.StatusOK, models.Response{
163 Success: true, 284 Success: true,
164 Message: "Successfully retrieved user scores.", 285 Message: "Successfully retrieved user scores.",
@@ -169,12 +290,11 @@ func FetchUser(c *gin.Context) {
169 AvatarLink: user.AvatarLink, 290 AvatarLink: user.AvatarLink,
170 CountryCode: user.CountryCode, 291 CountryCode: user.CountryCode,
171 Titles: user.Titles, 292 Titles: user.Titles,
172 Links: models.Links{}, 293 Links: links,
173 Rankings: ProfileRankings{}, 294 Rankings: ProfileRankings{},
174 Records: ProfileRecords{}, 295 Records: records,
175 }, 296 },
176 }) 297 })
177 return
178} 298}
179 299
180// PUT Profile 300// PUT Profile