Add vbucks in store! (not real)
This commit is contained in:
parent
590917adbb
commit
749643be88
|
@ -49,6 +49,7 @@ type CS struct {
|
||||||
Password bool
|
Password bool
|
||||||
DisableClientCredentials bool
|
DisableClientCredentials bool
|
||||||
ShopSeed int
|
ShopSeed int
|
||||||
|
EnableVBucks bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,4 +176,5 @@ func LoadConfig(file []byte) {
|
||||||
Config.Fortnite.Password = !(cfg.Section("fortnite").Key("disable_password").MustBool(false))
|
Config.Fortnite.Password = !(cfg.Section("fortnite").Key("disable_password").MustBool(false))
|
||||||
Config.Fortnite.DisableClientCredentials = cfg.Section("fortnite").Key("disable_client_credentials").MustBool(false)
|
Config.Fortnite.DisableClientCredentials = cfg.Section("fortnite").Key("disable_client_credentials").MustBool(false)
|
||||||
Config.Fortnite.ShopSeed = cfg.Section("fortnite").Key("shop_seed").MustInt(0)
|
Config.Fortnite.ShopSeed = cfg.Section("fortnite").Key("shop_seed").MustInt(0)
|
||||||
|
Config.Fortnite.EnableVBucks = cfg.Section("fortnite").Key("enable_vbucks").MustBool(false)
|
||||||
}
|
}
|
12
aid/fiber.go
12
aid/fiber.go
|
@ -31,3 +31,15 @@ func FiberCors() fiber.Handler {
|
||||||
AllowHeaders: "Origin, Content-Type, Accept, Authorization, X-Requested-With",
|
AllowHeaders: "Origin, Content-Type, Accept, Authorization, X-Requested-With",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/gofiber/fiber/issues/510
|
||||||
|
func FiberGetQueries(c *fiber.Ctx, queryKeys ...string) map[string][]string {
|
||||||
|
argsMaps := make(map[string][]string)
|
||||||
|
for _, keys := range queryKeys {
|
||||||
|
param := c.Request().URI().QueryArgs().PeekMulti(keys)
|
||||||
|
for _, value := range param {
|
||||||
|
argsMaps[keys] = append(argsMaps[keys], string(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return argsMaps
|
||||||
|
}
|
|
@ -80,3 +80,7 @@ disable_client_credentials=false
|
||||||
; each number will generate a different shop for the day
|
; each number will generate a different shop for the day
|
||||||
; the shop will stay the same for the entire day even after server restarts
|
; the shop will stay the same for the entire day even after server restarts
|
||||||
shop_seed=0
|
shop_seed=0
|
||||||
|
; this will enable vbucks in the store tab
|
||||||
|
; at this time it is not possible to buy vbucks
|
||||||
|
; this is only for testing purposes
|
||||||
|
enable_vbucks=true
|
|
@ -13,10 +13,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
External *ExternalDataClient
|
DataClient *dataClient
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExternalDataClient struct {
|
type dataClient struct {
|
||||||
h *http.Client
|
h *http.Client
|
||||||
FortniteSets map[string]*FortniteSet `json:"sets"`
|
FortniteSets map[string]*FortniteSet `json:"sets"`
|
||||||
FortniteItems map[string]*FortniteItem `json:"items"`
|
FortniteItems map[string]*FortniteItem `json:"items"`
|
||||||
|
@ -25,10 +25,14 @@ type ExternalDataClient struct {
|
||||||
TypedFortniteItems map[string][]*FortniteItem `json:"-"`
|
TypedFortniteItems map[string][]*FortniteItem `json:"-"`
|
||||||
TypedFortniteItemsWithDisplayAssets map[string][]*FortniteItem `json:"-"`
|
TypedFortniteItemsWithDisplayAssets map[string][]*FortniteItem `json:"-"`
|
||||||
SnowVariantTokens map[string]*FortniteVariantToken `json:"variants"`
|
SnowVariantTokens map[string]*FortniteVariantToken `json:"variants"`
|
||||||
|
StorefrontCosmeticOfferPriceLookup map[string]map[string]int `json:"-"`
|
||||||
|
StorefrontDailyItemCountLookup []struct{Season int;Items int} `json:"-"`
|
||||||
|
StorefrontWeeklySetCountLookup []struct{Season int;Sets int} `json:"-"`
|
||||||
|
StorefrontCurrencyOfferPriceLookup map[string]map[int]int `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExternalDataClient() *ExternalDataClient {
|
func NewDataClient() *dataClient {
|
||||||
return &ExternalDataClient{
|
return &dataClient{
|
||||||
h: &http.Client{},
|
h: &http.Client{},
|
||||||
FortniteItems: make(map[string]*FortniteItem),
|
FortniteItems: make(map[string]*FortniteItem),
|
||||||
FortniteSets: make(map[string]*FortniteSet),
|
FortniteSets: make(map[string]*FortniteSet),
|
||||||
|
@ -37,10 +41,76 @@ func NewExternalDataClient() *ExternalDataClient {
|
||||||
TypedFortniteItems: make(map[string][]*FortniteItem),
|
TypedFortniteItems: make(map[string][]*FortniteItem),
|
||||||
TypedFortniteItemsWithDisplayAssets: make(map[string][]*FortniteItem),
|
TypedFortniteItemsWithDisplayAssets: make(map[string][]*FortniteItem),
|
||||||
SnowVariantTokens: make(map[string]*FortniteVariantToken),
|
SnowVariantTokens: make(map[string]*FortniteVariantToken),
|
||||||
|
StorefrontDailyItemCountLookup: []struct{Season int;Items int}{
|
||||||
|
{2, 4},
|
||||||
|
{4, 6},
|
||||||
|
{13, 10},
|
||||||
|
},
|
||||||
|
StorefrontWeeklySetCountLookup: []struct{Season int;Sets int}{
|
||||||
|
{2, 2},
|
||||||
|
{4, 3},
|
||||||
|
{13, 5},
|
||||||
|
},
|
||||||
|
StorefrontCosmeticOfferPriceLookup: map[string]map[string]int{
|
||||||
|
"EFortRarity::Legendary": {
|
||||||
|
"AthenaCharacter": 2000,
|
||||||
|
"AthenaBackpack": 1500,
|
||||||
|
"AthenaPickaxe": 1500,
|
||||||
|
"AthenaGlider": 1800,
|
||||||
|
"AthenaDance": 500,
|
||||||
|
"AthenaItemWrap": 800,
|
||||||
|
},
|
||||||
|
"EFortRarity::Epic": {
|
||||||
|
"AthenaCharacter": 1500,
|
||||||
|
"AthenaBackpack": 1200,
|
||||||
|
"AthenaPickaxe": 1200,
|
||||||
|
"AthenaGlider": 1500,
|
||||||
|
"AthenaDance": 800,
|
||||||
|
"AthenaItemWrap": 800,
|
||||||
|
},
|
||||||
|
"EFortRarity::Rare": {
|
||||||
|
"AthenaCharacter": 1200,
|
||||||
|
"AthenaBackpack": 800,
|
||||||
|
"AthenaPickaxe": 800,
|
||||||
|
"AthenaGlider": 800,
|
||||||
|
"AthenaDance": 500,
|
||||||
|
"AthenaItemWrap": 600,
|
||||||
|
},
|
||||||
|
"EFortRarity::Uncommon": {
|
||||||
|
"AthenaCharacter": 800,
|
||||||
|
"AthenaBackpack": 200,
|
||||||
|
"AthenaPickaxe": 500,
|
||||||
|
"AthenaGlider": 500,
|
||||||
|
"AthenaDance": 200,
|
||||||
|
"AthenaItemWrap": 300,
|
||||||
|
},
|
||||||
|
"EFortRarity::Common": {
|
||||||
|
"AthenaCharacter": 500,
|
||||||
|
"AthenaBackpack": 200,
|
||||||
|
"AthenaPickaxe": 500,
|
||||||
|
"AthenaGlider": 500,
|
||||||
|
"AthenaDance": 200,
|
||||||
|
"AthenaItemWrap": 300,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
StorefrontCurrencyOfferPriceLookup: map[string]map[int]int{
|
||||||
|
"USD": {
|
||||||
|
1000: 999,
|
||||||
|
2800: 2499,
|
||||||
|
5000: 3999,
|
||||||
|
13500: 9999,
|
||||||
|
},
|
||||||
|
"GBP": {
|
||||||
|
1000: 799,
|
||||||
|
2800: 1999,
|
||||||
|
5000: 3499,
|
||||||
|
13500: 7999,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ExternalDataClient) LoadExternalData() {
|
func (c *dataClient) LoadExternalData() {
|
||||||
req, err := http.NewRequest("GET", "https://fortnite-api.com/v2/cosmetics/br", nil)
|
req, err := http.NewRequest("GET", "https://fortnite-api.com/v2/cosmetics/br", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -113,7 +183,7 @@ func (c *ExternalDataClient) LoadExternalData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ExternalDataClient) LoadItem(item *FortniteItem) {
|
func (c *dataClient) LoadItem(item *FortniteItem) {
|
||||||
if item.Introduction.BackendValue > aid.Config.Fortnite.Season || item.Introduction.BackendValue == 0 {
|
if item.Introduction.BackendValue > aid.Config.Fortnite.Season || item.Introduction.BackendValue == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -151,7 +221,7 @@ func (c *ExternalDataClient) LoadItem(item *FortniteItem) {
|
||||||
c.FortniteItemsWithFeaturedImage = append(c.FortniteItemsWithFeaturedImage, item)
|
c.FortniteItemsWithFeaturedImage = append(c.FortniteItemsWithFeaturedImage, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ExternalDataClient) AddBackpackToItem(backpack *FortniteItem) {
|
func (c *dataClient) AddBackpackToItem(backpack *FortniteItem) {
|
||||||
if backpack.ItemPreviewHeroPath == "" {
|
if backpack.ItemPreviewHeroPath == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -165,7 +235,7 @@ func (c *ExternalDataClient) AddBackpackToItem(backpack *FortniteItem) {
|
||||||
character.Backpack = backpack
|
character.Backpack = backpack
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ExternalDataClient) AddDisplayAssetToItem(displayAsset string) {
|
func (c *dataClient) AddDisplayAssetToItem(displayAsset string) {
|
||||||
split := strings.Split(displayAsset, "_")[1:]
|
split := strings.Split(displayAsset, "_")[1:]
|
||||||
found := c.FortniteItems[strings.Join(split[:], "_")]
|
found := c.FortniteItems[strings.Join(split[:], "_")]
|
||||||
|
|
||||||
|
@ -185,7 +255,7 @@ func (c *ExternalDataClient) AddDisplayAssetToItem(displayAsset string) {
|
||||||
c.TypedFortniteItemsWithDisplayAssets[found.Type.BackendValue] = append(c.TypedFortniteItemsWithDisplayAssets[found.Type.BackendValue], found)
|
c.TypedFortniteItemsWithDisplayAssets[found.Type.BackendValue] = append(c.TypedFortniteItemsWithDisplayAssets[found.Type.BackendValue], found)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ExternalDataClient) AddNumericStylesToItem(item *FortniteItem) {
|
func (c *dataClient) AddNumericStylesToItem(item *FortniteItem) {
|
||||||
ownedStyles := []FortniteVariantChannel{}
|
ownedStyles := []FortniteVariantChannel{}
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
ownedStyles = append(ownedStyles, FortniteVariantChannel{
|
ownedStyles = append(ownedStyles, FortniteVariantChannel{
|
||||||
|
@ -200,16 +270,46 @@ func (c *ExternalDataClient) AddNumericStylesToItem(item *FortniteItem) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func PreloadCosmetics() error {
|
func (c *dataClient) GetStorefrontDailyItemCount(season int) int {
|
||||||
External = NewExternalDataClient()
|
currentValue := 4
|
||||||
External.LoadExternalData()
|
for _, item := range c.StorefrontDailyItemCountLookup {
|
||||||
|
if item.Season > season {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentValue = item.Items
|
||||||
|
}
|
||||||
|
return currentValue
|
||||||
|
}
|
||||||
|
|
||||||
aid.Print("(snow) " + fmt.Sprint(len(External.FortniteItems)) + " cosmetics loaded from fortnite-api.com")
|
func (c *dataClient) GetStorefrontWeeklySetCount(season int) int {
|
||||||
|
currentValue := 2
|
||||||
|
for _, item := range c.StorefrontWeeklySetCountLookup {
|
||||||
|
if item.Season > season {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentValue = item.Sets
|
||||||
|
}
|
||||||
|
return currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *dataClient) GetStorefrontCosmeticOfferPrice(rarity string, type_ string) int {
|
||||||
|
return c.StorefrontCosmeticOfferPriceLookup[rarity][type_]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *dataClient) GetStorefrontCurrencyOfferPrice(currency string, amount int) int {
|
||||||
|
return c.StorefrontCurrencyOfferPriceLookup[currency][amount]
|
||||||
|
}
|
||||||
|
|
||||||
|
func PreloadCosmetics() error {
|
||||||
|
DataClient = NewDataClient()
|
||||||
|
DataClient.LoadExternalData()
|
||||||
|
|
||||||
|
aid.Print("(snow) " + fmt.Sprint(len(DataClient.FortniteItems)) + " cosmetics loaded from fortnite-api.com")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetItemByShallowID(shallowID string) *FortniteItem {
|
func GetItemByShallowID(shallowID string) *FortniteItem {
|
||||||
for _, item := range External.TypedFortniteItems["AthenaCharacter"] {
|
for _, item := range DataClient.TypedFortniteItems["AthenaCharacter"] {
|
||||||
if strings.Contains(item.ID, shallowID) {
|
if strings.Contains(item.ID, shallowID) {
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
@ -219,7 +319,7 @@ func GetItemByShallowID(shallowID string) *FortniteItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRandomItemWithDisplayAsset() *FortniteItem {
|
func GetRandomItemWithDisplayAsset() *FortniteItem {
|
||||||
items := External.FortniteItemsWithDisplayAssets
|
items := DataClient.FortniteItemsWithDisplayAssets
|
||||||
if len(items) == 0 {
|
if len(items) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -239,7 +339,7 @@ func GetRandomItemWithDisplayAsset() *FortniteItem {
|
||||||
func GetRandomItemWithDisplayAssetOfNotType(notType string) *FortniteItem {
|
func GetRandomItemWithDisplayAssetOfNotType(notType string) *FortniteItem {
|
||||||
flat := []FortniteItem{}
|
flat := []FortniteItem{}
|
||||||
|
|
||||||
for t, items := range External.TypedFortniteItemsWithDisplayAssets {
|
for t, items := range DataClient.TypedFortniteItemsWithDisplayAssets {
|
||||||
if t == notType {
|
if t == notType {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -258,7 +358,10 @@ func GetRandomItemWithDisplayAssetOfNotType(notType string) *FortniteItem {
|
||||||
|
|
||||||
func GetRandomSet() *FortniteSet {
|
func GetRandomSet() *FortniteSet {
|
||||||
sets := []FortniteSet{}
|
sets := []FortniteSet{}
|
||||||
for _, set := range External.FortniteSets {
|
for _, set := range DataClient.FortniteSets {
|
||||||
|
if set.BackendName == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
sets = append(sets, *set)
|
sets = append(sets, *set)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ func NewFortnitePerson(displayName string, everything bool) *p.Person {
|
||||||
func GiveEverything(person *p.Person) {
|
func GiveEverything(person *p.Person) {
|
||||||
items := make([]storage.DB_Item, 0)
|
items := make([]storage.DB_Item, 0)
|
||||||
|
|
||||||
for _, item := range External.FortniteItems {
|
for _, item := range DataClient.FortniteItems {
|
||||||
if strings.Contains(strings.ToLower(item.ID), "random") {
|
if strings.Contains(strings.ToLower(item.ID), "random") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
370
fortnite/shop.go
370
fortnite/shop.go
|
@ -1,110 +1,177 @@
|
||||||
package fortnite
|
package fortnite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
priceLookup = map[string]map[string]int{
|
type FortniteCatalogCurrencyOffer struct {
|
||||||
"EFortRarity::Legendary": {
|
ID string
|
||||||
"AthenaCharacter": 2000,
|
DevName string
|
||||||
"AthenaBackpack": 1500,
|
Price struct {
|
||||||
"AthenaPickaxe": 1500,
|
OriginalOffer int
|
||||||
"AthenaGlider": 1800,
|
ExtraBonus int
|
||||||
"AthenaDance": 500,
|
}
|
||||||
"AthenaItemWrap": 800,
|
Meta struct {
|
||||||
|
IconSize string
|
||||||
|
CurrencyAnalyticsName string
|
||||||
|
BannerOverride string
|
||||||
|
}
|
||||||
|
Title string
|
||||||
|
Description string
|
||||||
|
LongDescription string
|
||||||
|
Priority int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFortniteCatalogCurrencyOffer(original, bonus int) *FortniteCatalogCurrencyOffer {
|
||||||
|
return &FortniteCatalogCurrencyOffer{
|
||||||
|
ID: "v2:/"+aid.RandomString(32),
|
||||||
|
Price: struct {
|
||||||
|
OriginalOffer int
|
||||||
|
ExtraBonus int
|
||||||
|
}{original, bonus},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FortniteCatalogCurrencyOffer) GenerateFortniteCatalogCurrencyOfferResponse() aid.JSON {
|
||||||
|
return aid.JSON{
|
||||||
|
"offerId": f.ID,
|
||||||
|
"devName": f.DevName,
|
||||||
|
"offerType": "StaticPrice",
|
||||||
|
"prices": []aid.JSON{{
|
||||||
|
"currencyType": "RealMoney",
|
||||||
|
"currencySubType": "",
|
||||||
|
"regularPrice": 0,
|
||||||
|
"dynamicRegularPrice": -1,
|
||||||
|
"finalPrice": 0,
|
||||||
|
"saleExpiration": "9999-12-31T23:59:59.999Z",
|
||||||
|
"basePrice": 0,
|
||||||
|
}},
|
||||||
|
"categories": []string{},
|
||||||
|
"dailyLimit": -1,
|
||||||
|
"weeklyLimit": -1,
|
||||||
|
"monthlyLimit": -1,
|
||||||
|
"refundable": false,
|
||||||
|
"appStoreId": []string{
|
||||||
|
"",
|
||||||
|
"app-" + f.ID,
|
||||||
},
|
},
|
||||||
"EFortRarity::Epic": {
|
"requirements": []aid.JSON{},
|
||||||
"AthenaCharacter": 1500,
|
"metaInfo": []aid.JSON{
|
||||||
"AthenaBackpack": 1200,
|
{
|
||||||
"AthenaPickaxe": 1200,
|
"key": "MtxQuantity",
|
||||||
"AthenaGlider": 1500,
|
"value": f.Price.OriginalOffer + f.Price.ExtraBonus,
|
||||||
"AthenaDance": 800,
|
|
||||||
"AthenaItemWrap": 800,
|
|
||||||
},
|
},
|
||||||
"EFortRarity::Rare": {
|
{
|
||||||
"AthenaCharacter": 1200,
|
"key": "MtxBonus",
|
||||||
"AthenaBackpack": 800,
|
"value": f.Price.ExtraBonus,
|
||||||
"AthenaPickaxe": 800,
|
|
||||||
"AthenaGlider": 800,
|
|
||||||
"AthenaDance": 500,
|
|
||||||
"AthenaItemWrap": 600,
|
|
||||||
},
|
},
|
||||||
"EFortRarity::Uncommon": {
|
{
|
||||||
"AthenaCharacter": 800,
|
"key": "IconSize",
|
||||||
"AthenaBackpack": 200,
|
"value": f.Meta.IconSize,
|
||||||
"AthenaPickaxe": 500,
|
|
||||||
"AthenaGlider": 500,
|
|
||||||
"AthenaDance": 200,
|
|
||||||
"AthenaItemWrap": 300,
|
|
||||||
},
|
},
|
||||||
"EFortRarity::Common": {
|
{
|
||||||
"AthenaCharacter": 500,
|
"key": "BannerOverride",
|
||||||
"AthenaBackpack": 200,
|
"value": f.Meta.BannerOverride,
|
||||||
"AthenaPickaxe": 500,
|
|
||||||
"AthenaGlider": 500,
|
|
||||||
"AthenaDance": 200,
|
|
||||||
"AthenaItemWrap": 300,
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Key": "CurrencyAnalyticsName",
|
||||||
|
"Value": f.Meta.CurrencyAnalyticsName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"meta": aid.JSON{
|
||||||
|
"IconSize": f.Meta.IconSize,
|
||||||
|
"CurrencyAnalyticsName": f.Meta.CurrencyAnalyticsName,
|
||||||
|
"BannerOverride": f.Meta.BannerOverride,
|
||||||
|
"MtxQuantity": f.Price.OriginalOffer + f.Price.ExtraBonus,
|
||||||
|
"MtxBonus": f.Price.ExtraBonus,
|
||||||
|
},
|
||||||
|
"catalogGroup": "",
|
||||||
|
"catalogGroupPriority": 0,
|
||||||
|
"sortPriority": f.Priority,
|
||||||
|
"bannerOverride": f.Meta.BannerOverride,
|
||||||
|
"title": f.Title,
|
||||||
|
"shortDescription": "",
|
||||||
|
"description": f.Description,
|
||||||
|
"displayAssetPath": "/Game/Catalog/DisplayAssets/DA_" + f.Meta.CurrencyAnalyticsName + ".DA_" + f.Meta.CurrencyAnalyticsName,
|
||||||
|
"itemGrants": []aid.JSON{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dailyItemLookup = []struct {
|
func (f *FortniteCatalogCurrencyOffer) GenerateFortniteCatalogBulkOfferResponse() aid.JSON{
|
||||||
Season int
|
return aid.JSON{
|
||||||
Items int
|
"id": "app-" + f.ID,
|
||||||
}{
|
"title": f.Title,
|
||||||
{2, 4},
|
"description": f.Description,
|
||||||
{4, 6},
|
"longDescription": f.LongDescription,
|
||||||
{13, 10},
|
"technicalDetails": "",
|
||||||
|
"keyImages": []aid.JSON{},
|
||||||
|
"categories": []aid.JSON{},
|
||||||
|
"namespace": "fn",
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"creationDate": time.Now().Format(time.RFC3339),
|
||||||
|
"lastModifiedDate": time.Now().Format(time.RFC3339),
|
||||||
|
"customAttributes": aid.JSON{},
|
||||||
|
"internalName": f.Title,
|
||||||
|
"recurrence": "ONCE",
|
||||||
|
"items": []aid.JSON{},
|
||||||
|
"price": DataClient.GetStorefrontCurrencyOfferPrice("GBP", f.Price.OriginalOffer + f.Price.ExtraBonus),
|
||||||
|
"currentPrice": DataClient.GetStorefrontCurrencyOfferPrice("GBP", f.Price.OriginalOffer + f.Price.ExtraBonus),
|
||||||
|
"currencyCode": "GBP",
|
||||||
|
"basePrice": DataClient.GetStorefrontCurrencyOfferPrice("USD", f.Price.OriginalOffer + f.Price.ExtraBonus),
|
||||||
|
"basePriceCurrencyCode": "USD",
|
||||||
|
"recurringPrice": 0,
|
||||||
|
"freeDays": 0,
|
||||||
|
"maxBillingCycles": 0,
|
||||||
|
"seller": aid.JSON{},
|
||||||
|
"viewableDate": time.Now().Format(time.RFC3339),
|
||||||
|
"effectiveDate": time.Now().Format(time.RFC3339),
|
||||||
|
"expiryDate": "9999-12-31T23:59:59.999Z",
|
||||||
|
"vatIncluded": true,
|
||||||
|
"isCodeRedemptionOnly": false,
|
||||||
|
"isFeatured": false,
|
||||||
|
"taxSkuId": "FN_Currency",
|
||||||
|
"merchantGroup": "FN_MKT",
|
||||||
|
"priceTier": fmt.Sprintf("%d", DataClient.GetStorefrontCurrencyOfferPrice("USD", f.Price.OriginalOffer + f.Price.ExtraBonus)),
|
||||||
|
"urlSlug": "fortnite--" + f.Title,
|
||||||
|
"roleNamesToGrant": []aid.JSON{},
|
||||||
|
"tags": []aid.JSON{},
|
||||||
|
"purchaseLimit": -1,
|
||||||
|
"ignoreOrder": false,
|
||||||
|
"fulfillToGroup": false,
|
||||||
|
"fraudItemType": "V-Bucks",
|
||||||
|
"shareRevenue": false,
|
||||||
|
"offerType": "OTHERS",
|
||||||
|
"unsearchable": false,
|
||||||
|
"releaseDate": time.Now().Format(time.RFC3339),
|
||||||
|
"releaseOffer": "",
|
||||||
|
"title4Sort": f.Title,
|
||||||
|
"countriesBlacklist": []string{},
|
||||||
|
"selfRefundable": false,
|
||||||
|
"refundType": "NON_REFUNDABLE",
|
||||||
|
"pcReleaseDate": time.Now().Format(time.RFC3339),
|
||||||
|
"priceCalculationMode": "FIXED",
|
||||||
|
"assembleMode": "SINGLE",
|
||||||
|
"publisherDisplayName": "Epic Games",
|
||||||
|
"developerDisplayName": "Epic Games",
|
||||||
|
"visibilityType": "IS_LISTED",
|
||||||
|
"currencyDecimals": 2,
|
||||||
|
"allowPurchaseForPartialOwned": true,
|
||||||
|
"shareRevenueWithUnderageAffiliates": false,
|
||||||
|
"platformWhitelist": []string{},
|
||||||
|
"platformBlacklist": []string{},
|
||||||
|
"partialItemPrerequisiteCheck": false,
|
||||||
|
"upgradeMode": "UPGRADED_WITH_PRICE_FULL",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
weeklySetLookup = []struct {
|
type FortniteCatalogCosmeticOffer struct {
|
||||||
Season int
|
|
||||||
Sets int
|
|
||||||
}{
|
|
||||||
{2, 2},
|
|
||||||
{4, 3},
|
|
||||||
{11, 4},
|
|
||||||
{13, 3},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func price(rarity, type_ string) int {
|
|
||||||
return priceLookup[rarity][type_]
|
|
||||||
}
|
|
||||||
|
|
||||||
func dailyItems(season int) int {
|
|
||||||
currentValue := 4
|
|
||||||
|
|
||||||
for _, item := range dailyItemLookup {
|
|
||||||
if item.Season > season {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
currentValue = item.Items
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func weeklySets(season int) int {
|
|
||||||
currentValue := 2
|
|
||||||
|
|
||||||
for _, set := range weeklySetLookup {
|
|
||||||
if set.Season > season {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
currentValue = set.Sets
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentValue
|
|
||||||
}
|
|
||||||
|
|
||||||
type FortniteCatalogSectionOffer struct {
|
|
||||||
ID string
|
ID string
|
||||||
Grants []*FortniteItem
|
Grants []*FortniteItem
|
||||||
TotalPrice int
|
TotalPrice int
|
||||||
|
@ -128,11 +195,11 @@ type FortniteCatalogSectionOffer struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFortniteCatalogSectionOffer() *FortniteCatalogSectionOffer {
|
func NewFortniteCatalogSectionOffer() *FortniteCatalogCosmeticOffer {
|
||||||
return &FortniteCatalogSectionOffer{}
|
return &FortniteCatalogCosmeticOffer{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FortniteCatalogSectionOffer) GenerateID() {
|
func (f *FortniteCatalogCosmeticOffer) GenerateID() {
|
||||||
for _, item := range f.Grants {
|
for _, item := range f.Grants {
|
||||||
f.ID += item.Type.BackendValue + ":" + item.ID + ","
|
f.ID += item.Type.BackendValue + ":" + item.ID + ","
|
||||||
}
|
}
|
||||||
|
@ -140,18 +207,18 @@ func (f *FortniteCatalogSectionOffer) GenerateID() {
|
||||||
f.ID = "v2:/" + aid.Hash([]byte(f.ID))
|
f.ID = "v2:/" + aid.Hash([]byte(f.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FortniteCatalogSectionOffer) GenerateTotalPrice() {
|
func (f *FortniteCatalogCosmeticOffer) GenerateTotalPrice() {
|
||||||
if !f.BundleInfo.IsBundle {
|
if !f.BundleInfo.IsBundle {
|
||||||
f.TotalPrice = price(f.Grants[0].Rarity.BackendValue, f.Grants[0].Type.BackendValue)
|
f.TotalPrice = DataClient.GetStorefrontCosmeticOfferPrice(f.Grants[0].Rarity.BackendValue, f.Grants[0].Type.BackendValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range f.Grants {
|
for _, item := range f.Grants {
|
||||||
f.TotalPrice += price(item.Rarity.BackendValue, item.Rarity.BackendValue)
|
f.TotalPrice += DataClient.GetStorefrontCosmeticOfferPrice(item.Rarity.BackendValue, item.Rarity.BackendValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FortniteCatalogSectionOffer) GenerateFortniteCatalogSectionOffer() aid.JSON {
|
func (f *FortniteCatalogCosmeticOffer) GenerateFortniteCatalogCosmeticOfferResponse() aid.JSON {
|
||||||
f.GenerateTotalPrice()
|
f.GenerateTotalPrice()
|
||||||
|
|
||||||
itemGrantResponse := []aid.JSON{}
|
itemGrantResponse := []aid.JSON{}
|
||||||
|
@ -234,7 +301,7 @@ func (f *FortniteCatalogSectionOffer) GenerateFortniteCatalogSectionOffer() aid.
|
||||||
|
|
||||||
type FortniteCatalogSection struct {
|
type FortniteCatalogSection struct {
|
||||||
Name string
|
Name string
|
||||||
Offers []*FortniteCatalogSectionOffer
|
Offers []*FortniteCatalogCosmeticOffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFortniteCatalogSection(name string) *FortniteCatalogSection {
|
func NewFortniteCatalogSection(name string) *FortniteCatalogSection {
|
||||||
|
@ -243,10 +310,10 @@ func NewFortniteCatalogSection(name string) *FortniteCatalogSection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FortniteCatalogSection) GenerateFortniteCatalogSection() aid.JSON {
|
func (f *FortniteCatalogSection) GenerateFortniteCatalogSectionResponse() aid.JSON {
|
||||||
catalogEntiresResponse := []aid.JSON{}
|
catalogEntiresResponse := []aid.JSON{}
|
||||||
for _, offer := range f.Offers {
|
for _, offer := range f.Offers {
|
||||||
catalogEntiresResponse = append(catalogEntiresResponse, offer.GenerateFortniteCatalogSectionOffer())
|
catalogEntiresResponse = append(catalogEntiresResponse, offer.GenerateFortniteCatalogCosmeticOfferResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
return aid.JSON{
|
return aid.JSON{
|
||||||
|
@ -255,12 +322,12 @@ func (f *FortniteCatalogSection) GenerateFortniteCatalogSection() aid.JSON {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FortniteCatalogSection) GetGroupedOffers() map[string][]*FortniteCatalogSectionOffer {
|
func (f *FortniteCatalogSection) GetGroupedOffers() map[string][]*FortniteCatalogCosmeticOffer {
|
||||||
groupedOffers := map[string][]*FortniteCatalogSectionOffer{}
|
groupedOffers := map[string][]*FortniteCatalogCosmeticOffer{}
|
||||||
|
|
||||||
for _, offer := range f.Offers {
|
for _, offer := range f.Offers {
|
||||||
if groupedOffers[offer.Meta.Category] == nil {
|
if groupedOffers[offer.Meta.Category] == nil {
|
||||||
groupedOffers[offer.Meta.Category] = []*FortniteCatalogSectionOffer{}
|
groupedOffers[offer.Meta.Category] = []*FortniteCatalogCosmeticOffer{}
|
||||||
}
|
}
|
||||||
|
|
||||||
groupedOffers[offer.Meta.Category] = append(groupedOffers[offer.Meta.Category], offer)
|
groupedOffers[offer.Meta.Category] = append(groupedOffers[offer.Meta.Category], offer)
|
||||||
|
@ -271,18 +338,33 @@ func (f *FortniteCatalogSection) GetGroupedOffers() map[string][]*FortniteCatalo
|
||||||
|
|
||||||
type FortniteCatalog struct {
|
type FortniteCatalog struct {
|
||||||
Sections []*FortniteCatalogSection
|
Sections []*FortniteCatalogSection
|
||||||
|
MoneyOffers []*FortniteCatalogCurrencyOffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFortniteCatalog() *FortniteCatalog {
|
func NewFortniteCatalog() *FortniteCatalog {
|
||||||
return &FortniteCatalog{}
|
return &FortniteCatalog{
|
||||||
|
Sections: []*FortniteCatalogSection{},
|
||||||
|
MoneyOffers: []*FortniteCatalogCurrencyOffer{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FortniteCatalog) GenerateFortniteCatalog() aid.JSON {
|
func (f *FortniteCatalog) GenerateFortniteCatalogResponse() aid.JSON {
|
||||||
catalogSectionsResponse := []aid.JSON{}
|
catalogSectionsResponse := []aid.JSON{}
|
||||||
|
|
||||||
for _, section := range f.Sections {
|
for _, section := range f.Sections {
|
||||||
catalogSectionsResponse = append(catalogSectionsResponse, section.GenerateFortniteCatalogSection())
|
catalogSectionsResponse = append(catalogSectionsResponse, section.GenerateFortniteCatalogSectionResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currencyOffersResponse := []aid.JSON{}
|
||||||
|
for _, offer := range f.MoneyOffers {
|
||||||
|
currencyOffersResponse = append(currencyOffersResponse, offer.GenerateFortniteCatalogCurrencyOfferResponse())
|
||||||
|
}
|
||||||
|
|
||||||
|
catalogSectionsResponse = append(catalogSectionsResponse, aid.JSON{
|
||||||
|
"name": "CurrencyStorefront",
|
||||||
|
"catalogEntries": currencyOffersResponse,
|
||||||
|
})
|
||||||
|
|
||||||
return aid.JSON{
|
return aid.JSON{
|
||||||
"storefronts": catalogSectionsResponse,
|
"storefronts": catalogSectionsResponse,
|
||||||
"refreshIntervalHrs": 24,
|
"refreshIntervalHrs": 24,
|
||||||
|
@ -291,27 +373,49 @@ func (f *FortniteCatalog) GenerateFortniteCatalog() aid.JSON {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *FortniteCatalog) FindCosmeticOfferById(id string) *FortniteCatalogCosmeticOffer {
|
||||||
|
for _, section := range f.Sections {
|
||||||
|
for _, offer := range section.Offers {
|
||||||
|
if offer.ID == id {
|
||||||
|
return offer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FortniteCatalog) FindCurrencyOfferById(id string) *FortniteCatalogCurrencyOffer {
|
||||||
|
for _, offer := range f.MoneyOffers {
|
||||||
|
if offer.ID == id {
|
||||||
|
return offer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewRandomFortniteCatalog() *FortniteCatalog {
|
func NewRandomFortniteCatalog() *FortniteCatalog {
|
||||||
aid.SetRandom(rand.New(rand.NewSource(int64(aid.Config.Fortnite.ShopSeed) + aid.CurrentDayUnix())))
|
aid.SetRandom(rand.New(rand.NewSource(int64(aid.Config.Fortnite.ShopSeed) + aid.CurrentDayUnix())))
|
||||||
catalog := NewFortniteCatalog()
|
catalog := NewFortniteCatalog()
|
||||||
|
|
||||||
daily := NewFortniteCatalogSection("BRDailyStorefront")
|
daily := NewFortniteCatalogSection("BRDailyStorefront")
|
||||||
for len(daily.Offers) < dailyItems(aid.Config.Fortnite.Season) {
|
for len(daily.Offers) < DataClient.GetStorefrontDailyItemCount(aid.Config.Fortnite.Season) {
|
||||||
entry := newEntryFromFortniteItem(GetRandomItemWithDisplayAssetOfNotType("AthenaCharacter"), false)
|
entry := newCosmeticOfferFromFortniteitem(GetRandomItemWithDisplayAssetOfNotType("AthenaCharacter"), false)
|
||||||
entry.Meta.SectionId = "Daily"
|
entry.Meta.SectionId = "Daily"
|
||||||
daily.Offers = append(daily.Offers, entry)
|
daily.Offers = append(daily.Offers, entry)
|
||||||
}
|
}
|
||||||
catalog.Sections = append(catalog.Sections, daily)
|
catalog.Sections = append(catalog.Sections, daily)
|
||||||
|
|
||||||
weekly := NewFortniteCatalogSection("BRWeeklyStorefront")
|
weekly := NewFortniteCatalogSection("BRWeeklyStorefront")
|
||||||
for len(weekly.GetGroupedOffers()) < weeklySets(aid.Config.Fortnite.Season) {
|
for len(weekly.GetGroupedOffers()) < DataClient.GetStorefrontWeeklySetCount(aid.Config.Fortnite.Season) {
|
||||||
set := GetRandomSet()
|
set := GetRandomSet()
|
||||||
for _, item := range set.Items {
|
for _, item := range set.Items {
|
||||||
if item.DisplayAssetPath == "" || item.DisplayAssetPath2 == "" {
|
if item.DisplayAssetPath == "" || item.DisplayAssetPath2 == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
entry := newEntryFromFortniteItem(item, true)
|
entry := newCosmeticOfferFromFortniteitem(item, true)
|
||||||
entry.Meta.Category = set.BackendName
|
entry.Meta.Category = set.BackendName
|
||||||
entry.Meta.SectionId = "Featured"
|
entry.Meta.SectionId = "Featured"
|
||||||
weekly.Offers = append(weekly.Offers, entry)
|
weekly.Offers = append(weekly.Offers, entry)
|
||||||
|
@ -319,10 +423,39 @@ func NewRandomFortniteCatalog() *FortniteCatalog {
|
||||||
}
|
}
|
||||||
catalog.Sections = append(catalog.Sections, weekly)
|
catalog.Sections = append(catalog.Sections, weekly)
|
||||||
|
|
||||||
|
if aid.Config.Fortnite.EnableVBucks {
|
||||||
|
smallCurrencyOffer := newCurrencyOfferFromName("Small Currency Pack", 1000, 0)
|
||||||
|
smallCurrencyOffer.Meta.IconSize = "XSmall"
|
||||||
|
smallCurrencyOffer.Meta.CurrencyAnalyticsName = "MtxPack1000"
|
||||||
|
smallCurrencyOffer.Priority = -len(catalog.MoneyOffers)
|
||||||
|
catalog.MoneyOffers = append(catalog.MoneyOffers, smallCurrencyOffer)
|
||||||
|
|
||||||
|
mediumCurrencyOffer := newCurrencyOfferFromName("Medium Currency Pack", 2000, 800)
|
||||||
|
mediumCurrencyOffer.Meta.IconSize = "Small"
|
||||||
|
mediumCurrencyOffer.Meta.CurrencyAnalyticsName = "MtxPack2800"
|
||||||
|
mediumCurrencyOffer.Meta.BannerOverride = "12PercentExtra"
|
||||||
|
mediumCurrencyOffer.Priority = -len(catalog.MoneyOffers)
|
||||||
|
catalog.MoneyOffers = append(catalog.MoneyOffers, mediumCurrencyOffer)
|
||||||
|
|
||||||
|
intermediateCurrencyOffer := newCurrencyOfferFromName("Intermediate Currency Pack", 4000, 1000)
|
||||||
|
intermediateCurrencyOffer.Meta.IconSize = "Medium"
|
||||||
|
intermediateCurrencyOffer.Meta.CurrencyAnalyticsName = "MtxPack5000"
|
||||||
|
intermediateCurrencyOffer.Meta.BannerOverride = "25PercentExtra"
|
||||||
|
intermediateCurrencyOffer.Priority = -len(catalog.MoneyOffers)
|
||||||
|
catalog.MoneyOffers = append(catalog.MoneyOffers, intermediateCurrencyOffer)
|
||||||
|
|
||||||
|
jumboCurrencyOffer := newCurrencyOfferFromName("Jumbo Currency Pack", 10000, 3500)
|
||||||
|
jumboCurrencyOffer.Meta.IconSize = "XLarge"
|
||||||
|
jumboCurrencyOffer.Meta.CurrencyAnalyticsName = "MtxPack13500"
|
||||||
|
jumboCurrencyOffer.Meta.BannerOverride = "35PercentExtra"
|
||||||
|
jumboCurrencyOffer.Priority = -len(catalog.MoneyOffers)
|
||||||
|
catalog.MoneyOffers = append(catalog.MoneyOffers, jumboCurrencyOffer)
|
||||||
|
}
|
||||||
|
|
||||||
return catalog
|
return catalog
|
||||||
}
|
}
|
||||||
|
|
||||||
func newEntryFromFortniteItem(fortniteItem *FortniteItem, addAssets bool) *FortniteCatalogSectionOffer {
|
func newCosmeticOfferFromFortniteitem(fortniteItem *FortniteItem, addAssets bool) *FortniteCatalogCosmeticOffer {
|
||||||
displayAsset := regexp.MustCompile(`[^/]+$`).FindString(fortniteItem.DisplayAssetPath)
|
displayAsset := regexp.MustCompile(`[^/]+$`).FindString(fortniteItem.DisplayAssetPath)
|
||||||
|
|
||||||
entry := NewFortniteCatalogSectionOffer()
|
entry := NewFortniteCatalogSectionOffer()
|
||||||
|
@ -345,16 +478,15 @@ func newEntryFromFortniteItem(fortniteItem *FortniteItem, addAssets bool) *Fortn
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOfferByOfferId(id string) *FortniteCatalogSectionOffer {
|
func newCurrencyOfferFromName(name string, original, bonus int) *FortniteCatalogCurrencyOffer {
|
||||||
catalog := NewRandomFortniteCatalog()
|
formattedPrice := aid.FormatNumber(original + bonus)
|
||||||
|
offer := NewFortniteCatalogCurrencyOffer(original, bonus)
|
||||||
|
offer.Meta.IconSize = "Small"
|
||||||
|
offer.Meta.CurrencyAnalyticsName = name
|
||||||
|
offer.DevName = name
|
||||||
|
offer.Title = formattedPrice + " V-Bucks"
|
||||||
|
offer.Description = "Buy " + formattedPrice + " Fortnite V-Bucks, the in-game currency that can be spent in Fortnite Battle Royale and Creative modes. You can purchase new customization items like Outfits, Gliders, Pickaxes, Emotes, Wraps and the latest season's Battle Pass! Gliders and Contrails may not be used in Save the World mode."
|
||||||
|
offer.LongDescription = "Buy " + formattedPrice + " Fortnite V-Bucks, the in-game currency that can be spent in Fortnite Battle Royale and Creative modes. You can purchase new customization items like Outfits, Gliders, Pickaxes, Emotes, Wraps and the latest season's Battle Pass! Gliders and Contrails may not be used in Save the World mode.\n\nAll V-Bucks purchased on the Epic Games Store are not redeemable or usable on Nintendo Switch™."
|
||||||
|
|
||||||
for _, section := range catalog.Sections {
|
|
||||||
for _, offer := range section.Offers {
|
|
||||||
if offer.ID == id {
|
|
||||||
return offer
|
return offer
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@ func MiddlewareOnlyDebug(c *fiber.Ctx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSnowPreloadedCosmetics(c *fiber.Ctx) error {
|
func GetSnowPreloadedCosmetics(c *fiber.Ctx) error {
|
||||||
return c.JSON(fortnite.External)
|
return c.JSON(fortnite.DataClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSnowCachedPlayers(c *fiber.Ctx) error {
|
func GetSnowCachedPlayers(c *fiber.Ctx) error {
|
||||||
|
@ -43,7 +43,7 @@ func GetSnowParties(c *fiber.Ctx) error {
|
||||||
|
|
||||||
func GetSnowShop(c *fiber.Ctx) error {
|
func GetSnowShop(c *fiber.Ctx) error {
|
||||||
shop := fortnite.NewRandomFortniteCatalog()
|
shop := fortnite.NewRandomFortniteCatalog()
|
||||||
return c.JSON(shop.GenerateFortniteCatalog())
|
return c.JSON(shop.GenerateFortniteCatalogResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
|
@ -11,7 +13,7 @@ import (
|
||||||
|
|
||||||
func GetStorefrontCatalog(c *fiber.Ctx) error {
|
func GetStorefrontCatalog(c *fiber.Ctx) error {
|
||||||
shop := fortnite.NewRandomFortniteCatalog()
|
shop := fortnite.NewRandomFortniteCatalog()
|
||||||
return c.Status(200).JSON(shop.GenerateFortniteCatalog())
|
return c.Status(200).JSON(shop.GenerateFortniteCatalogResponse())
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStorefrontKeychain(c *fiber.Ctx) error {
|
func GetStorefrontKeychain(c *fiber.Ctx) error {
|
||||||
|
@ -23,3 +25,25 @@ func GetStorefrontKeychain(c *fiber.Ctx) error {
|
||||||
|
|
||||||
return c.Status(200).JSON(keychain)
|
return c.Status(200).JSON(keychain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetStorefrontCatalogBulkOffers(c *fiber.Ctx) error {
|
||||||
|
shop := fortnite.NewRandomFortniteCatalog()
|
||||||
|
|
||||||
|
appStoreIdBytes := c.Request().URI().QueryArgs().PeekMulti("id")
|
||||||
|
appStoreIds := make([]string, len(appStoreIdBytes))
|
||||||
|
for i, id := range appStoreIdBytes {
|
||||||
|
appStoreIds[i] = string(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
response := aid.JSON{}
|
||||||
|
for _, id := range appStoreIds {
|
||||||
|
offer := shop.FindCurrencyOfferById(strings.ReplaceAll(id, "app-", ""))
|
||||||
|
if offer == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
response[id] = offer.GenerateFortniteCatalogBulkOfferResponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(200).JSON(response)
|
||||||
|
}
|
1
main.go
1
main.go
|
@ -112,6 +112,7 @@ func main() {
|
||||||
storefront.Use(aid.FiberLimiter(4))
|
storefront.Use(aid.FiberLimiter(4))
|
||||||
storefront.Get("/catalog", handlers.GetStorefrontCatalog)
|
storefront.Get("/catalog", handlers.GetStorefrontCatalog)
|
||||||
storefront.Get("/keychain", handlers.GetStorefrontKeychain)
|
storefront.Get("/keychain", handlers.GetStorefrontKeychain)
|
||||||
|
r.Get("/catalog/api/shared/bulk/offers", handlers.GetStorefrontCatalogBulkOffers)
|
||||||
|
|
||||||
matchmaking := fortnite.Group("/matchmaking")
|
matchmaking := fortnite.Group("/matchmaking")
|
||||||
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetMatchmakingSession)
|
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetMatchmakingSession)
|
||||||
|
|
|
@ -30,7 +30,9 @@ And once battle royale is completed ...
|
||||||
- **Gifting** Of any item shop entry to any friend.
|
- **Gifting** Of any item shop entry to any friend.
|
||||||
- **Locker Loadouts** On seasons 12 onwards, this allows for the saving and loading of multiple locker presets.
|
- **Locker Loadouts** On seasons 12 onwards, this allows for the saving and loading of multiple locker presets.
|
||||||
- **Item Refunding** Of previous shop purchases, will use a refund ticket if refunded in time.
|
- **Item Refunding** Of previous shop purchases, will use a refund ticket if refunded in time.
|
||||||
|
- **V-Bucks Purchasing** By V-Bucks and Starter Packs right from the in-game store!
|
||||||
- **Client Settings Storage** Uses amazon buckets to store client settings.
|
- **Client Settings Storage** Uses amazon buckets to store client settings.
|
||||||
|
- **Giftable Bundles** Players can recieve bundles, e.g. Twitch Prime, and gift them to friends.
|
||||||
- **Support A Creator 5%** Use any display name and each purchase will give them 5% of the vbucks spent.
|
- **Support A Creator 5%** Use any display name and each purchase will give them 5% of the vbucks spent.
|
||||||
- **Discord Bot** Very useful to control players, their inventory and their settings
|
- **Discord Bot** Very useful to control players, their inventory and their settings
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user