aboutsummaryrefslogtreecommitdiff
path: root/backend/handlers/home.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--backend/handlers/home.go (renamed from backend/controllers/homeController.go)169
1 files changed, 87 insertions, 82 deletions
diff --git a/backend/controllers/homeController.go b/backend/handlers/home.go
index c94590a..2095a74 100644
--- a/backend/controllers/homeController.go
+++ b/backend/handlers/home.go
@@ -1,8 +1,9 @@
1package controllers 1package handlers
2 2
3import ( 3import (
4 "log" 4 "log"
5 "net/http" 5 "net/http"
6 "sort"
6 "strings" 7 "strings"
7 8
8 "github.com/gin-gonic/gin" 9 "github.com/gin-gonic/gin"
@@ -10,15 +11,15 @@ import (
10 "github.com/pektezol/leastportalshub/backend/models" 11 "github.com/pektezol/leastportalshub/backend/models"
11) 12)
12 13
13func Home(c *gin.Context) { 14type SearchResponse struct {
14 user, exists := c.Get("user") 15 Players []models.UserShort `json:"players"`
15 if !exists { 16 Maps []models.MapShort `json:"maps"`
16 c.JSON(200, "no id, not auth") 17}
17 } else { 18
18 c.JSON(200, gin.H{ 19type RankingsResponse struct {
19 "output": user, 20 Overall []models.UserRanking `json:"rankings_overall"`
20 }) 21 Singleplayer []models.UserRanking `json:"rankings_singleplayer"`
21 } 22 Multiplayer []models.UserRanking `json:"rankings_multiplayer"`
22} 23}
23 24
24// GET Rankings 25// GET Rankings
@@ -26,100 +27,104 @@ func Home(c *gin.Context) {
26// @Description Get rankings of every player. 27// @Description Get rankings of every player.
27// @Tags rankings 28// @Tags rankings
28// @Produce json 29// @Produce json
29// @Success 200 {object} models.Response{data=models.RankingsResponse} 30// @Success 200 {object} models.Response{data=RankingsResponse}
30// @Failure 400 {object} models.Response 31// @Failure 400 {object} models.Response
31// @Router /rankings [get] 32// @Router /rankings [get]
32func Rankings(c *gin.Context) { 33func Rankings(c *gin.Context) {
33 rows, err := database.DB.Query(`SELECT steam_id, user_name FROM users`) 34 response := RankingsResponse{
35 Overall: []models.UserRanking{},
36 Singleplayer: []models.UserRanking{},
37 Multiplayer: []models.UserRanking{},
38 }
39 // Singleplayer rankings
40 sql := `SELECT u.steam_id, u.user_name, COUNT(DISTINCT map_id),
41 (SELECT COUNT(maps.name) FROM maps INNER JOIN games g ON maps.game_id = g.id WHERE g.is_coop = FALSE AND is_disabled = false),
42 (SELECT SUM(min_score_count) AS total_min_score_count FROM (
43 SELECT
44 user_id,
45 MIN(score_count) AS min_score_count
46 FROM records_sp
47 GROUP BY user_id, map_id
48 ) AS subquery
49 WHERE user_id = u.steam_id)
50 FROM records_sp sp JOIN users u ON u.steam_id = sp.user_id GROUP BY u.steam_id, u.user_name`
51 rows, err := database.DB.Query(sql)
34 if err != nil { 52 if err != nil {
35 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 53 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
36 return 54 return
37 } 55 }
38 var spRankings []models.UserRanking
39 var mpRankings []models.UserRanking
40 for rows.Next() { 56 for rows.Next() {
41 var userID, username string 57 ranking := models.UserRanking{}
42 err := rows.Scan(&userID, &username) 58 var currentCount int
43 if err != nil { 59 var totalCount int
44 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 60 err = rows.Scan(&ranking.User.SteamID, &ranking.User.UserName, &currentCount, &totalCount, &ranking.TotalScore)
45 return
46 }
47 // Getting all sp records for each user
48 var uniqueSingleUserRecords, totalSingleMaps int
49 sql := `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps
50 WHERE is_coop = FALSE AND is_disabled = false) FROM records_sp WHERE user_id = $1`
51 err = database.DB.QueryRow(sql, userID).Scan(&uniqueSingleUserRecords, &totalSingleMaps)
52 if err != nil { 61 if err != nil {
53 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 62 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
54 return 63 return
55 } 64 }
56 // Has all singleplayer records 65 if currentCount != totalCount {
57 if uniqueSingleUserRecords == totalSingleMaps { 66 continue
58 var ranking models.UserRanking
59 ranking.UserID = userID
60 ranking.UserName = username
61 sql := `SELECT DISTINCT map_id, score_count FROM records_sp WHERE user_id = $1 ORDER BY map_id, score_count`
62 rows, err := database.DB.Query(sql, userID)
63 if err != nil {
64 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
65 return
66 }
67 totalScore := 0
68 var maps []int
69 for rows.Next() {
70 var mapID, scoreCount int
71 rows.Scan(&mapID, &scoreCount)
72 if len(maps) != 0 && maps[len(maps)-1] == mapID {
73 continue
74 }
75 totalScore += scoreCount
76 maps = append(maps, mapID)
77 }
78 ranking.TotalScore = totalScore
79 spRankings = append(spRankings, ranking)
80 } 67 }
81 // Getting all mp records for each user 68 response.Singleplayer = append(response.Singleplayer, ranking)
82 var uniqueMultiUserRecords, totalMultiMaps int 69 }
83 sql = `SELECT COUNT(DISTINCT map_id), (SELECT COUNT(map_name) FROM maps 70 // Multiplayer rankings
84 WHERE is_coop = TRUE AND is_disabled = false) FROM records_mp WHERE host_id = $1 OR partner_id = $2` 71 sql = `SELECT u.steam_id, u.user_name, COUNT(DISTINCT map_id),
85 err = database.DB.QueryRow(sql, userID, userID).Scan(&uniqueMultiUserRecords, &totalMultiMaps) 72 (SELECT COUNT(maps.name) FROM maps INNER JOIN games g ON maps.game_id = g.id WHERE g.is_coop = FALSE AND is_disabled = false),
73 (SELECT SUM(min_score_count) AS total_min_score_count FROM (
74 SELECT
75 host_id,
76 partner_id,
77 MIN(score_count) AS min_score_count
78 FROM records_mp
79 GROUP BY host_id, partner_id, map_id
80 ) AS subquery
81 WHERE host_id = u.steam_id OR partner_id = u.steam_id)
82 FROM records_mp mp JOIN users u ON u.steam_id = mp.host_id OR u.steam_id = mp.partner_id GROUP BY u.steam_id, u.user_name`
83 rows, err = database.DB.Query(sql)
84 if err != nil {
85 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
86 return
87 }
88 for rows.Next() {
89 ranking := models.UserRanking{}
90 var currentCount int
91 var totalCount int
92 err = rows.Scan(&ranking.User.SteamID, &ranking.User.UserName, &currentCount, &totalCount, &ranking.TotalScore)
86 if err != nil { 93 if err != nil {
87 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 94 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error()))
88 return 95 return
89 } 96 }
90 // Has all singleplayer records 97 if currentCount != totalCount {
91 if uniqueMultiUserRecords == totalMultiMaps { 98 continue
92 var ranking models.UserRanking 99 }
93 ranking.UserID = userID 100 response.Multiplayer = append(response.Multiplayer, ranking)
94 ranking.UserName = username 101 }
95 sql := `SELECT DISTINCT map_id, score_count FROM records_mp WHERE host_id = $1 OR partner_id = $2 ORDER BY map_id, score_count` 102 // Has both so they are qualified for overall ranking
96 rows, err := database.DB.Query(sql, userID, userID) 103 for _, spRanking := range response.Singleplayer {
97 if err != nil { 104 for _, mpRanking := range response.Multiplayer {
98 c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) 105 if spRanking.User.SteamID == mpRanking.User.SteamID {
99 return 106 totalScore := spRanking.TotalScore + mpRanking.TotalScore
100 } 107 overallRanking := models.UserRanking{
101 totalScore := 0 108 User: spRanking.User,
102 var maps []int 109 TotalScore: totalScore,
103 for rows.Next() {
104 var mapID, scoreCount int
105 rows.Scan(&mapID, &scoreCount)
106 if len(maps) != 0 && maps[len(maps)-1] == mapID {
107 continue
108 } 110 }
109 totalScore += scoreCount 111 response.Overall = append(response.Overall, overallRanking)
110 maps = append(maps, mapID)
111 } 112 }
112 ranking.TotalScore = totalScore
113 mpRankings = append(mpRankings, ranking)
114 } 113 }
115 } 114 }
115 sort.Slice(response.Singleplayer, func(i, j int) bool {
116 return response.Singleplayer[i].TotalScore < response.Singleplayer[j].TotalScore
117 })
118 sort.Slice(response.Multiplayer, func(i, j int) bool {
119 return response.Multiplayer[i].TotalScore < response.Multiplayer[j].TotalScore
120 })
121 sort.Slice(response.Overall, func(i, j int) bool {
122 return response.Overall[i].TotalScore < response.Overall[j].TotalScore
123 })
116 c.JSON(http.StatusOK, models.Response{ 124 c.JSON(http.StatusOK, models.Response{
117 Success: true, 125 Success: true,
118 Message: "Successfully retrieved rankings.", 126 Message: "Successfully retrieved rankings.",
119 Data: models.RankingsResponse{ 127 Data: response,
120 RankingsSP: spRankings,
121 RankingsMP: mpRankings,
122 },
123 }) 128 })
124} 129}
125 130
@@ -129,14 +134,14 @@ func Rankings(c *gin.Context) {
129// @Tags search 134// @Tags search
130// @Produce json 135// @Produce json
131// @Param q query string false "Search user or map name." 136// @Param q query string false "Search user or map name."
132// @Success 200 {object} models.Response{data=models.SearchResponse} 137// @Success 200 {object} models.Response{data=SearchResponse}
133// @Failure 400 {object} models.Response 138// @Failure 400 {object} models.Response
134// @Router /search [get] 139// @Router /search [get]
135func SearchWithQuery(c *gin.Context) { 140func SearchWithQuery(c *gin.Context) {
136 query := c.Query("q") 141 query := c.Query("q")
137 query = strings.ToLower(query) 142 query = strings.ToLower(query)
138 log.Println(query) 143 log.Println(query)
139 var response models.SearchResponse 144 var response SearchResponse
140 // Cache all maps for faster response 145 // Cache all maps for faster response
141 var maps = []models.MapShort{ 146 var maps = []models.MapShort{
142 {ID: 1, Name: "Container Ride"}, 147 {ID: 1, Name: "Container Ride"},