diff --git a/api/account/discord.go b/api/account/discord.go
index bf2a00f..176cb9f 100644
--- a/api/account/discord.go
+++ b/api/account/discord.go
@@ -41,6 +41,7 @@ func HandleDiscordCallback(w http.ResponseWriter, r *http.Request) (string, erro
http.Redirect(w, r, GameURL, http.StatusSeeOther)
return "", errors.New("code is empty")
}
+
discordId, err := RetrieveDiscordId(code)
if err != nil {
http.Redirect(w, r, GameURL, http.StatusSeeOther)
diff --git a/api/account/login.go b/api/account/login.go
index f9b6034..8eb7d49 100644
--- a/api/account/login.go
+++ b/api/account/login.go
@@ -75,5 +75,6 @@ func GenerateTokenForUsername(username string) (string, error) {
if err != nil {
return "", fmt.Errorf("failed to add account session")
}
+
return base64.StdEncoding.EncodeToString(token), nil
}
diff --git a/api/daily/common.go b/api/daily/common.go
index 63353d7..521bf53 100644
--- a/api/daily/common.go
+++ b/api/daily/common.go
@@ -40,9 +40,8 @@ import (
const secondsPerDay = 60 * 60 * 24
var (
- scheduler = cron.New(cron.WithLocation(time.UTC))
- s3scheduler = cron.New(cron.WithLocation(time.UTC))
- secret []byte
+ scheduler = cron.New(cron.WithLocation(time.UTC))
+ secret []byte
)
func Init() error {
@@ -91,22 +90,17 @@ func Init() error {
scheduler.Start()
- if os.Getenv("AWS_ENDPOINT_URL_S3") == "" {
- log.Printf("AWS_ENDPOINT_URL_S3 not set, skipping s3 migration")
- return nil
+ if os.Getenv("AWS_ENDPOINT_URL_S3") != "" {
+ go func() {
+ for {
+ err = S3SaveMigration()
+ if err != nil {
+ return
+ }
+ }
+ }()
}
- _, err = s3scheduler.AddFunc("@hourly", func() {
- time.Sleep(time.Second)
- S3SaveMigration()
- })
-
- if err != nil {
- return err
- }
-
- s3scheduler.Start()
-
return nil
}
@@ -123,38 +117,60 @@ func deriveSeed(seedTime time.Time) []byte {
return hashedSeed[:]
}
-func S3SaveMigration() {
+func S3SaveMigration() error {
cfg, _ := config.LoadDefaultConfig(context.TODO())
svc := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String(os.Getenv("AWS_ENDPOINT_URL_S3"))
})
- // retrieve accounts from db
+
_, err := svc.CreateBucket(context.Background(), &s3.CreateBucketInput{
Bucket: aws.String("pokerogue-system"),
})
-
if err != nil {
- log.Printf("error while creating bucket: %s", err)
+ log.Printf("error while creating bucket (already exists?): %s", err)
+ }
+
+ // retrieve accounts from db
+ accounts, err := db.RetrieveOldAccounts()
+ if err != nil {
+ return fmt.Errorf("failed to retrieve old accounts: %s", err)
}
- accounts := db.RetrieveOldAccounts()
for _, user := range accounts {
- data, _ := db.ReadSystemSaveData(user)
- username, _ := db.FetchUsernameFromUUID(user)
- json, _ := json.Marshal(data)
- _, err := svc.PutObject(context.Background(), &s3.PutObjectInput{
+ data, err := db.ReadSystemSaveData(user)
+ if err != nil {
+ continue
+ }
+
+ username, err := db.FetchUsernameFromUUID(user)
+ if err != nil {
+ continue
+ }
+
+ json, err := json.Marshal(data)
+ if err != nil {
+ continue
+ }
+
+ _, err = svc.PutObject(context.Background(), &s3.PutObjectInput{
Bucket: aws.String("pokerogue-system"),
Key: aws.String(username),
Body: bytes.NewReader(json),
})
-
if err != nil {
- log.Printf("error while saving data in s3 for user %s: %s", username, err)
+ log.Printf("error while saving data in S3 for user %s: %s", username, err)
continue
}
- fmt.Printf("Saved data in s3 for user %s\n", username)
- db.UpdateLocation(user, username)
+ err = db.UpdateLocation(user, username)
+ if err != nil {
+ log.Printf("failed to update location for user %s: %s", username, err)
+ continue
+ }
+
+ log.Printf("saved data in S3 for user %s", username)
}
+
+ return nil
}
diff --git a/api/endpoints.go b/api/endpoints.go
index 0e9b9bf..478b434 100644
--- a/api/endpoints.go
+++ b/api/endpoints.go
@@ -420,8 +420,7 @@ func handleSystem(w http.ResponseWriter, r *http.Request) {
if errors.Is(err, sql.ErrNoRows) {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
- fmt.Printf("failed to get system save data: %s\n", err)
- httpError(w, r, err, http.StatusInternalServerError)
+ httpError(w, r, fmt.Errorf("failed to get system save data: %s", err), http.StatusInternalServerError)
}
return
@@ -751,36 +750,36 @@ func handleAdminDiscordUnlink(w http.ResponseWriter, r *http.Request) {
discordId := r.Form.Get("discordId")
switch {
- case username != "":
- log.Printf("Username given, removing discordId")
- // this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
- // this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
- _, err = db.CheckUsernameExists(username)
- if err != nil {
- httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
- return
- }
+ case username != "":
+ log.Printf("Username given, removing discordId")
+ // this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
+ // this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
+ _, err = db.CheckUsernameExists(username)
+ if err != nil {
+ httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
+ return
+ }
- userUuid, err := db.FetchUUIDFromUsername(username)
- if err != nil {
- httpError(w, r, err, http.StatusInternalServerError)
- return
- }
+ userUuid, err := db.FetchUUIDFromUsername(username)
+ if err != nil {
+ httpError(w, r, err, http.StatusInternalServerError)
+ return
+ }
- err = db.RemoveDiscordIdByUUID(userUuid)
- if err != nil {
- httpError(w, r, err, http.StatusInternalServerError)
- return
- }
- case discordId != "":
- log.Printf("DiscordID given, removing discordId")
- err = db.RemoveDiscordIdByDiscordId(discordId)
- if err != nil {
- httpError(w, r, err, http.StatusInternalServerError)
- return
- }
+ err = db.RemoveDiscordIdByUUID(userUuid)
+ if err != nil {
+ httpError(w, r, err, http.StatusInternalServerError)
+ return
+ }
+ case discordId != "":
+ log.Printf("DiscordID given, removing discordId")
+ err = db.RemoveDiscordIdByDiscordId(discordId)
+ if err != nil {
+ httpError(w, r, err, http.StatusInternalServerError)
+ return
+ }
}
-
+
log.Printf("%s: %s removed discord id %s from username %s", userDiscordId, r.URL.Path, r.Form.Get("discordId"), r.Form.Get("username"))
w.WriteHeader(http.StatusOK)
@@ -821,7 +820,7 @@ func handleAdminGoogleLink(w http.ResponseWriter, r *http.Request) {
httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
return
}
-
+
userUuid, err := db.FetchUUIDFromUsername(username)
if err != nil {
httpError(w, r, err, http.StatusInternalServerError)
@@ -868,34 +867,34 @@ func handleAdminGoogleUnlink(w http.ResponseWriter, r *http.Request) {
googleId := r.Form.Get("googleId")
switch {
- case username != "":
- log.Printf("Username given, removing googleId")
- // this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
- // this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
- _, err = db.CheckUsernameExists(username)
- if err != nil {
- httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
- return
- }
+ case username != "":
+ log.Printf("Username given, removing googleId")
+ // this does a quick call to make sure the username exists on the server before allowing the rest of the code to run
+ // this calls error value 404 (StatusNotFound) if there's no data; this means the username does not exist in the server
+ _, err = db.CheckUsernameExists(username)
+ if err != nil {
+ httpError(w, r, fmt.Errorf("username does not exist on the server"), http.StatusNotFound)
+ return
+ }
- userUuid, err := db.FetchUUIDFromUsername(username)
- if err != nil {
- httpError(w, r, err, http.StatusInternalServerError)
- return
- }
+ userUuid, err := db.FetchUUIDFromUsername(username)
+ if err != nil {
+ httpError(w, r, err, http.StatusInternalServerError)
+ return
+ }
- err = db.RemoveGoogleIdByUUID(userUuid)
- if err != nil {
- httpError(w, r, err, http.StatusInternalServerError)
- return
- }
- case googleId != "":
- log.Printf("DiscordID given, removing googleId")
- err = db.RemoveGoogleIdByDiscordId(googleId)
- if err != nil {
- httpError(w, r, err, http.StatusInternalServerError)
- return
- }
+ err = db.RemoveGoogleIdByUUID(userUuid)
+ if err != nil {
+ httpError(w, r, err, http.StatusInternalServerError)
+ return
+ }
+ case googleId != "":
+ log.Printf("DiscordID given, removing googleId")
+ err = db.RemoveGoogleIdByDiscordId(googleId)
+ if err != nil {
+ httpError(w, r, err, http.StatusInternalServerError)
+ return
+ }
}
log.Printf("%s: %s removed google id %s from username %s", userDiscordId, r.URL.Path, r.Form.Get("googleId"), r.Form.Get("username"))
diff --git a/api/savedata/session.go b/api/savedata/session.go
index 78ff85d..d750f7a 100644
--- a/api/savedata/session.go
+++ b/api/savedata/session.go
@@ -1,3 +1,20 @@
+/*
+ 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 .
+*/
+
package savedata
import (
diff --git a/api/savedata/system.go b/api/savedata/system.go
index 112060b..6c02f2a 100644
--- a/api/savedata/system.go
+++ b/api/savedata/system.go
@@ -1,3 +1,20 @@
+/*
+ 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 .
+*/
+
package savedata
import (
diff --git a/db/account.go b/db/account.go
index b04da77..8a98f5a 100644
--- a/db/account.go
+++ b/db/account.go
@@ -86,7 +86,6 @@ func AddDiscordIdByUUID(discordId string, uuid []byte) error {
return nil
}
-
func FetchUsernameByDiscordId(discordId string) (string, error) {
var username string
err := handle.QueryRow("SELECT username FROM accounts WHERE discordId = ?", discordId).Scan(&username)
@@ -478,4 +477,4 @@ func RemoveGoogleIdByDiscordId(discordId string) error {
}
return nil
-}
\ No newline at end of file
+}
diff --git a/db/db.go b/db/db.go
index b8b79c0..04fec2d 100644
--- a/db/db.go
+++ b/db/db.go
@@ -116,5 +116,6 @@ func setupDb(tx *sql.Tx) error {
return fmt.Errorf("failed to execute query: %w, query: %s", err, q)
}
}
+
return nil
}
diff --git a/db/savedata.go b/db/savedata.go
index aed1eee..4974c4c 100644
--- a/db/savedata.go
+++ b/db/savedata.go
@@ -68,8 +68,13 @@ func ReadSystemSaveData(uuid []byte) (defs.SystemSaveData, error) {
}
if !isLocal {
- RetrieveSystemSaveFromS3(uuid)
+ // writes the data back into the database
+ err = RetrieveSystemSaveFromS3(uuid)
+ if err != nil {
+ return system, err
+ }
}
+
var data []byte
err = handle.QueryRow("SELECT data FROM systemSaveData WHERE uuid = ?", uuid).Scan(&data)
if err != nil {
@@ -220,6 +225,11 @@ func isSaveInLocalDb(uuid []byte) (bool, error) {
}
func RetrieveSystemSaveFromS3(uuid []byte) error {
+ username, err := FetchUsernameFromUUID(uuid)
+ if err != nil {
+ return err
+ }
+
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
return err
@@ -227,31 +237,26 @@ func RetrieveSystemSaveFromS3(uuid []byte) error {
client := s3.NewFromConfig(cfg)
- username, err := FetchUsernameFromUUID(uuid)
- if err != nil {
- return err
- }
-
- s3Object := &s3.GetObjectInput{
+ s3Object := s3.GetObjectInput{
Bucket: aws.String("pokerogue-system"),
Key: aws.String(username),
}
- resp, err := client.GetObject(context.TODO(), s3Object)
+ resp, err := client.GetObject(context.TODO(), &s3Object)
if err != nil {
return err
}
var session defs.SystemSaveData
- json.NewDecoder(resp.Body).Decode(&session)
-
- err = StoreSystemSaveData(uuid, session)
+ err = json.NewDecoder(resp.Body).Decode(&session)
if err != nil {
- fmt.Printf("Failed to store system save data from s3 for user %s\n", username)
return err
}
- fmt.Printf("Retrieved system save data from s3 for user %s\n", username)
+ err = StoreSystemSaveData(uuid, session)
+ if err != nil {
+ return fmt.Errorf("failed to store system save data from S3 for user %s: %s", username, err)
+ }
_, err = handle.Exec("UPDATE accounts SET isInLocalDb = 1 WHERE uuid = ?", uuid)
if err != nil {
@@ -262,41 +267,45 @@ func RetrieveSystemSaveFromS3(uuid []byte) error {
Bucket: aws.String("pokerogue-system"),
Key: aws.String(username),
})
-
if err != nil {
- fmt.Printf("Failed to delete object %s from s3: %s\n", username, err)
+ return fmt.Errorf("failed to delete object %s from S3: %s", username, err)
}
+
return nil
}
-func RetrieveOldAccounts() [][]byte {
+func RetrieveOldAccounts() ([][]byte, error) {
var users [][]byte
- rows, err := handle.Query("SELECT uuid FROM accounts WHERE isInLocalDb = 1 && lastActivity < DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 3000")
+ rows, err := handle.Query("SELECT uuid FROM accounts WHERE isInLocalDb = 1 AND lastActivity < DATE_SUB(NOW(), INTERVAL 3 MONTH) LIMIT 3000")
if err != nil {
- return nil
+ return nil, err
}
+
defer rows.Close()
for rows.Next() {
var uuid []byte
- if err := rows.Scan(&uuid); err != nil {
- return nil
+ err := rows.Scan(&uuid)
+ if err != nil {
+ return nil, err
}
+
users = append(users, uuid)
}
- if err := rows.Err(); err != nil {
- return nil
- }
- return users
+ return users, nil
}
-func UpdateLocation(uuid []byte, username string) {
+func UpdateLocation(uuid []byte, username string) error {
_, err := handle.Exec("UPDATE accounts SET isInLocalDb = 0 WHERE uuid = ?", uuid)
if err != nil {
- fmt.Printf("Failed to update location for user %s\n", username)
- return
+ return err
}
- DeleteSystemSaveData(uuid)
+ err = DeleteSystemSaveData(uuid)
+ if err != nil {
+ return err
+ }
+
+ return nil
}
diff --git a/rogueserver.go b/rogueserver.go
index c54c6de..b69631d 100644
--- a/rogueserver.go
+++ b/rogueserver.go
@@ -70,6 +70,7 @@ func main() {
account.GoogleCallbackURL = callbackurl + "/auth/google/callback"
account.DiscordSession, _ = discordgo.New("Bot " + discordbottoken)
account.DiscordGuildID = discordguildid
+
// register gob types
gob.Register([]interface{}{})
gob.Register(map[string]interface{}{})