Continue to research how fortnite storefront works.
This commit is contained in:
parent
731705c0f4
commit
5348295631
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -10,3 +10,5 @@
|
||||||
.vscode
|
.vscode
|
||||||
tmp
|
tmp
|
||||||
config.ini
|
config.ini
|
||||||
|
|
||||||
|
hide_*
|
231
fortnite/interact.go
Normal file
231
fortnite/interact.go
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
package fortnite
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ectrc/snow/aid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FortniteAPI struct {
|
||||||
|
URL string
|
||||||
|
C *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
type FAPI_Response struct {
|
||||||
|
Status int `json:"status"`
|
||||||
|
Data []FAPI_Cosmetic `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FAPI_Error struct {
|
||||||
|
Status int `json:"status"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FAPI_Cosmetic struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Type struct {
|
||||||
|
Value string `json:"value"`
|
||||||
|
DisplayValue string `json:"displayValue"`
|
||||||
|
BackendValue string `json:"backendValue"`
|
||||||
|
} `json:"type"`
|
||||||
|
Rarity struct {
|
||||||
|
Value string `json:"value"`
|
||||||
|
DisplayValue string `json:"displayValue"`
|
||||||
|
BackendValue string `json:"backendValue"`
|
||||||
|
} `json:"rarity"`
|
||||||
|
Series struct {
|
||||||
|
Value string `json:"value"`
|
||||||
|
Image string `json:"image"`
|
||||||
|
BackendValue string `json:"backendValue"`
|
||||||
|
} `json:"series"`
|
||||||
|
Set struct {
|
||||||
|
Value string `json:"value"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
BackendValue string `json:"backendValue"`
|
||||||
|
} `json:"set"`
|
||||||
|
Introduction struct {
|
||||||
|
Chapter string `json:"chapter"`
|
||||||
|
Season string `json:"season"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
BackendValue int `json:"backendValue"`
|
||||||
|
} `json:"introduction"`
|
||||||
|
Images struct {
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
Featured string `json:"featured"`
|
||||||
|
SmallIcon string `json:"smallIcon"`
|
||||||
|
Other map[string]string `json:"other"`
|
||||||
|
} `json:"images"`
|
||||||
|
Variants []struct {
|
||||||
|
Channel string `json:"channel"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Options []struct {
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Image string `json:"image"`
|
||||||
|
} `json:"options"`
|
||||||
|
} `json:"variants"`
|
||||||
|
GameplayTags []string `json:"gameplayTags"`
|
||||||
|
SearchTags []string `json:"searchTags"`
|
||||||
|
MetaTags []string `json:"metaTags"`
|
||||||
|
ShowcaseVideo string `json:"showcaseVideo"`
|
||||||
|
DynamicPakID string `json:"dynamicPakId"`
|
||||||
|
DisplayAssetPath string `json:"displayAssetPath"`
|
||||||
|
ItemPreviewHeroPath string `json:"itemPreviewHeroPath"`
|
||||||
|
Backpack string `json:"backpack"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Added string `json:"added"`
|
||||||
|
ShopHistory []string `json:"shopHistory"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Set struct {
|
||||||
|
Items map[string]FAPI_Cosmetic `json:"items"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CosmeticData struct {
|
||||||
|
Items map[string]FAPI_Cosmetic `json:"items"`
|
||||||
|
Sets map[string]Set `json:"sets"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CosmeticData) GetRandomItem() FAPI_Cosmetic {
|
||||||
|
randomInt := rand.Intn(len(c.Items))
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for _, item := range c.Items {
|
||||||
|
if i == randomInt {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.GetRandomItem()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CosmeticData) GetRandomSet() Set {
|
||||||
|
randomInt := rand.Intn(len(c.Sets))
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for _, set := range c.Sets {
|
||||||
|
if i == randomInt {
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.GetRandomSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
StaticAPI = NewFortniteAPI()
|
||||||
|
Cosmetics = CosmeticData{
|
||||||
|
Items: make(map[string]FAPI_Cosmetic),
|
||||||
|
Sets: make(map[string]Set),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewFortniteAPI() *FortniteAPI {
|
||||||
|
return &FortniteAPI{
|
||||||
|
URL: "https://fortnite-api.com",
|
||||||
|
C: &http.Client{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FortniteAPI) Get(path string) (*FAPI_Response, error) {
|
||||||
|
req, err := http.NewRequest("GET", f.URL + path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := f.C.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var data FAPI_Response
|
||||||
|
err = json.Unmarshal(bodyBytes, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FortniteAPI) GetAllCosmetics() ([]FAPI_Cosmetic, error) {
|
||||||
|
resp, err := f.Get("/v2/cosmetics/br")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PreloadCosmetics(max int) error {
|
||||||
|
list, err := StaticAPI.GetAllCosmetics()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range list {
|
||||||
|
if item.Introduction.BackendValue > max {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Cosmetics.Items[item.ID] = item
|
||||||
|
|
||||||
|
if item.Set.BackendValue != "" {
|
||||||
|
if _, ok := Cosmetics.Sets[item.Set.BackendValue]; !ok {
|
||||||
|
Cosmetics.Sets[item.Set.BackendValue] = Set{
|
||||||
|
Items: make(map[string]FAPI_Cosmetic),
|
||||||
|
Name: item.Set.Value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cosmetics.Sets[item.Set.BackendValue].Items[item.ID] = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aid.Print("Preloaded", len(Cosmetics.Items), "cosmetics")
|
||||||
|
aid.Print("Preloaded", len(Cosmetics.Sets), "sets")
|
||||||
|
|
||||||
|
notFound := make([]string, 0)
|
||||||
|
for id, item := range Cosmetics.Items {
|
||||||
|
if item.ItemPreviewHeroPath == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Type.Value != "AthenaBackpack" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
previewHeroPath := strings.Split(item.ItemPreviewHeroPath, "/")
|
||||||
|
characterId := previewHeroPath[len(previewHeroPath)-1]
|
||||||
|
|
||||||
|
character, ok := Cosmetics.Items[characterId]
|
||||||
|
if !ok {
|
||||||
|
notFound = append(notFound, characterId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
character.Backpack = id
|
||||||
|
|
||||||
|
Cosmetics.Items[characterId] = character
|
||||||
|
Cosmetics.Sets[character.Set.BackendValue].Items[characterId] = character
|
||||||
|
}
|
||||||
|
|
||||||
|
aid.Print("Could not find", len(notFound), "items with backpacks")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
package fortnite
|
package fortnite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
p "github.com/ectrc/snow/person"
|
p "github.com/ectrc/snow/person"
|
||||||
"github.com/ectrc/snow/storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -35,21 +34,27 @@ func NewFortnitePerson(displayName string, key string) *p.Person {
|
||||||
for _, item := range defaultCommonCoreItems {
|
for _, item := range defaultCommonCoreItems {
|
||||||
if item == "HomebaseBannerIcon:StandardBanner" {
|
if item == "HomebaseBannerIcon:StandardBanner" {
|
||||||
for i := 1; i < 32; i++ {
|
for i := 1; i < 32; i++ {
|
||||||
person.CommonCoreProfile.Items.AddItem(p.NewItem(item+strconv.Itoa(i), 1)).Save()
|
item := p.NewItem(item+strconv.Itoa(i), 1)
|
||||||
|
item.HasSeen = true
|
||||||
|
person.CommonCoreProfile.Items.AddItem(item).Save()
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if item == "HomebaseBannerColor:DefaultColor" {
|
if item == "HomebaseBannerColor:DefaultColor" {
|
||||||
for i := 1; i < 22; i++ {
|
for i := 1; i < 22; i++ {
|
||||||
person.CommonCoreProfile.Items.AddItem(p.NewItem(item+strconv.Itoa(i), 1)).Save()
|
item := p.NewItem(item+strconv.Itoa(i), 1)
|
||||||
|
item.HasSeen = true
|
||||||
|
person.CommonCoreProfile.Items.AddItem(item).Save()
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if item == "Currency:MtxPurchased" {
|
if item == "Currency:MtxPurchased" {
|
||||||
person.CommonCoreProfile.Items.AddItem(p.NewItem(item, 0)).Save()
|
item := p.NewItem(item, 0)
|
||||||
person.Profile0Profile.Items.AddItem(p.NewItem(item, 0)).Save()
|
item.HasSeen = true
|
||||||
|
person.CommonCoreProfile.Items.AddItem(item).Save()
|
||||||
|
person.Profile0Profile.Items.AddItem(item).Save()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,19 +111,19 @@ func NewFortnitePerson(displayName string, key string) *p.Person {
|
||||||
|
|
||||||
loadout := p.NewLoadout("sandbox_loadout", person.AthenaProfile)
|
loadout := p.NewLoadout("sandbox_loadout", person.AthenaProfile)
|
||||||
person.AthenaProfile.Loadouts.AddLoadout(loadout).Save()
|
person.AthenaProfile.Loadouts.AddLoadout(loadout).Save()
|
||||||
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("loadouts", []string{
|
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("loadouts", []string{loadout.ID})).Save()
|
||||||
loadout.ID,
|
|
||||||
})).Save()
|
|
||||||
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("last_applied_loadout", loadout.ID)).Save()
|
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("last_applied_loadout", loadout.ID)).Save()
|
||||||
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("active_loadout_index", 0)).Save()
|
person.AthenaProfile.Attributes.AddAttribute(p.NewAttribute("active_loadout_index", 0)).Save()
|
||||||
|
|
||||||
if aid.Config.Fortnite.Everything {
|
if aid.Config.Fortnite.Everything {
|
||||||
allItemsBytes := storage.Asset("cosmetics.json")
|
for _, item := range Cosmetics.Items {
|
||||||
var allItems []string
|
if strings.Contains(strings.ToLower(item.ID), "random") {
|
||||||
json.Unmarshal(*allItemsBytes, &allItems)
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for _, item := range allItems {
|
item := p.NewItem(item.Type.BackendValue + ":" + item.ID, 1)
|
||||||
person.AthenaProfile.Items.AddItem(p.NewItem(item, 1)).Save()
|
item.HasSeen = true
|
||||||
|
person.AthenaProfile.Items.AddItem(item).Save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
204
fortnite/shop.go
204
fortnite/shop.go
|
@ -1,10 +1,27 @@
|
||||||
package fortnite
|
package fortnite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
"github.com/ectrc/snow/person"
|
"github.com/ectrc/snow/person"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Rarities = map[string]int{
|
||||||
|
"EFortRarity::Legendary": 2000,
|
||||||
|
"EFortRarity::Epic": 1500,
|
||||||
|
"EFortRarity::Rare": 1200,
|
||||||
|
"EFortRarity::Uncommon": 800,
|
||||||
|
"EFortRarity::Common": 500,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPriceForRarity(rarity string) int {
|
||||||
|
return Rarities[rarity]
|
||||||
|
}
|
||||||
|
|
||||||
type Catalog struct {
|
type Catalog struct {
|
||||||
RefreshIntervalHrs int `json:"refreshIntervalHrs"`
|
RefreshIntervalHrs int `json:"refreshIntervalHrs"`
|
||||||
DailyPurchaseHrs int `json:"dailyPurchaseHrs"`
|
DailyPurchaseHrs int `json:"dailyPurchaseHrs"`
|
||||||
|
@ -63,87 +80,63 @@ func (s *Storefront) GenerateResponse(p *person.Person) aid.JSON {
|
||||||
"catalogEntries": []aid.JSON{},
|
"catalogEntries": []aid.JSON{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
names := []string{}
|
||||||
for _, entry := range s.CatalogEntries {
|
for _, entry := range s.CatalogEntries {
|
||||||
json["catalogEntries"] = append(json["catalogEntries"].([]aid.JSON), entry.GenerateResponse(p))
|
grantStrings := entry.Grants
|
||||||
|
sort.Strings(grantStrings)
|
||||||
|
for _, grant := range grantStrings {
|
||||||
|
entry.Name += grant + "-"
|
||||||
|
}
|
||||||
|
|
||||||
|
names = append(names, entry.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
aid.PrintJSON(names)
|
||||||
|
sort.Strings(names)
|
||||||
|
|
||||||
|
for _, devname := range names {
|
||||||
|
for _, entry := range s.CatalogEntries {
|
||||||
|
grantStrings := entry.Grants
|
||||||
|
sort.Strings(grantStrings)
|
||||||
|
for _, grant := range grantStrings {
|
||||||
|
entry.Name += grant + "-"
|
||||||
|
}
|
||||||
|
|
||||||
|
if devname == entry.Name {
|
||||||
|
json["catalogEntries"] = append(json["catalogEntries"].([]aid.JSON), entry.GenerateResponse(p))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return json
|
return json
|
||||||
}
|
}
|
||||||
|
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
Price int
|
|
||||||
ID string
|
ID string
|
||||||
Name string
|
Name string
|
||||||
Title string
|
Price int
|
||||||
Description string
|
|
||||||
Type string
|
|
||||||
Meta []aid.JSON
|
Meta []aid.JSON
|
||||||
Panel string
|
Panel string
|
||||||
Priority int
|
Priority int
|
||||||
Asset string
|
|
||||||
Grants []string
|
Grants []string
|
||||||
IsBundle bool
|
DisplayAssetPath string
|
||||||
BundleMeta BundleMeta
|
Title string
|
||||||
|
ShortDescription string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewItemEntry(id string, name string, price int) *Entry {
|
func NewCatalogEntry(meta ...aid.JSON) *Entry {
|
||||||
return &Entry{
|
return &Entry{
|
||||||
Price: price,
|
ID: uuid.New().String(),
|
||||||
ID: id,
|
Meta: meta,
|
||||||
Name: name,
|
|
||||||
Type: "StaticPrice",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBundleEntry(id string, name string, price int) *Entry {
|
|
||||||
return &Entry{
|
|
||||||
Price: price,
|
|
||||||
ID: id,
|
|
||||||
Name: name,
|
|
||||||
Type: "DynamicBundle",
|
|
||||||
IsBundle: true,
|
|
||||||
BundleMeta: BundleMeta{
|
|
||||||
FloorPrice: price,
|
|
||||||
RegularBasePrice: price,
|
|
||||||
DiscountedBasePrice: price,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type BundleMeta struct {
|
|
||||||
FloorPrice int
|
|
||||||
RegularBasePrice int
|
|
||||||
DiscountedBasePrice int
|
|
||||||
DisplayType string // "AmountOff" or "PercentOff"
|
|
||||||
BundleItems []BundleItem
|
|
||||||
}
|
|
||||||
|
|
||||||
type BundleItem struct {
|
|
||||||
TemplateID string
|
|
||||||
RegularPrice int
|
|
||||||
DiscountedPrice int
|
|
||||||
AlreadyOwnedPriceReduction int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBundleItem(templateId string, regularPrice int, discountedPrice int, alreadyOwnedPriceReduction int) *BundleItem {
|
|
||||||
return &BundleItem{
|
|
||||||
TemplateID: templateId,
|
|
||||||
RegularPrice: regularPrice,
|
|
||||||
DiscountedPrice: discountedPrice,
|
|
||||||
AlreadyOwnedPriceReduction: alreadyOwnedPriceReduction,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) AddGrant(templateId string) *Entry {
|
func (e *Entry) AddGrant(templateId string) *Entry {
|
||||||
e.Grants = append(e.Grants, templateId)
|
e.Grants = append(e.Grants, templateId)
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Entry) AddBundleGrant(B BundleItem) *Entry {
|
|
||||||
e.BundleMeta.BundleItems = append(e.BundleMeta.BundleItems, B)
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Entry) AddMeta(key string, value interface{}) *Entry {
|
func (e *Entry) AddMeta(key string, value interface{}) *Entry {
|
||||||
e.Meta = append(e.Meta, aid.JSON{
|
e.Meta = append(e.Meta, aid.JSON{
|
||||||
"Key": key,
|
"Key": key,
|
||||||
|
@ -152,11 +145,58 @@ func (e *Entry) AddMeta(key string, value interface{}) *Entry {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Entry) TileSize(size string) *Entry {
|
||||||
|
e.Meta = append(e.Meta, aid.JSON{
|
||||||
|
"Key": "TileSize",
|
||||||
|
"Value": size,
|
||||||
|
})
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entry) PanelType(panel string) *Entry {
|
||||||
|
e.Panel = panel
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entry) Section(sectionId string) *Entry {
|
||||||
|
e.Meta = append(e.Meta, aid.JSON{
|
||||||
|
"Key": "SectionId",
|
||||||
|
"Value": sectionId,
|
||||||
|
})
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entry) DisplayAsset(asset string) *Entry {
|
||||||
|
e.DisplayAssetPath = asset
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entry) SetTitle(title string) *Entry {
|
||||||
|
e.Title = title
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entry) SetShortDescription(description string) *Entry {
|
||||||
|
e.ShortDescription = description
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entry) SetPrice(price int) *Entry {
|
||||||
|
e.Price = price
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Entry) GenerateResponse(p *person.Person) aid.JSON {
|
func (e *Entry) GenerateResponse(p *person.Person) aid.JSON {
|
||||||
|
grantStrings := e.Grants
|
||||||
|
sort.Strings(grantStrings)
|
||||||
|
for _, grant := range grantStrings {
|
||||||
|
e.Name += grant + "-"
|
||||||
|
}
|
||||||
|
|
||||||
json := aid.JSON{
|
json := aid.JSON{
|
||||||
"offerId": e.ID,
|
"offerId": e.ID,
|
||||||
"devName": e.Name,
|
"devName": e.Name,
|
||||||
"offerType": e.Type,
|
"offerType": "StaticPrice",
|
||||||
"prices": []aid.JSON{
|
"prices": []aid.JSON{
|
||||||
{
|
{
|
||||||
"currencyType": "MtxCurrency",
|
"currencyType": "MtxCurrency",
|
||||||
|
@ -169,18 +209,23 @@ func (e *Entry) GenerateResponse(p *person.Person) aid.JSON {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"categories": []string{},
|
"categories": []string{},
|
||||||
"catalogGroupPriority": e.Priority,
|
"catalogGroupPriority": 0,
|
||||||
"dailyLimit": -1,
|
"dailyLimit": -1,
|
||||||
"weeklyLimit": -1,
|
"weeklyLimit": -1,
|
||||||
"monthlyLimit": -1,
|
"monthlyLimit": -1,
|
||||||
"fufillmentIds": []string{},
|
"fufillmentIds": []string{},
|
||||||
"filterWeight": 0,
|
"filterWeight": e.Priority,
|
||||||
"appStoreId": []string{},
|
"appStoreId": []string{},
|
||||||
"refundable": false,
|
"refundable": false,
|
||||||
"itemGrants": []aid.JSON{},
|
"itemGrants": []aid.JSON{},
|
||||||
"metaInfo": e.Meta,
|
"metaInfo": e.Meta,
|
||||||
"meta": aid.JSON{},
|
"meta": aid.JSON{},
|
||||||
"displayAssetPath": e.Asset,
|
"title": e.Title,
|
||||||
|
"shortDescription": e.ShortDescription,
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.DisplayAssetPath != "" {
|
||||||
|
json["displayAssetPath"] = "/" + e.DisplayAssetPath
|
||||||
}
|
}
|
||||||
|
|
||||||
grants := []aid.JSON{}
|
grants := []aid.JSON{}
|
||||||
|
@ -211,45 +256,6 @@ func (e *Entry) GenerateResponse(p *person.Person) aid.JSON {
|
||||||
json["categories"] = []string{e.Panel}
|
json["categories"] = []string{e.Panel}
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.IsBundle {
|
|
||||||
json["dynamicBundleInfo"] = aid.JSON{
|
|
||||||
"discountedBasePrice": e.BundleMeta.DiscountedBasePrice,
|
|
||||||
"regularBasePrice": e.BundleMeta.RegularBasePrice,
|
|
||||||
"floorPrice": e.BundleMeta.FloorPrice,
|
|
||||||
"currencyType": "MtxCurrency",
|
|
||||||
"currencySubType": "Currency",
|
|
||||||
"displayType": "AmountOff",
|
|
||||||
"bundleItems": []aid.JSON{},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, bundleItem := range e.BundleMeta.BundleItems {
|
|
||||||
json["prices"] = []aid.JSON{}
|
|
||||||
|
|
||||||
json["dynamicBundleInfo"].(aid.JSON)["bundleItems"] = append(json["dynamicBundleInfo"].(aid.JSON)["bundleItems"].([]aid.JSON), aid.JSON{
|
|
||||||
"regularPrice": bundleItem.RegularPrice,
|
|
||||||
"discountedPrice": bundleItem.DiscountedPrice,
|
|
||||||
"alreadyOwnedPriceReduction": bundleItem.AlreadyOwnedPriceReduction,
|
|
||||||
"item": aid.JSON{
|
|
||||||
"templateId": bundleItem.TemplateID,
|
|
||||||
"quantity": 1,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
grants = append(grants, aid.JSON{
|
|
||||||
"templateId": bundleItem.TemplateID,
|
|
||||||
"quantity": 1,
|
|
||||||
})
|
|
||||||
|
|
||||||
if item := p.AthenaProfile.Items.GetItemByTemplateID(bundleItem.TemplateID); item != nil {
|
|
||||||
requirements = append(requirements, aid.JSON{
|
|
||||||
"requirementType": "DenyOnItemOwnership",
|
|
||||||
"requiredId": item.ID,
|
|
||||||
"minQuantity": 1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
json["itemGrants"] = grants
|
json["itemGrants"] = grants
|
||||||
json["requirements"] = requirements
|
json["requirements"] = requirements
|
||||||
json["metaInfo"] = meta
|
json["metaInfo"] = meta
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -17,10 +17,12 @@ require (
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/klauspost/compress v1.17.2 // indirect
|
github.com/klauspost/compress v1.17.2 // indirect
|
||||||
github.com/lib/pq v1.10.9 // indirect
|
github.com/lib/pq v1.10.9 // indirect
|
||||||
|
github.com/lukechampine/randmap v0.0.0-20161125183226-9e3c222d0413 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||||
github.com/philhofer/fwd v1.1.2 // indirect
|
github.com/philhofer/fwd v1.1.2 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -194,6 +194,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lukechampine/randmap v0.0.0-20161125183226-9e3c222d0413 h1:tysX0ocX3VYPAW06M8E5sEkRzr+7ygS162QpIi/N3hI=
|
||||||
|
github.com/lukechampine/randmap v0.0.0-20161125183226-9e3c222d0413/go.mod h1:CDBUzfMMkesqPDGmuMzuDrzBd2069GPe4wMJ3FC2sEw=
|
||||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
|
@ -207,6 +209,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
||||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||||
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
|
10
handlers/snow.go
Normal file
10
handlers/snow.go
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ectrc/snow/fortnite"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetPrelaodedCosmetics(c *fiber.Ctx) error {
|
||||||
|
return c.JSON(fortnite.Cosmetics)
|
||||||
|
}
|
|
@ -4,39 +4,59 @@ import (
|
||||||
"github.com/goccy/go-json"
|
"github.com/goccy/go-json"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
"github.com/ectrc/snow/fortnite"
|
|
||||||
"github.com/ectrc/snow/person"
|
|
||||||
"github.com/ectrc/snow/storage"
|
"github.com/ectrc/snow/storage"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetStorefrontCatalog(c *fiber.Ctx) error {
|
func GetStorefrontCatalog(c *fiber.Ctx) error {
|
||||||
person := c.Locals("person").(*person.Person)
|
// person := c.Locals("person").(*person.Person)
|
||||||
storefront := fortnite.NewCatalog()
|
// storefront := fortnite.NewCatalog()
|
||||||
|
|
||||||
bundleStorefront := fortnite.NewStorefront("bundles")
|
// daily := fortnite.NewStorefront("BRDailyStorefront")
|
||||||
{
|
// weekly := fortnite.NewStorefront("BRWeeklyStorefront")
|
||||||
bundle := fortnite.NewBundleEntry("v2:/hello_og", "OG Bundle", 300)
|
|
||||||
bundle.Asset = "/Game/Catalog/NewDisplayAssets/DAv2_CID_A_183_M_AntiquePal_S7A9W.DAv2_CID_A_183_M_AntiquePal_S7A9W"
|
|
||||||
bundle.AddBundleGrant(*fortnite.NewBundleItem("AthenaCharacter:CID_028_Athena_Commando_F", 1000, 500, 800))
|
|
||||||
bundle.AddBundleGrant(*fortnite.NewBundleItem("AthenaCharacter:CID_001_Athena_Commando_F", 1000, 500, 800))
|
|
||||||
bundle.AddMeta("AnalyticOfferGroupId", "3")
|
|
||||||
bundle.AddMeta("SectionId", "OGBundles")
|
|
||||||
bundle.AddMeta("TileSize", "DoubleWide")
|
|
||||||
bundle.AddMeta("NewDisplayAssetPath", bundle.Asset)
|
|
||||||
bundleStorefront.Add(*bundle)
|
|
||||||
|
|
||||||
random := fortnite.NewItemEntry("v2:/random", "Random Bundle", 300)
|
// for len(weekly.CatalogEntries) < 8 {
|
||||||
random.AddGrant("AthenaCharacter:CID_Random")
|
// set := fortnite.Cosmetics.GetRandomSet()
|
||||||
random.AddMeta("AnalyticOfferGroupId", "3")
|
|
||||||
random.AddMeta("SectionId", "OGBundles")
|
|
||||||
random.AddMeta("TileSize", "DoubleWide")
|
|
||||||
|
|
||||||
bundleStorefront.Add(*random)
|
// for _, cosmetic := range set.Items {
|
||||||
|
// if cosmetic.Type.BackendValue == "AthenaBackpack" {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// entry := fortnite.NewCatalogEntry().Section("Featured").DisplayAsset(cosmetic.DisplayAssetPath).SetPrice(fortnite.GetPriceForRarity(cosmetic.Rarity.BackendValue))
|
||||||
|
// entry.AddGrant(cosmetic.Type.BackendValue + ":" + cosmetic.ID)
|
||||||
|
|
||||||
|
// if cosmetic.Backpack != "" {
|
||||||
|
// entry.AddGrant("AthenaBackpack:" + cosmetic.Backpack)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if cosmetic.Type.BackendValue != "AthenaCharacter" {
|
||||||
|
// entry.TileSize("Small")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if cosmetic.Type.BackendValue == "AthenaCharacter" {
|
||||||
|
// entry.TileSize("Normal")
|
||||||
|
// entry.Priority = -99999
|
||||||
|
// }
|
||||||
|
|
||||||
|
// entry.Panel = set.Name
|
||||||
|
|
||||||
|
// weekly.Add(*entry)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// storefront.Add(daily)
|
||||||
|
// storefront.Add(weekly)
|
||||||
|
|
||||||
|
// return c.Status(fiber.StatusOK).JSON(storefront.GenerateFortniteCatalog(person))
|
||||||
|
|
||||||
|
var x aid.JSON
|
||||||
|
err := json.Unmarshal(*storage.Asset("hide_a.json"), &x)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(aid.JSON{"error":err.Error()})
|
||||||
}
|
}
|
||||||
storefront.Add(bundleStorefront)
|
|
||||||
|
|
||||||
return c.Status(fiber.StatusOK).JSON(storefront.GenerateFortniteCatalog(person))
|
return c.Status(fiber.StatusOK).JSON(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetStorefrontKeychain(c *fiber.Ctx) error {
|
func GetStorefrontKeychain(c *fiber.Ctx) error {
|
||||||
|
|
5
main.go
5
main.go
|
@ -28,6 +28,8 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
fortnite.PreloadCosmetics(aid.Config.Fortnite.Season)
|
||||||
|
|
||||||
if aid.Config.Database.DropAllTables {
|
if aid.Config.Database.DropAllTables {
|
||||||
fortnite.NewFortnitePerson("ac", "1")
|
fortnite.NewFortnitePerson("ac", "1")
|
||||||
}
|
}
|
||||||
|
@ -95,6 +97,9 @@ func main() {
|
||||||
lightswitch := r.Group("/lightswitch/api")
|
lightswitch := r.Group("/lightswitch/api")
|
||||||
lightswitch.Get("/service/bulk/status", handlers.GetLightswitchBulkStatus)
|
lightswitch.Get("/service/bulk/status", handlers.GetLightswitchBulkStatus)
|
||||||
|
|
||||||
|
snow := r.Group("/snow")
|
||||||
|
snow.Get("/cosmetics", handlers.GetPrelaodedCosmetics)
|
||||||
|
|
||||||
r.Hooks().OnListen(func(ld fiber.ListenData) error {
|
r.Hooks().OnListen(func(ld fiber.ListenData) error {
|
||||||
aid.Print("Listening on " + ld.Host + ":" + ld.Port)
|
aid.Print("Listening on " + ld.Host + ":" + ld.Port)
|
||||||
return nil
|
return nil
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user