2024-04-29 14:26:46 -07:00
/ *
Copyright ( C ) 2024 Pagefault Games
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Affero General Public License for more details .
You should have received a copy of the GNU Affero General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
2024-04-29 12:32:58 -07:00
2023-12-05 10:28:08 -08:00
package db
import (
2024-04-06 14:43:11 -07:00
"fmt"
"slices"
2023-12-28 16:58:54 -08:00
_ "github.com/go-sql-driver/mysql"
2024-04-29 12:22:27 -07:00
"github.com/pagefaultgames/rogueserver/defs"
2023-12-05 10:28:08 -08:00
)
2023-12-28 16:53:59 -08:00
func AddAccountRecord ( uuid [ ] byte , username string , key , salt [ ] byte ) error {
2023-12-28 18:32:03 -08:00
_ , err := handle . Exec ( "INSERT INTO accounts (uuid, username, hash, salt, registered) VALUES (?, ?, ?, ?, UTC_TIMESTAMP())" , uuid , username , key , salt )
2023-12-28 16:53:59 -08:00
if err != nil {
return err
}
return nil
}
func AddAccountSession ( username string , token [ ] byte ) error {
2023-12-28 18:37:04 -08:00
_ , err := handle . Exec ( "INSERT INTO sessions (uuid, token, expire) SELECT a.uuid, ?, DATE_ADD(UTC_TIMESTAMP(), INTERVAL 1 WEEK) FROM accounts a WHERE a.username = ?" , token , username )
2023-12-28 16:53:59 -08:00
if err != nil {
2024-04-30 11:59:58 -07:00
return err
}
_ , err = handle . Exec ( "UPDATE sessions s JOIN accounts a ON a.uuid = s.uuid SET s.active = 1 WHERE a.username = ? AND a.lastLoggedIn IS NULL" , username )
if err != nil {
2023-12-28 16:53:59 -08:00
return err
}
2023-12-30 19:05:56 -08:00
_ , err = handle . Exec ( "UPDATE accounts SET lastLoggedIn = UTC_TIMESTAMP() WHERE username = ?" , username )
if err != nil {
return err
}
2023-12-28 16:53:59 -08:00
return nil
}
2024-04-28 14:27:58 -07:00
func UpdateAccountPassword ( uuid , key , salt [ ] byte ) error {
_ , err := handle . Exec ( "UPDATE accounts SET (hash, salt) VALUES (?, ?) WHERE uuid = ?" , key , salt , uuid )
if err != nil {
return err
}
return nil
}
2024-03-15 13:38:32 -07:00
func UpdateAccountLastActivity ( uuid [ ] byte ) error {
_ , err := handle . Exec ( "UPDATE accounts SET lastActivity = UTC_TIMESTAMP() WHERE uuid = ?" , uuid )
if err != nil {
return err
}
return nil
}
2024-04-11 07:13:35 -07:00
func UpdateAccountStats ( uuid [ ] byte , stats defs . GameStats , voucherCounts map [ string ] int ) error {
var columns = [ ] string { "playTime" , "battles" , "classicSessionsPlayed" , "sessionsWon" , "highestEndlessWave" , "highestLevel" , "pokemonSeen" , "pokemonDefeated" , "pokemonCaught" , "pokemonHatched" , "eggsPulled" , "regularVouchers" , "plusVouchers" , "premiumVouchers" , "goldenVouchers" }
2024-04-06 14:43:11 -07:00
var statCols [ ] string
var statValues [ ] interface { }
m , ok := stats . ( map [ string ] interface { } )
if ! ok {
return fmt . Errorf ( "expected map[string]interface{}, got %T" , stats )
}
for k , v := range m {
value , ok := v . ( float64 )
if ! ok {
return fmt . Errorf ( "expected float64, got %T" , v )
}
if slices . Contains ( columns , k ) {
statCols = append ( statCols , k )
statValues = append ( statValues , value )
}
}
2024-04-11 07:13:35 -07:00
for k , v := range voucherCounts {
var column string
switch k {
case "0" :
column = "regularVouchers"
case "1" :
column = "plusVouchers"
case "2" :
column = "premiumVouchers"
case "3" :
column = "goldenVouchers"
default :
continue
}
statCols = append ( statCols , column )
statValues = append ( statValues , v )
}
2024-04-06 14:43:11 -07:00
var statArgs [ ] interface { }
statArgs = append ( statArgs , uuid )
for range 2 {
statArgs = append ( statArgs , statValues ... )
}
query := "INSERT INTO accountStats (uuid"
for _ , col := range statCols {
query += ", " + col
}
query += ") VALUES (?"
for range len ( statCols ) {
query += ", ?"
}
query += ") ON DUPLICATE KEY UPDATE "
for i , col := range statCols {
if i > 0 {
query += ", "
}
query += col + " = ?"
}
_ , err := handle . Exec ( query , statArgs ... )
if err != nil {
return err
}
return nil
}
2024-04-09 19:22:00 -07:00
func FetchAndClaimAccountCompensations ( uuid [ ] byte ) ( map [ int ] int , error ) {
var compensations = make ( map [ int ] int )
results , err := handle . Query ( "SELECT voucherType, count FROM accountCompensations WHERE uuid = ?" , uuid )
if err != nil {
return nil , err
}
defer results . Close ( )
for results . Next ( ) {
var voucherType int
var count int
err := results . Scan ( & voucherType , & count )
if err != nil {
return compensations , err
}
compensations [ voucherType ] = count
}
_ , err = handle . Exec ( "UPDATE accountCompensations SET claimed = 1 WHERE uuid = ?" , uuid )
if err != nil {
return compensations , err
}
return compensations , nil
}
func DeleteClaimedAccountCompensations ( uuid [ ] byte ) error {
_ , err := handle . Exec ( "DELETE FROM accountCompensations WHERE uuid = ? AND claimed = 1" , uuid )
if err != nil {
return err
}
return nil
}
2024-03-18 16:55:02 -07:00
func FetchAccountKeySaltFromUsername ( username string ) ( [ ] byte , [ ] byte , error ) {
2023-12-28 16:53:59 -08:00
var key , salt [ ] byte
2023-12-28 18:32:03 -08:00
err := handle . QueryRow ( "SELECT hash, salt FROM accounts WHERE username = ?" , username ) . Scan ( & key , & salt )
2023-12-28 16:53:59 -08:00
if err != nil {
return nil , nil , err
}
return key , salt , nil
}
2024-04-25 12:11:26 -07:00
func FetchTrainerIds ( uuid [ ] byte ) ( trainerId , secretId int , err error ) {
2024-04-25 06:56:56 -07:00
err = handle . QueryRow ( "SELECT trainerId, secretId FROM accounts WHERE uuid = ?" , uuid ) . Scan ( & trainerId , & secretId )
if err != nil {
return 0 , 0 , err
}
return trainerId , secretId , nil
}
2024-04-25 12:11:26 -07:00
func UpdateTrainerIds ( trainerId , secretId int , uuid [ ] byte ) error {
2024-04-25 06:56:56 -07:00
_ , err := handle . Exec ( "UPDATE accounts SET trainerId = ?, secretId = ? WHERE uuid = ?" , trainerId , secretId , uuid )
if err != nil {
return err
}
return nil
}
2024-04-21 13:23:25 -07:00
func IsActiveSession ( token [ ] byte ) ( bool , error ) {
var active int
err := handle . QueryRow ( "SELECT `active` FROM sessions WHERE token = ?" , token ) . Scan ( & active )
if err != nil {
return false , err
}
return active == 1 , nil
}
func UpdateActiveSession ( uuid [ ] byte , token [ ] byte ) error {
_ , err := handle . Exec ( "UPDATE sessions SET `active` = CASE WHEN token = ? THEN 1 ELSE 0 END WHERE uuid = ?" , token , uuid )
if err != nil {
return err
}
return nil
}
2024-04-08 15:15:09 -07:00
func FetchUUIDFromToken ( token [ ] byte ) ( [ ] byte , error ) {
2023-12-28 16:53:59 -08:00
var uuid [ ] byte
2024-05-05 11:57:58 -07:00
err := handle . QueryRow ( "SELECT uuid FROM sessions WHERE token = ?" , token ) . Scan ( & uuid )
2023-12-28 16:53:59 -08:00
if err != nil {
return nil , err
}
return uuid , nil
}
func RemoveSessionFromToken ( token [ ] byte ) error {
_ , err := handle . Exec ( "DELETE FROM sessions WHERE token = ?" , token )
if err != nil {
return err
}
return nil
}
2024-05-05 13:12:10 -07:00
func FetchUsernameFromUUID ( uuid [ ] byte ) ( string , error ) {
var username string
err := handle . QueryRow ( "SELECT username FROM accounts WHERE uuid = ?" , uuid ) . Scan ( & username )
if err != nil {
return "" , err
}
return username , nil
}