Fixed Styled Lobbies; Fixed VBucks on early seasons; ...
Added KeyChain for newer seasons.
This commit is contained in:
parent
2e8d2fbc95
commit
188e7dc7b0
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
func FiberLogger() fiber.Handler {
|
||||
return logger.New(logger.Config{
|
||||
Format: "(${status}) (${latency}) ${path}\n",
|
||||
Format: "(${method}) (${status}) (${latency}) ${path}\n",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -25,5 +25,5 @@ host="0.0.0.0"
|
|||
secret="secret"
|
||||
|
||||
[fortnite]
|
||||
; the game build to use
|
||||
build=2.5
|
||||
; used for account creation + lobby
|
||||
build=5.41
|
|
@ -1,8 +1,6 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -41,15 +39,6 @@ func PostOAuthToken(c *fiber.Ctx) error {
|
|||
func PostOAuthTokenClientCredentials(c *fiber.Ctx, body *OAuthTokenBody) error {
|
||||
credentials, err := aid.JWTSign(aid.JSON{
|
||||
"snow_id": 0, // custom
|
||||
"t": "s",
|
||||
"am": "client_credentials", // authorization method
|
||||
"ic": true, // internal client
|
||||
"mver": false, // mobile version
|
||||
"clsvc": "snow", // client service
|
||||
"clid": c.IP(), // client id
|
||||
"jti": rand.Int63(), // jwt id
|
||||
"p": base64.StdEncoding.EncodeToString([]byte(c.IP())), // payload
|
||||
"hours_expire": 1,
|
||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -87,20 +76,6 @@ func PostOAuthTokenPassword(c *fiber.Ctx, body *OAuthTokenBody) error {
|
|||
|
||||
access, err := aid.JWTSign(aid.JSON{
|
||||
"snow_id": person.ID, // custom
|
||||
"iai": person.ID, // account id
|
||||
"dn": person.DisplayName, // display name
|
||||
"t": "s",
|
||||
"am": "password", // authorization method
|
||||
"ic": true, // internal client
|
||||
"mver": false, // mobile version
|
||||
"clsvc": "snow", // client service
|
||||
"app": "com.epicgames.fortnite", // app name
|
||||
"clid": c.IP(), // client id
|
||||
"dvid": "default", // device id
|
||||
"jti": rand.Int63(), // jwt id
|
||||
"p": base64.StdEncoding.EncodeToString([]byte(c.IP())), // payload
|
||||
"sec": 1, // security level
|
||||
"hours_expire": 24,
|
||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -108,13 +83,7 @@ func PostOAuthTokenPassword(c *fiber.Ctx, body *OAuthTokenBody) error {
|
|||
}
|
||||
|
||||
refresh, err := aid.JWTSign(aid.JSON{
|
||||
"snow_id": person.ID, // custom
|
||||
"sub": person.ID, // account id
|
||||
"clid": c.IP(), // client id
|
||||
"jti": rand.Int63(), // jwt id
|
||||
"t": "s",
|
||||
"am": "refresh_token", // authorization method
|
||||
"hours_expire": 24,
|
||||
"snow_id": person.ID,
|
||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -138,6 +107,66 @@ func PostOAuthTokenPassword(c *fiber.Ctx, body *OAuthTokenBody) error {
|
|||
})
|
||||
}
|
||||
|
||||
func GetOAuthVerify(c *fiber.Ctx) error {
|
||||
auth := c.Get("Authorization")
|
||||
if auth == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Authorization Header is empty"))
|
||||
}
|
||||
real := strings.ReplaceAll(auth, "bearer eg1~", "")
|
||||
|
||||
claims, err := aid.JWTVerify(real)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
if claims["snow_id"] == nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
snowId, ok := claims["snow_id"].(string)
|
||||
if !ok {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
person := p.Find(snowId)
|
||||
if person == nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
|
||||
func MiddlewareOAuthVerify(c *fiber.Ctx) error {
|
||||
auth := c.Get("Authorization")
|
||||
if auth == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Authorization Header is empty"))
|
||||
}
|
||||
real := strings.ReplaceAll(auth, "bearer eg1~", "")
|
||||
|
||||
claims, err := aid.JWTVerify(real)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
if claims["snow_id"] == nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
snowId, ok := claims["snow_id"].(string)
|
||||
if !ok {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
person := p.Find(snowId)
|
||||
if person == nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Access Token"))
|
||||
}
|
||||
|
||||
c.Locals("person", person)
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
func DeleteOAuthSessions(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{})
|
||||
}
|
||||
|
|
|
@ -9,33 +9,35 @@ func AnyNoContent(c *fiber.Ctx) error {
|
|||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
|
||||
func PostTryPlayOnPlatform(c *fiber.Ctx) error {
|
||||
func PostGamePlatform(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).SendString("true")
|
||||
}
|
||||
|
||||
func GetEnabledFeatures(c *fiber.Ctx) error {
|
||||
func GetGameEnabledFeatures(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON([]string{})
|
||||
}
|
||||
|
||||
func PostGrantAccess(c *fiber.Ctx) error {
|
||||
func PostGameAccess(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).SendString("true")
|
||||
}
|
||||
|
||||
func GetAccountReceipts(c *fiber.Ctx) error {
|
||||
func GetFortniteReceipts(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON([]string{})
|
||||
}
|
||||
|
||||
func GetSessionFindPlayer(c *fiber.Ctx) error {
|
||||
func GetMatchmakingSession(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON([]string{})
|
||||
}
|
||||
|
||||
func GetVersionCheck(c *fiber.Ctx) error {
|
||||
func GetFortniteVersion(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||
"type": "NO_UPDATE",
|
||||
})
|
||||
}
|
||||
|
||||
func GetContentPages(c *fiber.Ctx) error {
|
||||
// seasonString := strconv.Itoa(aid.Config.Fortnite.Season)
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||
"battlepassaboutmessages": aid.JSON{
|
||||
"news": aid.JSON{
|
||||
|
@ -73,6 +75,19 @@ func GetContentPages(c *fiber.Ctx) error {
|
|||
},
|
||||
"lastModified": "0000-00-00T00:00:00.000Z",
|
||||
},
|
||||
"dynamicbackgrounds": aid.JSON{
|
||||
"backgrounds": aid.JSON{"backgrounds": []aid.JSON{
|
||||
// {
|
||||
// "key": "lobby",
|
||||
// "stage": "season"+seasonString,
|
||||
// },
|
||||
// {
|
||||
// "key": "vault",
|
||||
// "stage": "season"+seasonString,
|
||||
// },
|
||||
}},
|
||||
"lastModified": "0000-00-00T00:00:00.000Z",
|
||||
},
|
||||
"lastModified": "0000-00-00T00:00:00.000Z",
|
||||
})
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
|
@ -11,28 +14,69 @@ import (
|
|||
func GetLightswitchBulkStatus(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON([]aid.JSON{{
|
||||
"serviceInstanceId": "fortnite",
|
||||
"status": "UP",
|
||||
"banned": false,
|
||||
"status" :"UP",
|
||||
"message": "fortnite is up.",
|
||||
"maintenanceUri": nil,
|
||||
"allowedActions": []string{"PLAY","DOWNLOAD"},
|
||||
"banned":false,
|
||||
"launcherInfoDTO": aid.JSON{
|
||||
"appName":"Fortnite",
|
||||
"catalogItemId":"4fe75bbc5a674f4f9b356b5c90567da5",
|
||||
"namespace":"fn",
|
||||
},
|
||||
}})
|
||||
}
|
||||
|
||||
func GetTimelineCalendar(c *fiber.Ctx) error {
|
||||
func GetFortniteTimeline(c *fiber.Ctx) error {
|
||||
userAgent := c.Get("User-Agent")
|
||||
fmt.Println(userAgent)
|
||||
if !strings.Contains(userAgent, "++Fortnite") {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("No User Agent"))
|
||||
}
|
||||
|
||||
build := regexp.MustCompile(`\d+\.\d+`).FindString(userAgent)
|
||||
if len(strings.Split(build, ".")) != 2 {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Invalid Build"))
|
||||
}
|
||||
|
||||
season, err := strconv.Atoi(strings.Split(build, ".")[0])
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(aid.ErrorBadRequest("Failed to parse Build"))
|
||||
}
|
||||
|
||||
events := []aid.JSON{
|
||||
{
|
||||
"activeUntil": aid.TimeEndOfWeekString(),
|
||||
"activeUntil": "9999-12-31T23:59:59.999Z",
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"activeEventId": "EventFlag.Season" + strconv.Itoa(aid.Config.Fortnite.Season),
|
||||
},
|
||||
{
|
||||
"activeUntil": aid.TimeEndOfWeekString(),
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"activeEventId": "EventFlag.LobbySeason" + strconv.Itoa(aid.Config.Fortnite.Season),
|
||||
"eventType": "EventFlag.Season" + strings.Split(build, ".")[0],
|
||||
},
|
||||
}
|
||||
|
||||
switch season {
|
||||
case 2:
|
||||
events = append(events, aid.JSON{
|
||||
"activeUntil": "9999-12-31T23:59:59.999Z",
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"eventType": "EventFlag.LobbyWinterDecor",
|
||||
})
|
||||
case 6:
|
||||
events = append(events, aid.JSON{
|
||||
"activeUntil": "9999-01-01T00:00:00.000Z",
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"eventType": "EventFlag.LobbySeason6Halloween",
|
||||
})
|
||||
default:
|
||||
events = append(events, aid.JSON{
|
||||
"activeUntil": "9999-12-31T23:59:59.999Z",
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"eventType": "EventFlag.LobbySeason" + strings.Split(build, ".")[0],
|
||||
})
|
||||
}
|
||||
|
||||
state := aid.JSON{
|
||||
"seasonNumber": aid.Config.Fortnite.Season,
|
||||
"seasonTemplateId": "AthenaSeason:AthenaSeason" + strconv.Itoa(aid.Config.Fortnite.Season),
|
||||
"eventNamedWeights": aid.JSON{},
|
||||
"seasonNumber": season,
|
||||
"seasonTemplateId": "AthenaSeason:AthenaSeason" + strings.Split(build, ".")[0],
|
||||
"seasonBegin": time.Now().Add(-time.Hour * 24 * 7).Format("2006-01-02T15:04:05.000Z"),
|
||||
"seasonEnd": time.Now().Add(time.Hour * 24 * 7).Format("2006-01-02T15:04:05.000Z"),
|
||||
"seasonDisplayedEnd": time.Now().Add(time.Hour * 24 * 7).Format("2006-01-02T15:04:05.000Z"),
|
||||
|
@ -56,6 +100,10 @@ func GetTimelineCalendar(c *fiber.Ctx) error {
|
|||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||
"channels": aid.JSON{
|
||||
"client-events": client,
|
||||
"client-matchmaking": aid.JSON{
|
||||
"states": []aid.JSON{},
|
||||
"cacheExpire": "9999-12-31T23:59:59.999Z",
|
||||
},
|
||||
},
|
||||
"currentTime": time.Now().Format("2006-01-02T15:04:05.000Z"),
|
||||
"cacheIntervalMins": 5,
|
||||
|
|
1228
handlers/storefront.go
Normal file
1228
handlers/storefront.go
Normal file
File diff suppressed because it is too large
Load Diff
19
main.go
19
main.go
|
@ -66,16 +66,21 @@ func main() {
|
|||
account := r.Group("/account/api")
|
||||
account.Get("/public/account/:accountId", handlers.GetPublicAccount)
|
||||
account.Get("/public/account/:accountId/externalAuths", handlers.GetPublicAccountExternalAuths)
|
||||
account.Get("/oauth/verify", handlers.GetOAuthVerify)
|
||||
account.Post("/oauth/token", handlers.PostOAuthToken)
|
||||
account.Delete("/oauth/sessions/kill", handlers.DeleteOAuthSessions)
|
||||
|
||||
fortnite := r.Group("/fortnite/api")
|
||||
fortnite.Get("/receipts/v1/account/:accountId/receipts", handlers.GetAccountReceipts)
|
||||
fortnite.Get("/versioncheck/*", handlers.GetVersionCheck)
|
||||
fortnite.Get("/calendar/v1/timeline", handlers.GetTimelineCalendar)
|
||||
fortnite.Get("/receipts/v1/account/:accountId/receipts", handlers.GetFortniteReceipts)
|
||||
fortnite.Get("/v2/versioncheck/*", handlers.GetFortniteVersion)
|
||||
fortnite.Get("/calendar/v1/timeline", handlers.GetFortniteTimeline)
|
||||
|
||||
storefront := fortnite.Group("/storefront/v2")
|
||||
storefront.Get("/catalog", handlers.GetStorefrontCatalog)
|
||||
storefront.Get("/keychain", handlers.GetStorefrontKeychain)
|
||||
|
||||
matchmaking := fortnite.Group("/matchmaking")
|
||||
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetSessionFindPlayer)
|
||||
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetMatchmakingSession)
|
||||
|
||||
storage := fortnite.Group("/cloudstorage")
|
||||
storage.Get("/system", handlers.GetCloudStorageFiles)
|
||||
|
@ -86,9 +91,9 @@ func main() {
|
|||
storage.Put("/user/:accountId/:fileName", handlers.PutUserStorageFile)
|
||||
|
||||
game := fortnite.Group("/game/v2")
|
||||
game.Post("/tryPlayOnPlatform/account/:accountId", handlers.PostTryPlayOnPlatform)
|
||||
game.Post("/grant_access/:accountId", handlers.PostGrantAccess)
|
||||
game.Get("/enabled_features", handlers.GetEnabledFeatures)
|
||||
game.Get("/enabled_features", handlers.GetGameEnabledFeatures)
|
||||
game.Post("/tryPlayOnPlatform/account/:accountId", handlers.PostGamePlatform)
|
||||
game.Post("/grant_access/:accountId", handlers.PostGameAccess)
|
||||
|
||||
profile := game.Group("/profile/:accountId")
|
||||
profile.Post("/client/:action", handlers.PostProfileAction)
|
||||
|
|
|
@ -71,6 +71,11 @@ func FromDatabaseLoot(item *storage.DB_Loot) *Item {
|
|||
|
||||
func (i *Item) GenerateFortniteItemEntry() aid.JSON {
|
||||
variants := []aid.JSON{}
|
||||
attributes := aid.JSON{
|
||||
"variants": variants,
|
||||
"favorite": i.Favorite,
|
||||
"item_seen": i.HasSeen,
|
||||
}
|
||||
|
||||
for _, variant := range i.Variants {
|
||||
variants = append(variants, aid.JSON{
|
||||
|
@ -80,13 +85,15 @@ func (i *Item) GenerateFortniteItemEntry() aid.JSON {
|
|||
})
|
||||
}
|
||||
|
||||
if i.TemplateID == "Currency:MtxPurchased" {
|
||||
attributes = aid.JSON{
|
||||
"platform": "Shared",
|
||||
}
|
||||
}
|
||||
|
||||
return aid.JSON{
|
||||
"templateId": i.TemplateID,
|
||||
"attributes": aid.JSON{
|
||||
"variants": variants,
|
||||
"favorite": i.Favorite,
|
||||
"item_seen": i.HasSeen,
|
||||
},
|
||||
"attributes": attributes,
|
||||
"quantity": i.Quantity,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,11 +140,10 @@ func (s *PostgresStorage) DeleteGift(giftId string) {
|
|||
s.Postgres.Delete(&DB_Gift{}, "id = ?", giftId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveAttribute(attribute *DB_PAttribute) {
|
||||
s.Postgres.Save(attribute)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteAttribute(attributeId string) {
|
||||
s.Postgres.Delete(&DB_PAttribute{}, "id = ?", attributeId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveAttribute(attribute *DB_PAttribute) {
|
||||
aid.Print("saving attribute", attribute.Key, attribute.ValueJSON)
|
||||
s.Postgres.Save(attribute)
|
||||
}
|
Loading…
Reference in New Issue
Block a user