Update random daily seed logic

pull/1/head
Flashfyre 2024-03-18 19:55:02 -04:00
parent 2cb7be52eb
commit be04408336
9 changed files with 63 additions and 66 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
pokerogue-server.exe
userdata/*
key
secret.key

View File

@ -22,7 +22,7 @@ func GetUsernameFromRequest(request *http.Request) (string, error) {
return "", fmt.Errorf("invalid token length: got %d, expected 32", len(token))
}
username, err := db.GetUsernameFromToken(token)
username, err := db.FetchUsernameFromToken(token)
if err != nil {
return "", fmt.Errorf("failed to validate token: %s", err)
}
@ -44,7 +44,7 @@ func GetUuidFromRequest(request *http.Request) ([]byte, error) {
return nil, fmt.Errorf("invalid token length: got %d, expected 32", len(token))
}
uuid, err := db.GetUuidFromToken(token)
uuid, err := db.FetchUuidFromToken(token)
if err != nil {
return nil, fmt.Errorf("failed to validate token: %s", err)
}

View File

@ -144,7 +144,7 @@ func (s *Server) HandleAccountLogin(w http.ResponseWriter, r *http.Request) {
return
}
key, salt, err := db.GetAccountKeySaltFromUsername(request.Username)
key, salt, err := db.FetchAccountKeySaltFromUsername(request.Username)
if err != nil {
if err == sql.ErrNoRows {
http.Error(w, "account doesn't exist", http.StatusBadRequest)

View File

@ -1,16 +1,25 @@
package api
import (
"crypto/md5"
"crypto/rand"
"encoding/base64"
"encoding/binary"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"
"github.com/Flashfyre/pokerogue-server/db"
)
const secondsPerDay = 60 * 60 * 24
var (
dailyRunSecret []byte
dailyRunSeed string
)
@ -21,24 +30,48 @@ func ScheduleDailyRunRefresh() {
}
func InitDailyRun() {
var err error
dailyRunSeed, err = db.GetDailyRunSeed()
secret, err := os.ReadFile("secret.key")
if err != nil {
log.Printf("failed to generated daily run seed: %s", err.Error())
if !os.IsNotExist(err) {
log.Fatalf("failed to read daily seed secret: %s", err)
}
if dailyRunSeed == "" {
dailyRunSeed = RandString(24)
err := db.TryAddDailyRun(dailyRunSeed)
newSecret := make([]byte, 32)
_, err := rand.Read(newSecret)
if err != nil {
log.Fatalf("failed to generate daily seed secret: %s", err)
}
err = os.WriteFile("secret.key", newSecret, 0400)
if err != nil {
log.Fatalf("failed to write daily seed secret: %s", err)
}
secret = newSecret
}
dailyRunSecret = secret
dailyRunSeed = base64.StdEncoding.EncodeToString(DeriveDailyRunSeed(time.Now().UTC()))
err = db.TryAddDailyRun(dailyRunSeed)
if err != nil {
log.Print(err.Error())
} else {
log.Printf("Daily Run Seed: %s", dailyRunSeed)
}
}
func DeriveDailyRunSeed(seedTime time.Time) []byte {
day := make([]byte, 8)
binary.BigEndian.PutUint64(day, uint64(seedTime.Unix()/secondsPerDay))
hashedSeed := md5.Sum(append(day, dailyRunSecret...))
return hashedSeed[:]
}
// /daily/seed - get daily run seed
// /daily/seed - fetch daily run seed
func (s *Server) HandleSeed(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(dailyRunSeed))
@ -60,7 +93,7 @@ func (s *Server) HandleRankings(w http.ResponseWriter, r *http.Request) {
page = 1
}
rankings, err := db.GetRankings(page)
rankings, err := db.FetchRankings(page)
if err != nil {
log.Print("failed to retrieve rankings")
}

View File

@ -12,7 +12,7 @@ import (
"github.com/klauspost/compress/zstd"
)
func GetSystemSaveData(uuid []byte) (defs.SystemSaveData, error) {
func ReadSystemSaveData(uuid []byte) (defs.SystemSaveData, error) {
var system defs.SystemSaveData
save, err := os.ReadFile("userdata/" + hex.EncodeToString(uuid) + "/system.pzs")
@ -40,7 +40,7 @@ func GetSystemSaveData(uuid []byte) (defs.SystemSaveData, error) {
return system, nil
}
func GetSessionSaveData(uuid []byte, slotId int) (defs.SessionSaveData, error) {
func ReadSessionSaveData(uuid []byte, slotId int) (defs.SessionSaveData, error) {
var session defs.SessionSaveData
fileName := "session"
@ -76,9 +76,9 @@ func GetSessionSaveData(uuid []byte, slotId int) (defs.SessionSaveData, error) {
func ValidateSessionCompleted(session defs.SessionSaveData) bool {
switch session.GameMode {
case 0:
return session.WaveIndex == 200
return session.BattleType == 2 && session.WaveIndex == 200
case 3:
return session.WaveIndex == 50
return session.BattleType == 2 && session.WaveIndex == 50
}
return false
}

View File

@ -29,7 +29,7 @@ func (s *Server) HandleSavedataGet(w http.ResponseWriter, r *http.Request) {
switch r.URL.Query().Get("datatype") {
case "0": // System
system, err := GetSystemSaveData(uuid)
system, err := ReadSystemSaveData(uuid)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@ -54,7 +54,7 @@ func (s *Server) HandleSavedataGet(w http.ResponseWriter, r *http.Request) {
return
}
session, err := GetSessionSaveData(uuid, slotId)
session, err := ReadSessionSaveData(uuid, slotId)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@ -276,12 +276,12 @@ func (s *Server) HandleSavedataClear(w http.ResponseWriter, r *http.Request) {
return
}
sessionCompleted := session.BattleType == 2 && ValidateSessionCompleted(session)
sessionCompleted := ValidateSessionCompleted(session)
newCompletion := false
if session.GameMode == 3 {
waveCompleted := session.WaveIndex
if session.BattleType != 2 {
if !sessionCompleted {
waveCompleted--
}
err = db.AddOrUpdateAccountDailyRun(uuid, session.Score, waveCompleted)

View File

@ -1,20 +0,0 @@
package api
import (
"crypto/rand"
)
const randRunes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
const lenRandRunes = len(randRunes)
func RandString(length int) string {
b := make([]byte, length)
rand.Read(b)
for i := range b {
b[i] = randRunes[int(b[i])%lenRandRunes]
}
return string(b)
}

View File

@ -38,7 +38,7 @@ func UpdateAccountLastActivity(uuid []byte) error {
return nil
}
func GetUsernameFromToken(token []byte) (string, error) {
func FetchUsernameFromToken(token []byte) (string, error) {
var username string
err := handle.QueryRow("SELECT a.username FROM accounts a JOIN sessions s ON s.uuid = a.uuid WHERE s.token = ? AND s.expire > UTC_TIMESTAMP()", token).Scan(&username)
if err != nil {
@ -48,7 +48,7 @@ func GetUsernameFromToken(token []byte) (string, error) {
return username, nil
}
func GetAccountKeySaltFromUsername(username string) ([]byte, []byte, error) {
func FetchAccountKeySaltFromUsername(username string) ([]byte, []byte, error) {
var key, salt []byte
err := handle.QueryRow("SELECT hash, salt FROM accounts WHERE username = ?", username).Scan(&key, &salt)
if err != nil {
@ -58,7 +58,7 @@ func GetAccountKeySaltFromUsername(username string) ([]byte, []byte, error) {
return key, salt, nil
}
func GetUuidFromToken(token []byte) ([]byte, error) {
func FetchUuidFromToken(token []byte) ([]byte, error) {
var uuid []byte
err := handle.QueryRow("SELECT uuid FROM sessions WHERE token = ? AND expire > UTC_TIMESTAMP()", token).Scan(&uuid)
if err != nil {

View File

@ -1,8 +1,6 @@
package db
import (
"database/sql"
"github.com/Flashfyre/pokerogue-server/defs"
)
@ -15,20 +13,6 @@ func TryAddDailyRun(seed string) error {
return nil
}
func GetDailyRunSeed() (string, error) {
var seed string
err := handle.QueryRow("SELECT seed FROM dailyRuns WHERE date = UTC_DATE()").Scan(&seed)
if err != nil {
if err == sql.ErrNoRows {
return "", err
}
return "", err
}
return seed, nil
}
func AddOrUpdateAccountDailyRun(uuid []byte, score int, wave int) error {
_, err := handle.Exec("INSERT INTO accountDailyRuns (uuid, date, score, wave, timestamp) VALUES (?, UTC_DATE(), ?, ?, UTC_TIMESTAMP()) ON DUPLICATE KEY UPDATE score = ?, wave = GREATEST(wave, ?), timestamp = IF(score < ?, UTC_TIMESTAMP(), timestamp)", uuid, score, wave, score, wave, score)
if err != nil {
@ -38,7 +22,7 @@ func AddOrUpdateAccountDailyRun(uuid []byte, score int, wave int) error {
return nil
}
func GetRankings(page int) ([]defs.DailyRanking, error) {
func FetchRankings(page int) ([]defs.DailyRanking, error) {
var rankings []defs.DailyRanking
offset := (page - 1) * 10