Improve default JSON Encoder; Other organising features,

This commit is contained in:
eccentric 2023-11-09 18:53:19 +00:00
parent 5237402c5e
commit 5c6b1d6407
9 changed files with 58 additions and 149 deletions

View File

@ -1,10 +1,11 @@
package aid package aid
import ( import (
"encoding/json"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"github.com/goccy/go-json"
) )
func WaitForExit() { func WaitForExit() {

View File

@ -1,9 +1,10 @@
package aid package aid
import ( import (
"encoding/json"
"fmt" "fmt"
"time" "time"
"github.com/goccy/go-json"
) )
func Print(v ...interface{}) { func Print(v ...interface{}) {

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.21.3
require ( require (
github.com/andybalholm/brotli v1.0.6 // indirect github.com/andybalholm/brotli v1.0.6 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gofiber/fiber/v2 v2.50.0 // indirect github.com/gofiber/fiber/v2 v2.50.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/google/uuid v1.4.0 // indirect github.com/google/uuid v1.4.0 // indirect

2
go.sum
View File

@ -86,6 +86,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofiber/fiber/v2 v2.50.0 h1:ia0JaB+uw3GpNSCR5nvC5dsaxXjRU5OEu36aytx+zGw= github.com/gofiber/fiber/v2 v2.50.0 h1:ia0JaB+uw3GpNSCR5nvC5dsaxXjRU5OEu36aytx+zGw=
github.com/gofiber/fiber/v2 v2.50.0/go.mod h1:21eytvay9Is7S6z+OgPi7c7n4++tnClWmhpimVHMimw= github.com/gofiber/fiber/v2 v2.50.0/go.mod h1:21eytvay9Is7S6z+OgPi7c7n4++tnClWmhpimVHMimw=

View File

@ -133,10 +133,24 @@ func GetOAuthVerify(c *fiber.Ctx) error {
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Access Token")) return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Invalid Access Token"))
} }
return c.SendStatus(fiber.StatusOK) return c.Status(fiber.StatusOK).JSON(aid.JSON{
"app": "fortnite",
"token": "eg1~"+real,
"token_type": "bearer",
"expires_at": time.Now().Add(time.Hour * 24).Format("2006-01-02T15:04:05.999Z"),
"expires_in": 86400,
"client_id": c.IP(),
"session_id": "0",
"device_id": "default",
"internal_client": true,
"client_service": "snow",
"in_app_id": person.ID,
"account_id": person.ID,
"displayName": person.DisplayName,
})
} }
func MiddlewareOAuthVerify(c *fiber.Ctx) error { func OAuthMiddleware(c *fiber.Ctx) error {
auth := c.Get("Authorization") auth := c.Get("Authorization")
if auth == "" { if auth == "" {
return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Authorization Header is empty")) return c.Status(fiber.StatusForbidden).JSON(aid.ErrorBadRequest("Authorization Header is empty"))

View File

@ -32,7 +32,7 @@ func PostProfileAction(c *fiber.Ctx) error {
before := profile.Snapshot() before := profile.Snapshot()
if action, ok := profileActions[c.Params("action")]; ok { if action, ok := profileActions[c.Params("action")]; ok {
if err := action(c, person, profile); err != nil { if err := action(c, person, profile); err != nil {
return err return c.Status(400).JSON(aid.ErrorBadRequest(err.Error()))
} }
} }
profile.Diff(before) profile.Diff(before)
@ -86,7 +86,7 @@ func PostMarkItemSeenAction(c *fiber.Ctx, person *p.Person, profile *p.Profile)
func PostEquipBattleRoyaleCustomizationAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error { func PostEquipBattleRoyaleCustomizationAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
var body struct { var body struct {
SlotName string `json:"slotName"` SlotName string `json:"slotName" binding:"required"`
ItemToSlot string `json:"itemToSlot"` ItemToSlot string `json:"itemToSlot"`
IndexWithinSlot int `json:"indexWithinSlot"` IndexWithinSlot int `json:"indexWithinSlot"`
} }

View File

@ -1,7 +1,7 @@
package handlers package handlers
import ( import (
"encoding/json" "github.com/goccy/go-json"
"github.com/ectrc/snow/aid" "github.com/ectrc/snow/aid"
"github.com/ectrc/snow/storage" "github.com/ectrc/snow/storage"
@ -9,123 +9,14 @@ import (
) )
func GetStorefrontCatalog(c *fiber.Ctx) error { func GetStorefrontCatalog(c *fiber.Ctx) error {
t := aid.JSON{ storefront := aid.JSON{
"refreshIntervalHrs": 24, "refreshIntervalHrs": 24,
"dailyPurchaseHrs": 24, "dailyPurchaseHrs": 24,
"expiration": aid.TimeEndOfDay(), "expiration": aid.TimeEndOfDay(),
"storefronts": []aid.JSON{}, "storefronts": []aid.JSON{},
} }
str := `{ return c.Status(fiber.StatusOK).JSON(storefront)
"name": "CurrencyStorefront",
"catalogEntries": [
{
"devName": "[VIRTUAL]1 x Isabelle for 1200 MtxCurrency",
"offerId": "v2:/f3d84c3ded015ae12a0c8ae3cc60d771a45df0d90f0af5e1cfbd454fa3083c94",
"fulfillmentIds": [],
"dailyLimit": -1,
"weeklyLimit": -1,
"monthlyLimit": -1,
"categories": [
"Panel 03"
],
"prices": [
{
"currencyType": "MtxCurrency",
"currencySubType": "",
"regularPrice": 1200,
"dynamicRegularPrice": 1200,
"finalPrice": 1200,
"saleExpiration": "9999-12-31T23:59:59.999Z",
"basePrice": 1200
}
],
"meta": {
"NewDisplayAssetPath": "/Game/Catalog/DisplayAssets/DA_BR_Season8_BattlePass.DA_BR_Season8_BattlePass",
"offertag": "",
"SectionId": "Featured",
"TileSize": "Normal",
"AnalyticOfferGroupId": "3",
"ViolatorTag": "",
"ViolatorIntensity": "High",
"FirstSeen": ""
},
"matchFilter": "",
"filterWeight": 0.0,
"appStoreId": [],
"requirements": [
{
"requirementType": "DenyOnItemOwnership",
"requiredId": "AthenaCharacter:CID_033_Athena_Commando_F_Medieval",
"minQuantity": 1
}
],
"offerType": "StaticPrice",
"giftInfo": {
"bIsEnabled": true,
"forcedGiftBoxTemplateId": "",
"purchaseRequirements": [],
"giftRecordIds": []
},
"refundable": true,
"metaInfo": [
{
"key": "NewDisplayAssetPath",
"value": "/Game/Catalog/DisplayAssets/DA_BR_Season8_BattlePass.DA_BR_Season8_BattlePass"
},
{
"key": "offertag",
"value": ""
},
{
"key": "SectionId",
"value": "Featured"
},
{
"key": "TileSize",
"value": "Normal"
},
{
"key": "AnalyticOfferGroupId",
"value": "3"
},
{
"key": "ViolatorTag",
"value": ""
},
{
"key": "ViolatorIntensity",
"value": "High"
},
{
"key": "FirstSeen",
"value": ""
}
],
"displayAssetPath": "/Game/Catalog/DisplayAssets/DA_BR_Season8_BattlePass.DA_BR_Season8_BattlePass",
"itemGrants": [
{
"templateId": "AthenaCharacter:CID_033_Athena_Commando_F_Medieval",
"quantity": 1
}
],
"additionalGrants": [],
"sortPriority": -2,
"catalogGroupPriority": 0
}
]
}`
var catalog aid.JSON
err := json.Unmarshal([]byte(str), &catalog)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(aid.JSON{"error":err.Error()})
}
t["storefronts"] = append(t["storefronts"].([]aid.JSON), catalog)
return c.Status(fiber.StatusOK).JSON(t)
} }
func GetStorefrontKeychain(c *fiber.Ctx) error { func GetStorefrontKeychain(c *fiber.Ctx) error {

42
main.go
View File

@ -5,6 +5,7 @@ import (
"github.com/ectrc/snow/handlers" "github.com/ectrc/snow/handlers"
"github.com/ectrc/snow/person" "github.com/ectrc/snow/person"
"github.com/ectrc/snow/storage" "github.com/ectrc/snow/storage"
"github.com/goccy/go-json"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
@ -15,21 +16,11 @@ func init() {
switch aid.Config.Database.Type { switch aid.Config.Database.Type {
case "postgres": case "postgres":
postgresStorage := storage.NewPostgresStorage() postgresStorage := storage.NewPostgresStorage()
if aid.Config.Database.DropAllTables { if aid.Config.Database.DropAllTables {
aid.Print("Dropping all tables") aid.Print("Dropping all tables")
postgresStorage.DropTables() postgresStorage.DropTables()
} }
postgresStorage.MigrateAll()
postgresStorage.Migrate(&storage.DB_Person{}, "Persons")
postgresStorage.Migrate(&storage.DB_Profile{}, "Profiles")
postgresStorage.Migrate(&storage.DB_Item{}, "Items")
postgresStorage.Migrate(&storage.DB_Gift{}, "Gifts")
postgresStorage.Migrate(&storage.DB_Quest{}, "Quests")
postgresStorage.Migrate(&storage.DB_Loot{}, "Loot")
postgresStorage.Migrate(&storage.DB_VariantChannel{}, "Variants")
postgresStorage.Migrate(&storage.DB_PAttribute{}, "Attributes")
device = postgresStorage device = postgresStorage
} }
@ -40,22 +31,14 @@ func init() {
if aid.Config.Database.DropAllTables { if aid.Config.Database.DropAllTables {
person.NewFortnitePerson("ac", "1") person.NewFortnitePerson("ac", "1")
} }
aid.PrintTime("Loading all persons from database", func() {
for _, person := range person.AllFromDatabase() {
aid.Print("Loaded person: " + person.DisplayName)
}
})
aid.PrintTime("Loading all persons from cache", func() {
for _, person := range person.AllFromCache() {
aid.Print("Loaded person: " + person.DisplayName)
}
})
} }
func main() { func main() {
r := fiber.New() r := fiber.New(fiber.Config{
DisableStartupMessage: true,
JSONEncoder: json.Marshal,
JSONDecoder: json.Unmarshal,
})
r.Use(aid.FiberLogger()) r.Use(aid.FiberLogger())
r.Use(aid.FiberLimiter()) r.Use(aid.FiberLimiter())
@ -78,7 +61,7 @@ func main() {
fortnite.Get("/calendar/v1/timeline", handlers.GetFortniteTimeline) fortnite.Get("/calendar/v1/timeline", handlers.GetFortniteTimeline)
storefront := fortnite.Group("/storefront/v2") storefront := fortnite.Group("/storefront/v2")
storefront.Use(handlers.MiddlewareOAuthVerify) storefront.Use(handlers.OAuthMiddleware)
storefront.Get("/catalog", handlers.GetStorefrontCatalog) storefront.Get("/catalog", handlers.GetStorefrontCatalog)
storefront.Get("/keychain", handlers.GetStorefrontKeychain) storefront.Get("/keychain", handlers.GetStorefrontKeychain)
@ -91,7 +74,7 @@ func main() {
storage.Get("/system/:fileName", handlers.GetCloudStorageFile) storage.Get("/system/:fileName", handlers.GetCloudStorageFile)
user := storage.Group("/user") user := storage.Group("/user")
user.Use(handlers.MiddlewareOAuthVerify) user.Use(handlers.OAuthMiddleware)
user.Get("/:accountId", handlers.GetUserStorageFiles) user.Get("/:accountId", handlers.GetUserStorageFiles)
user.Get("/:accountId/:fileName", handlers.GetUserStorageFile) user.Get("/:accountId/:fileName", handlers.GetUserStorageFile)
user.Put("/:accountId/:fileName", handlers.PutUserStorageFile) user.Put("/:accountId/:fileName", handlers.PutUserStorageFile)
@ -102,12 +85,17 @@ func main() {
game.Post("/grant_access/:accountId", handlers.PostGameAccess) game.Post("/grant_access/:accountId", handlers.PostGameAccess)
profile := game.Group("/profile/:accountId") profile := game.Group("/profile/:accountId")
profile.Use(handlers.MiddlewareOAuthVerify) profile.Use(handlers.OAuthMiddleware)
profile.Post("/client/:action", handlers.PostProfileAction) profile.Post("/client/:action", handlers.PostProfileAction)
lightswitch := r.Group("/lightswitch/api") lightswitch := r.Group("/lightswitch/api")
lightswitch.Get("/service/bulk/status", handlers.GetLightswitchBulkStatus) lightswitch.Get("/service/bulk/status", handlers.GetLightswitchBulkStatus)
r.Hooks().OnListen(func(ld fiber.ListenData) error {
aid.Print("Listening on " + ld.Host + ":" + ld.Port)
return nil
})
r.All("*", func(c *fiber.Ctx) error { return c.Status(fiber.StatusNotFound).JSON(aid.ErrorNotFound) }) r.All("*", func(c *fiber.Ctx) error { return c.Status(fiber.StatusNotFound).JSON(aid.ErrorNotFound) })
r.Listen(aid.Config.API.Host + aid.Config.API.Port) r.Listen(aid.Config.API.Host + aid.Config.API.Port)
} }

View File

@ -25,6 +25,17 @@ func (s *PostgresStorage) Migrate(table interface{}, tableName string) {
s.Postgres.Table(tableName).AutoMigrate(table) s.Postgres.Table(tableName).AutoMigrate(table)
} }
func (s *PostgresStorage) MigrateAll() {
s.Migrate(&DB_Person{}, "Persons")
s.Migrate(&DB_Profile{}, "Profiles")
s.Migrate(&DB_Item{}, "Items")
s.Migrate(&DB_Gift{}, "Gifts")
s.Migrate(&DB_Quest{}, "Quests")
s.Migrate(&DB_Loot{}, "Loot")
s.Migrate(&DB_VariantChannel{}, "Variants")
s.Migrate(&DB_PAttribute{}, "Attributes")
}
func (s *PostgresStorage) DropTables() { func (s *PostgresStorage) DropTables() {
s.Postgres.Exec(`DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public;`) s.Postgres.Exec(`DROP SCHEMA public CASCADE; CREATE SCHEMA public; GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO public;`)
} }