2016-05-14 19:02:05 +00:00
|
|
|
package v1
|
|
|
|
|
2016-05-19 15:15:17 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
2016-05-14 19:02:05 +00:00
|
|
|
|
2016-05-19 15:15:17 +00:00
|
|
|
"git.zxq.co/ripple/rippleapi/common"
|
|
|
|
)
|
|
|
|
|
|
|
|
type userScore struct {
|
|
|
|
score
|
2016-07-18 21:27:37 +00:00
|
|
|
Beatmap beatmap `json:"beatmap"`
|
2016-05-19 15:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type userScoresResponse struct {
|
|
|
|
common.ResponseBase
|
|
|
|
Scores []userScore `json:"scores"`
|
|
|
|
}
|
|
|
|
|
|
|
|
const userScoreSelectBase = `
|
|
|
|
SELECT
|
|
|
|
scores.id, scores.beatmap_md5, scores.score,
|
|
|
|
scores.max_combo, scores.full_combo, scores.mods,
|
|
|
|
scores.300_count, scores.100_count, scores.50_count,
|
|
|
|
scores.gekis_count, scores.katus_count, scores.misses_count,
|
|
|
|
scores.time, scores.play_mode, scores.accuracy, scores.pp,
|
2016-05-22 14:22:13 +00:00
|
|
|
scores.completed,
|
2016-07-03 19:55:03 +00:00
|
|
|
|
2016-05-19 15:15:17 +00:00
|
|
|
beatmaps.beatmap_id, beatmaps.beatmapset_id, beatmaps.beatmap_md5,
|
2016-07-18 21:27:37 +00:00
|
|
|
beatmaps.song_name, beatmaps.ar, beatmaps.od, beatmaps.difficulty_std,
|
|
|
|
beatmaps.difficulty_taiko, beatmaps.difficulty_ctb, beatmaps.difficulty_mania,
|
2016-05-19 15:15:17 +00:00
|
|
|
beatmaps.max_combo, beatmaps.hit_length, beatmaps.ranked,
|
|
|
|
beatmaps.ranked_status_freezed, beatmaps.latest_update
|
|
|
|
FROM scores
|
2016-07-20 08:49:29 +00:00
|
|
|
INNER JOIN beatmaps ON beatmaps.beatmap_md5 = scores.beatmap_md5
|
|
|
|
INNER JOIN users ON users.id = scores.userid
|
2016-05-19 15:15:17 +00:00
|
|
|
`
|
|
|
|
|
|
|
|
// UserScoresBestGET retrieves the best scores of an user, sorted by PP if
|
|
|
|
// mode is standard and sorted by ranked score otherwise.
|
|
|
|
func UserScoresBestGET(md common.MethodData) common.CodeMessager {
|
|
|
|
cm, wc, param := whereClauseUser(md, "users")
|
|
|
|
if cm != nil {
|
|
|
|
return *cm
|
|
|
|
}
|
2016-05-26 19:13:36 +00:00
|
|
|
mc := genModeClause(md)
|
|
|
|
// Do not print 0pp scores on std
|
2016-08-15 17:59:46 +00:00
|
|
|
if getMode(md.Query("mode")) == "std" {
|
2016-05-26 19:13:36 +00:00
|
|
|
mc += " AND scores.pp > 0"
|
|
|
|
}
|
2016-05-19 15:15:17 +00:00
|
|
|
return scoresPuts(md, fmt.Sprintf(
|
|
|
|
`WHERE
|
2016-07-03 19:55:03 +00:00
|
|
|
scores.completed = '3'
|
2016-05-19 15:15:17 +00:00
|
|
|
AND %s
|
|
|
|
%s
|
2016-07-03 19:55:03 +00:00
|
|
|
AND users.privileges & 1 > 0
|
2016-05-19 15:15:17 +00:00
|
|
|
ORDER BY scores.pp DESC, scores.score DESC %s`,
|
2016-08-15 17:59:46 +00:00
|
|
|
wc, mc, common.Paginate(md.Query("p"), md.Query("l"), 100),
|
2016-05-19 15:31:49 +00:00
|
|
|
), param)
|
|
|
|
}
|
|
|
|
|
|
|
|
// UserScoresRecentGET retrieves an user's latest scores.
|
|
|
|
func UserScoresRecentGET(md common.MethodData) common.CodeMessager {
|
|
|
|
cm, wc, param := whereClauseUser(md, "users")
|
|
|
|
if cm != nil {
|
|
|
|
return *cm
|
|
|
|
}
|
|
|
|
return scoresPuts(md, fmt.Sprintf(
|
|
|
|
`WHERE
|
|
|
|
%s
|
|
|
|
%s
|
2016-07-03 19:55:03 +00:00
|
|
|
AND users.privileges & 1 > 0
|
2016-05-19 15:31:49 +00:00
|
|
|
ORDER BY scores.time DESC %s`,
|
2016-08-15 17:59:46 +00:00
|
|
|
wc, genModeClause(md), common.Paginate(md.Query("p"), md.Query("l"), 100),
|
2016-05-19 15:15:17 +00:00
|
|
|
), param)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getMode(m string) string {
|
|
|
|
switch m {
|
|
|
|
case "1":
|
|
|
|
return "taiko"
|
|
|
|
case "2":
|
|
|
|
return "ctb"
|
|
|
|
case "3":
|
|
|
|
return "mania"
|
|
|
|
default:
|
|
|
|
return "std"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-19 15:31:49 +00:00
|
|
|
func genModeClause(md common.MethodData) string {
|
|
|
|
var modeClause string
|
2016-08-15 17:59:46 +00:00
|
|
|
if md.Query("mode") != "" {
|
|
|
|
m, err := strconv.Atoi(md.Query("mode"))
|
2016-05-19 15:31:49 +00:00
|
|
|
if err == nil && m >= 0 && m <= 3 {
|
|
|
|
modeClause = fmt.Sprintf("AND scores.play_mode = '%d'", m)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return modeClause
|
|
|
|
}
|
|
|
|
|
2016-05-19 15:15:17 +00:00
|
|
|
func scoresPuts(md common.MethodData, whereClause string, params ...interface{}) common.CodeMessager {
|
|
|
|
rows, err := md.DB.Query(userScoreSelectBase+whereClause, params...)
|
|
|
|
if err != nil {
|
|
|
|
md.Err(err)
|
|
|
|
return Err500
|
|
|
|
}
|
|
|
|
var scores []userScore
|
|
|
|
for rows.Next() {
|
|
|
|
var (
|
2016-07-06 20:32:30 +00:00
|
|
|
us userScore
|
2016-07-18 21:27:37 +00:00
|
|
|
b beatmap
|
2016-05-19 15:15:17 +00:00
|
|
|
)
|
|
|
|
err = rows.Scan(
|
|
|
|
&us.ID, &us.BeatmapMD5, &us.Score,
|
|
|
|
&us.MaxCombo, &us.FullCombo, &us.Mods,
|
|
|
|
&us.Count300, &us.Count100, &us.Count50,
|
|
|
|
&us.CountGeki, &us.CountKatu, &us.CountMiss,
|
2016-08-15 17:59:46 +00:00
|
|
|
&us.Time, &us.PlayMode, &us.Accuracy, &us.PP,
|
2016-05-22 14:22:13 +00:00
|
|
|
&us.Completed,
|
2016-05-19 15:15:17 +00:00
|
|
|
|
|
|
|
&b.BeatmapID, &b.BeatmapsetID, &b.BeatmapMD5,
|
2016-07-18 21:27:37 +00:00
|
|
|
&b.SongName, &b.AR, &b.OD, &b.Diff2.STD,
|
|
|
|
&b.Diff2.Taiko, &b.Diff2.CTB, &b.Diff2.Mania,
|
2016-05-19 15:15:17 +00:00
|
|
|
&b.MaxCombo, &b.HitLength, &b.Ranked,
|
2016-07-06 20:32:30 +00:00
|
|
|
&b.RankedStatusFrozen, &b.LatestUpdate,
|
2016-05-19 15:15:17 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
md.Err(err)
|
|
|
|
return Err500
|
|
|
|
}
|
2016-08-15 17:59:46 +00:00
|
|
|
b.Difficulty = b.Diff2.STD
|
2016-07-18 21:27:37 +00:00
|
|
|
us.Beatmap = b
|
2016-05-19 15:15:17 +00:00
|
|
|
scores = append(scores, us)
|
|
|
|
}
|
|
|
|
r := userScoresResponse{}
|
|
|
|
r.Code = 200
|
|
|
|
r.Scores = scores
|
|
|
|
return r
|
2016-05-14 19:02:05 +00:00
|
|
|
}
|