diff options
| author | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-08-25 22:58:52 +0300 |
|---|---|---|
| committer | Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> | 2023-08-25 22:58:52 +0300 |
| commit | aa93b382722cc34f63666dc56d68b53e86ce5394 (patch) | |
| tree | 41356cdf1e132349da5bdfa25691a13836572957 /backend | |
| parent | feat: profile cleanup before rework (#51) (diff) | |
| download | lphub-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.go | 174 |
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 | ||
| 38 | type ProfileRecords struct { | 38 | type 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 | ||
| 43 | type ProfileRecordsDetails struct { | 43 | type 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 | ||
| 48 | type ProfileScores struct { | 49 | type 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 |