added friend support for rankings and rankingpagecount (friend = category 2)

This commit is contained in:
gamray 2024-05-18 13:38:56 +02:00
parent b93ef24411
commit b5d4118e96
4 changed files with 74 additions and 13 deletions

View File

@ -25,8 +25,8 @@ import (
) )
// /daily/rankings - fetch daily rankings // /daily/rankings - fetch daily rankings
func Rankings(category, page int) ([]defs.DailyRanking, error) { func Rankings(category, page int, uuid []byte) ([]defs.DailyRanking, error) {
rankings, err := db.FetchRankings(category, page) rankings, err := db.FetchRankings(category, page, uuid)
if err != nil { if err != nil {
log.Print("failed to retrieve rankings") log.Print("failed to retrieve rankings")
} }

View File

@ -24,8 +24,8 @@ import (
) )
// /daily/rankingpagecount - fetch daily ranking page count // /daily/rankingpagecount - fetch daily ranking page count
func RankingPageCount(category int) (int, error) { func RankingPageCount(category int, uuid []byte) (int, error) {
pageCount, err := db.FetchRankingPageCount(category) pageCount, err := db.FetchRankingPageCount(category, uuid)
if err != nil { if err != nil {
log.Print("failed to retrieve ranking page count") log.Print("failed to retrieve ranking page count")
} }

View File

@ -860,7 +860,11 @@ func handleDailySeed(w http.ResponseWriter, r *http.Request) {
} }
func handleDailyRankings(w http.ResponseWriter, r *http.Request) { func handleDailyRankings(w http.ResponseWriter, r *http.Request) {
var err error uuid, err := uuidFromRequest(r)
if err != nil {
httpError(w, r, err, http.StatusBadRequest)
return
}
var category int var category int
if r.URL.Query().Has("category") { if r.URL.Query().Has("category") {
@ -880,7 +884,7 @@ func handleDailyRankings(w http.ResponseWriter, r *http.Request) {
} }
} }
rankings, err := daily.Rankings(category, page) rankings, err := daily.Rankings(category, page, uuid)
if err != nil { if err != nil {
httpError(w, r, err, http.StatusInternalServerError) httpError(w, r, err, http.StatusInternalServerError)
return return
@ -890,6 +894,12 @@ func handleDailyRankings(w http.ResponseWriter, r *http.Request) {
} }
func handleDailyRankingPageCount(w http.ResponseWriter, r *http.Request) { func handleDailyRankingPageCount(w http.ResponseWriter, r *http.Request) {
uuid, err := uuidFromRequest(r)
if err != nil {
httpError(w, r, err, http.StatusBadRequest)
return
}
var category int var category int
if r.URL.Query().Has("category") { if r.URL.Query().Has("category") {
var err error var err error
@ -900,7 +910,7 @@ func handleDailyRankingPageCount(w http.ResponseWriter, r *http.Request) {
} }
} }
count, err := daily.RankingPageCount(category) count, err := daily.RankingPageCount(category, uuid)
if err != nil { if err != nil {
httpError(w, r, err, http.StatusInternalServerError) httpError(w, r, err, http.StatusInternalServerError)
} }

View File

@ -19,6 +19,7 @@ package db
import ( import (
"math" "math"
"database/sql"
"github.com/pagefaultgames/rogueserver/defs" "github.com/pagefaultgames/rogueserver/defs"
) )
@ -53,9 +54,14 @@ func AddOrUpdateAccountDailyRun(uuid []byte, score int, wave int) error {
return nil return nil
} }
func FetchRankings(category int, page int) ([]defs.DailyRanking, error) { func FetchRankings(category int, page int, uuid []byte) ([]defs.DailyRanking, error) {
var rankings []defs.DailyRanking var rankings []defs.DailyRanking
username, err := FetchUsernameFromUUID(uuid);
if err != nil {
return rankings, err
}
offset := (page - 1) * 10 offset := (page - 1) * 10
var query string var query string
@ -64,9 +70,36 @@ func FetchRankings(category int, page int) ([]defs.DailyRanking, error) {
query = "SELECT RANK() OVER (ORDER BY adr.score DESC, adr.timestamp), a.username, adr.score, adr.wave FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date = UTC_DATE() AND a.banned = 0 LIMIT 10 OFFSET ?" query = "SELECT RANK() OVER (ORDER BY adr.score DESC, adr.timestamp), a.username, adr.score, adr.wave FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date = UTC_DATE() AND a.banned = 0 LIMIT 10 OFFSET ?"
case 1: case 1:
query = "SELECT RANK() OVER (ORDER BY SUM(adr.score) DESC, adr.timestamp), a.username, SUM(adr.score), 0 FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date >= DATE_SUB(DATE(UTC_TIMESTAMP()), INTERVAL DAYOFWEEK(UTC_TIMESTAMP()) - 1 DAY) AND a.banned = 0 GROUP BY a.username ORDER BY 1 LIMIT 10 OFFSET ?" query = "SELECT RANK() OVER (ORDER BY SUM(adr.score) DESC, adr.timestamp), a.username, SUM(adr.score), 0 FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date >= DATE_SUB(DATE(UTC_TIMESTAMP()), INTERVAL DAYOFWEEK(UTC_TIMESTAMP()) - 1 DAY) AND a.banned = 0 GROUP BY a.username ORDER BY 1 LIMIT 10 OFFSET ?"
case 2:
// We retrieve the friends of the user and the user itself
query = `SELECT RANK() OVER (ORDER BY score DESC, timestamp) AS rank, username, score, wave
FROM (
SELECT a.username, adr.score, adr.wave, adr.timestamp
FROM accountDailyRuns adr
JOIN dailyRuns dr ON dr.date = adr.date
JOIN accounts a ON adr.uuid = a.uuid
JOIN friends f ON a.username = f.friend
WHERE dr.date = UTC_DATE()
AND a.banned = 0
AND f.user = ?
UNION
SELECT a.username, adr.score, adr.wave, adr.timestamp
FROM accountDailyRuns adr
JOIN dailyRuns dr ON dr.date = adr.date
JOIN accounts a ON adr.uuid = a.uuid
WHERE dr.date = UTC_DATE()
AND a.banned = 0
AND a.username = ?
) AS combined LIMIT 10 OFFSET ?;`
}
var results *sql.Rows
if category == 2 {
results, err = handle.Query(query, username, username, offset)
} else {
results, err = handle.Query(query, offset)
} }
results, err := handle.Query(query, offset)
if err != nil { if err != nil {
return rankings, err return rankings, err
} }
@ -86,19 +119,37 @@ func FetchRankings(category int, page int) ([]defs.DailyRanking, error) {
return rankings, nil return rankings, nil
} }
func FetchRankingPageCount(category int) (int, error) { func FetchRankingPageCount(category int, uuid []byte) (int, error) {
username, err := FetchUsernameFromUUID(uuid);
if err != nil {
return 0, err
}
var query string var query string
switch category { switch category {
case 0: case 0:
query = "SELECT COUNT(a.username) FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date = UTC_DATE()" query = "SELECT COUNT(a.username) FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date = UTC_DATE()"
case 1: case 1:
query = "SELECT COUNT(DISTINCT a.username) FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date >= DATE_SUB(DATE(UTC_TIMESTAMP()), INTERVAL DAYOFWEEK(UTC_TIMESTAMP()) - 1 DAY)" query = "SELECT COUNT(DISTINCT a.username) FROM accountDailyRuns adr JOIN dailyRuns dr ON dr.date = adr.date JOIN accounts a ON adr.uuid = a.uuid WHERE dr.date >= DATE_SUB(DATE(UTC_TIMESTAMP()), INTERVAL DAYOFWEEK(UTC_TIMESTAMP()) - 1 DAY)"
case 2:
query = `SELECT COUNT(a.username)
FROM accountDailyRuns adr
JOIN dailyRuns dr ON dr.date = adr.date
JOIN accounts a ON adr.uuid = a.uuid
JOIN friends f ON a.username = f.friend
WHERE dr.date = UTC_DATE()
AND f.user = ?
OR a.username = ?`
} }
var recordCount int var recordCount int
err := handle.QueryRow(query).Scan(&recordCount) if category == 2 {
if err != nil { err = handle.QueryRow(query, username, username).Scan(&recordCount)
return 0, err // We only fetch friends of the account, not the account itself so adding +1 here.
// this way, we don't have to do the big union query like in FetchRankings
recordCount += 1
} else {
err = handle.QueryRow(query).Scan(&recordCount)
} }
return int(math.Ceil(float64(recordCount) / 10)), nil return int(math.Ceil(float64(recordCount) / 10)), nil