Add daily run rankings

pull/1/head
Flashfyre 8 months ago
parent 71889f7daa
commit ff98047caa

@ -2,6 +2,8 @@ package api
import ( import (
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt"
"log" "log"
"net/http" "net/http"
"time" "time"
@ -34,3 +36,20 @@ func InitDailyRun() {
func (s *Server) HandleSeed(w http.ResponseWriter, r *http.Request) { func (s *Server) HandleSeed(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(dailyRunSeed)) w.Write([]byte(dailyRunSeed))
} }
// /daily/rankings - fetch daily rankings
func (s *Server) HandleRankings(w http.ResponseWriter, r *http.Request) {
rankings, err := db.GetRankings()
if err != nil {
log.Print("failed to retrieve rankings")
}
response, err := json.Marshal(rankings)
if err != nil {
http.Error(w, fmt.Sprintf("failed to marshal response json: %s", err), http.StatusInternalServerError)
return
}
w.Write(response)
}

@ -52,6 +52,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case "/daily/seed": case "/daily/seed":
s.HandleSeed(w, r) s.HandleSeed(w, r)
case "/daily/rankings":
s.HandleRankings(w, r)
} }
} }

@ -8,11 +8,12 @@ import (
"os" "os"
"strconv" "strconv"
"github.com/Flashfyre/pokerogue-server/defs"
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
) )
func GetSystemSaveData(uuid []byte) (SystemSaveData, error) { func GetSystemSaveData(uuid []byte) (defs.SystemSaveData, error) {
var system SystemSaveData var system defs.SystemSaveData
save, err := os.ReadFile("userdata/" + hex.EncodeToString(uuid) + "/system.pzs") save, err := os.ReadFile("userdata/" + hex.EncodeToString(uuid) + "/system.pzs")
if err != nil { if err != nil {
@ -39,8 +40,8 @@ func GetSystemSaveData(uuid []byte) (SystemSaveData, error) {
return system, nil return system, nil
} }
func GetSessionSaveData(uuid []byte, slotId int) (SessionSaveData, error) { func GetSessionSaveData(uuid []byte, slotId int) (defs.SessionSaveData, error) {
var session SessionSaveData var session defs.SessionSaveData
fileName := "session" fileName := "session"
if slotId != 0 { if slotId != 0 {
@ -72,7 +73,7 @@ func GetSessionSaveData(uuid []byte, slotId int) (SessionSaveData, error) {
return session, nil return session, nil
} }
func ValidateSessionCompleted(session SessionSaveData) bool { func ValidateSessionCompleted(session defs.SessionSaveData) bool {
switch session.GameMode { switch session.GameMode {
case 0: case 0:
return session.WaveIndex == 200 return session.WaveIndex == 200

@ -12,6 +12,7 @@ import (
"strconv" "strconv"
"github.com/Flashfyre/pokerogue-server/db" "github.com/Flashfyre/pokerogue-server/db"
"github.com/Flashfyre/pokerogue-server/defs"
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
) )
@ -90,7 +91,7 @@ func (s *Server) HandleSavedataUpdate(w http.ResponseWriter, r *http.Request) {
switch r.URL.Query().Get("datatype") { switch r.URL.Query().Get("datatype") {
case "0": // System case "0": // System
var system SystemSaveData var system defs.SystemSaveData
err = json.NewDecoder(r.Body).Decode(&system) err = json.NewDecoder(r.Body).Decode(&system)
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("failed to decode request body: %s", err), http.StatusBadRequest) http.Error(w, fmt.Sprintf("failed to decode request body: %s", err), http.StatusBadRequest)
@ -145,7 +146,7 @@ func (s *Server) HandleSavedataUpdate(w http.ResponseWriter, r *http.Request) {
fileName += strconv.Itoa(slotId) fileName += strconv.Itoa(slotId)
} }
var session SessionSaveData var session defs.SessionSaveData
err = json.NewDecoder(r.Body).Decode(&session) err = json.NewDecoder(r.Body).Decode(&session)
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("failed to decode request body: %s", err), http.StatusBadRequest) http.Error(w, fmt.Sprintf("failed to decode request body: %s", err), http.StatusBadRequest)
@ -268,7 +269,7 @@ func (s *Server) HandleSavedataClear(w http.ResponseWriter, r *http.Request) {
return return
} }
var session SessionSaveData var session defs.SessionSaveData
err = json.NewDecoder(r.Body).Decode(&session) err = json.NewDecoder(r.Body).Decode(&session)
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("failed to decode request body: %s", err), http.StatusBadRequest) http.Error(w, fmt.Sprintf("failed to decode request body: %s", err), http.StatusBadRequest)

@ -1,5 +1,9 @@
package db package db
import (
"github.com/Flashfyre/pokerogue-server/defs"
)
func TryAddDailyRun(seed string) error { func TryAddDailyRun(seed string) error {
_, err := handle.Exec("INSERT INTO dailyRuns (seed, date) VALUES (?, UTC_DATE()) ON DUPLICATE KEY UPDATE date = date", seed) _, err := handle.Exec("INSERT INTO dailyRuns (seed, date) VALUES (?, UTC_DATE()) ON DUPLICATE KEY UPDATE date = date", seed)
if err != nil { if err != nil {
@ -8,3 +12,26 @@ func TryAddDailyRun(seed string) error {
return nil return nil
} }
func GetRankings() ([]defs.DailyRanking, error) {
var rankings []defs.DailyRanking
results, err := handle.Query("SELECT RANK() OVER (ORDER BY sc.score DESC, sc.timestamp), a.username, sc.score FROM seedCompletions sc JOIN dailyRuns dr ON dr.seed = sc.seed JOIN accounts a ON sc.uuid = a.uuid WHERE dr.date = UTC_DATE()")
if err != nil {
return rankings, err
}
defer results.Close()
for results.Next() {
ranking := defs.DailyRanking{}
err = results.Scan(&ranking.Rank, &ranking.Username, &ranking.Score)
if err != nil {
return rankings, err
}
rankings = append(rankings, ranking)
}
return rankings, nil
}

@ -0,0 +1,7 @@
package defs
type DailyRanking struct {
Rank int `json:"rank"`
Username string `json:"username"`
Score int `json:"score"`
}

@ -1,103 +1,103 @@
package api package defs
type SystemSaveData struct { type SystemSaveData struct {
TrainerId int `json:"trainerId"` TrainerId int `json:"trainerId"`
SecretId int `json:"secretId"` SecretId int `json:"secretId"`
Gender int `json:"gender"` Gender int `json:"gender"`
DexData DexData `json:"dexData"` DexData DexData `json:"dexData"`
StarterMoveData StarterMoveData `json:"starterMoveData"` StarterMoveData StarterMoveData `json:"starterMoveData"`
StarterEggMoveData StarterEggMoveData `json:"starterEggMoveData"` StarterEggMoveData StarterEggMoveData `json:"starterEggMoveData"`
GameStats GameStats `json:"gameStats"` GameStats GameStats `json:"gameStats"`
Unlocks Unlocks `json:"unlocks"` Unlocks Unlocks `json:"unlocks"`
AchvUnlocks AchvUnlocks `json:"achvUnlocks"` AchvUnlocks AchvUnlocks `json:"achvUnlocks"`
VoucherUnlocks VoucherUnlocks `json:"voucherUnlocks"` VoucherUnlocks VoucherUnlocks `json:"voucherUnlocks"`
VoucherCounts VoucherCounts `json:"voucherCounts"` VoucherCounts VoucherCounts `json:"voucherCounts"`
Eggs []EggData `json:"eggs"` Eggs []EggData `json:"eggs"`
GameVersion string `json:"gameVersion"` GameVersion string `json:"gameVersion"`
Timestamp int `json:"timestamp"` Timestamp int `json:"timestamp"`
} }
type DexData map[int]DexEntry type DexData map[int]DexEntry
type DexEntry struct { type DexEntry struct {
SeenAttr interface{} `json:"seenAttr"` // integer or string SeenAttr interface{} `json:"seenAttr"` // integer or string
CaughtAttr interface{} `json:"caughtAttr"` // integer or string CaughtAttr interface{} `json:"caughtAttr"` // integer or string
NatureAttr int `json:"natureAttr"` NatureAttr int `json:"natureAttr"`
SeenCount int `json:"seenCount"` SeenCount int `json:"seenCount"`
CaughtCount int `json:"caughtCount"` CaughtCount int `json:"caughtCount"`
HatchedCount int `json:"hatchedCount"` HatchedCount int `json:"hatchedCount"`
Ivs []int `json:"ivs"` Ivs []int `json:"ivs"`
} }
type StarterMoveData map[int]interface{} type StarterMoveData map[int]interface{}
type StarterEggMoveData map[int]int type StarterEggMoveData map[int]int
type GameStats interface{} type GameStats interface{}
type Unlocks map[int]bool type Unlocks map[int]bool
type AchvUnlocks map[string]int type AchvUnlocks map[string]int
type VoucherUnlocks map[string]int type VoucherUnlocks map[string]int
type VoucherCounts map[string]int type VoucherCounts map[string]int
type EggData struct { type EggData struct {
Id int `json:"id"` Id int `json:"id"`
GachaType GachaType `json:"gachaType"` GachaType GachaType `json:"gachaType"`
HatchWaves int `json:"hatchWaves"` HatchWaves int `json:"hatchWaves"`
Timestamp int `json:"timestamp"` Timestamp int `json:"timestamp"`
} }
type GachaType int type GachaType int
type SessionSaveData struct { type SessionSaveData struct {
Seed string `json:"seed"` Seed string `json:"seed"`
PlayTime int `json:"playTime"` PlayTime int `json:"playTime"`
GameMode GameMode `json:"gameMode"` GameMode GameMode `json:"gameMode"`
Party []PokemonData `json:"party"` Party []PokemonData `json:"party"`
EnemyParty []PokemonData `json:"enemyParty"` EnemyParty []PokemonData `json:"enemyParty"`
Modifiers []PersistentModifierData `json:"modifiers"` Modifiers []PersistentModifierData `json:"modifiers"`
EnemyModifiers []PersistentModifierData `json:"enemyModifiers"` EnemyModifiers []PersistentModifierData `json:"enemyModifiers"`
Arena ArenaData `json:"arena"` Arena ArenaData `json:"arena"`
PokeballCounts PokeballCounts `json:"pokeballCounts"` PokeballCounts PokeballCounts `json:"pokeballCounts"`
Money int `json:"money"` Money int `json:"money"`
Score int `json:"score"` Score int `json:"score"`
WaveIndex int `json:"waveIndex"` WaveIndex int `json:"waveIndex"`
BattleType BattleType `json:"battleType"` BattleType BattleType `json:"battleType"`
Trainer TrainerData `json:"trainer"` Trainer TrainerData `json:"trainer"`
GameVersion string `json:"gameVersion"` GameVersion string `json:"gameVersion"`
Timestamp int `json:"timestamp"` Timestamp int `json:"timestamp"`
} }
type GameMode int type GameMode int
type PokemonData interface{} type PokemonData interface{}
type PersistentModifierData interface{} type PersistentModifierData interface{}
type ArenaData interface{} type ArenaData interface{}
type PokeballCounts map[string]int type PokeballCounts map[string]int
type BattleType int type BattleType int
type TrainerData interface{} type TrainerData interface{}
type SessionHistoryData struct { type SessionHistoryData struct {
Seed string `json:"seed"` Seed string `json:"seed"`
PlayTime int `json:"playTime"` PlayTime int `json:"playTime"`
Result SessionHistoryResult `json:"sessionHistoryResult"` Result SessionHistoryResult `json:"sessionHistoryResult"`
GameMode GameMode `json:"gameMode"` GameMode GameMode `json:"gameMode"`
Party []PokemonData `json:"party"` Party []PokemonData `json:"party"`
Modifiers []PersistentModifierData `json:"modifiers"` Modifiers []PersistentModifierData `json:"modifiers"`
Money int `json:"money"` Money int `json:"money"`
Score int `json:"score"` Score int `json:"score"`
WaveIndex int `json:"waveIndex"` WaveIndex int `json:"waveIndex"`
BattleType BattleType `json:"battleType"` BattleType BattleType `json:"battleType"`
GameVersion string `json:"gameVersion"` GameVersion string `json:"gameVersion"`
Timestamp int `json:"timestamp"` Timestamp int `json:"timestamp"`
} }
type SessionHistoryResult int type SessionHistoryResult int
Loading…
Cancel
Save