Improve default JSON Encoder; Other organising features,
This commit is contained in:
parent
5237402c5e
commit
5c6b1d6407
|
@ -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() {
|
||||||
|
|
|
@ -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
1
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
42
main.go
|
@ -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)
|
||||||
}
|
}
|
|
@ -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;`)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user