Fix minor issues

This commit is contained in:
eccentric 2023-12-06 22:26:42 +00:00
parent f4fa7866fd
commit 045ac4ff1b
6 changed files with 39 additions and 54 deletions

View File

@ -82,6 +82,7 @@ type FAPI_Cosmetic struct {
Path string `json:"path"` Path string `json:"path"`
Added string `json:"added"` Added string `json:"added"`
ShopHistory []string `json:"shopHistory"` ShopHistory []string `json:"shopHistory"`
BattlePass bool `json:"battlePass"`
} }
type Set struct { type Set struct {
@ -214,18 +215,24 @@ func (f *FortniteAPI) GetAllCosmetics() ([]FAPI_Cosmetic, error) {
} }
func PreloadCosmetics(max int) error { func PreloadCosmetics(max int) error {
aid.Print("Fortnite Assets from", "https://fortnite-api.com") aid.Print("Fortnite Assets from", StaticAPI.URL)
list, err := StaticAPI.GetAllCosmetics() list, err := StaticAPI.GetAllCosmetics()
if err != nil { if err != nil {
return err return err
} }
battlePassSkins := make([]FAPI_Cosmetic, 0)
for _, item := range list { for _, item := range list {
if item.Introduction.BackendValue > max { if item.Introduction.BackendValue > max {
continue continue
} }
if len(item.ShopHistory) == 0 && item.Type.Value == "outfit" {
item.BattlePass = true
battlePassSkins = append(battlePassSkins, item)
}
Cosmetics.Items[item.ID] = item Cosmetics.Items[item.ID] = item
if item.Set.BackendValue != "" { if item.Set.BackendValue != "" {
@ -243,14 +250,20 @@ func PreloadCosmetics(max int) error {
aid.Print("Preloaded", len(Cosmetics.Items), "cosmetics") aid.Print("Preloaded", len(Cosmetics.Items), "cosmetics")
aid.Print("Preloaded", len(Cosmetics.Sets), "sets") aid.Print("Preloaded", len(Cosmetics.Sets), "sets")
aid.Print("Preloaded", len(battlePassSkins), "battle pass skins")
notFound := make([]string, 0) found := make([]string, 0)
characters := make([]string, 0)
for id, item := range Cosmetics.Items { for id, item := range Cosmetics.Items {
if item.ItemPreviewHeroPath == "" { if item.Type.Value == "outfit" {
characters = append(characters, id)
}
if item.Type.Value != "backpack" {
continue continue
} }
if item.Type.Value != "AthenaBackpack" { if item.ItemPreviewHeroPath == "" {
continue continue
} }
@ -259,19 +272,24 @@ func PreloadCosmetics(max int) error {
character, ok := Cosmetics.Items[characterId] character, ok := Cosmetics.Items[characterId]
if !ok { if !ok {
notFound = append(notFound, characterId)
continue continue
} }
character.Backpack = id character.Backpack = id
Cosmetics.Items[characterId] = character Cosmetics.Items[characterId] = character
if _, ok := Cosmetics.Sets[character.Set.BackendValue]; !ok {
Cosmetics.Sets[character.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: character.Set.Value,
BackendName: character.Set.BackendValue,
}
}
Cosmetics.Sets[character.Set.BackendValue].Items[characterId] = character Cosmetics.Sets[character.Set.BackendValue].Items[characterId] = character
found = append(found, id)
} }
if len(notFound) > 0 { // print the perecentage of backpacks that have a character
aid.Print("Couldn't find", len(notFound), "backpacks for characters:", notFound) aid.Print("Preloaded", len(found), "backpacks with characters", "(", float64(len(found))/float64(len(characters))*100, "% )")
}
DAv2 := *storage.Asset("assets.json") DAv2 := *storage.Asset("assets.json")
if DAv2 == nil { if DAv2 == nil {

View File

@ -53,8 +53,8 @@ func NewFortnitePerson(displayName string, key string) *p.Person {
} }
if item == "Currency:MtxPurchased" { if item == "Currency:MtxPurchased" {
person.CommonCoreProfile.Items.AddItem(p.NewItem(item, 9999)).Save() person.CommonCoreProfile.Items.AddItem(p.NewItem(item, 0)).Save()
person.Profile0Profile.Items.AddItem(p.NewItem(item, 9999)).Save() person.Profile0Profile.Items.AddItem(p.NewItem(item, 0)).Save()
continue continue
} }

View File

@ -307,7 +307,7 @@ func (e *Entry) GenerateResponse(p *person.Person) aid.JSON {
return json return json
} }
func GenerateStorefront() { func GenerateRandomStorefront() {
storefront := NewCatalog() storefront := NewCatalog()
daily := NewStorefront("BRDailyStorefront") daily := NewStorefront("BRDailyStorefront")

View File

@ -404,13 +404,17 @@ func PostPurchaseCatalogEntryAction(c *fiber.Ctx, person *p.Person, profile *p.P
}() }()
if offer.ProfileType != "athena" { if offer.ProfileType != "athena" {
return fmt.Errorf("save the world not implemeted yet!") return fmt.Errorf("save the world not implemeted yet")
} }
loot := []aid.JSON{} loot := []aid.JSON{}
for i := 0; i < body.PurchaseQuantity; i++ { for i := 0; i < body.PurchaseQuantity; i++ {
for _, grant := range offer.Grants { for _, grant := range offer.Grants {
if profile.Items.GetItemByTemplateID(grant) != nil { if profile.Items.GetItemByTemplateID(grant) != nil {
item := profile.Items.GetItemByTemplateID(grant)
item.Quantity++
go item.Save()
continue continue
} }

View File

@ -29,7 +29,7 @@ func init() {
func init() { func init() {
fortnite.PreloadCosmetics(aid.Config.Fortnite.Season) fortnite.PreloadCosmetics(aid.Config.Fortnite.Season)
fortnite.GenerateStorefront() fortnite.GenerateRandomStorefront()
if aid.Config.Database.DropAllTables { if aid.Config.Database.DropAllTables {
fortnite.NewFortnitePerson("ac", "1") fortnite.NewFortnitePerson("ac", "1")

View File

@ -7,49 +7,12 @@ Performance first, universal Fortnite private server backend written in Go.
## Features ## Features
- **Blazing Fast** Written in Go and build on Fast HTTP, snow is extremely fast and can handle any profile action in milliseconds with its caching system. - **Blazing Fast** Written in Go and build on Fast HTTP, snow is extremely fast and can handle any profile action in milliseconds with its caching system.
- **Profile Changes** Snow, semi-automatically, keeps track of profile changes exactly like Fortnite does, meaning it is one-to-one with the game. - **Profile Changes** Snow, automatically, keeps track of profile changes exactly like Fortnite does, meaning it is one-to-one with the game and never desyncs.
- **Universal Database** Easily add new storage methods that satisfy the `Storage` interface. This means you can use any database you want. _(example of how to do this coming soon)_ - **Universal Database** Easily add new storage methods that satisfy the `Storage` interface. This means you can use any database you want. _(example of how to do this coming soon)_
## Examples of Person Structures
### Quests
```golang
schedule := person.NewItem("ChallengeBundleSchedule:Paid_1", 1)
user.AthenaProfile.Items.AddItem(schedule)
bundle := person.NewItem("ChallengeBundle:Daily_1", 1)
user.AthenaProfile.Items.AddItem(bundle)
quest := person.NewQuest("Quest:Quest_2", bundle.ID, schedule.ID)
quest.AddObjective("quest_objective_eliminateplayers", 0)
user.AthenaProfile.Quests.AddQuest(quest)
daily := person.NewDailyQuest("Quest:Quest_3")
daily.AddObjective("quest_objective_place_top10", 0)
user.AthenaProfile.Quests.AddQuest(daily)
```
### Profile Changes
```golang
snapshot := user.CommonCoreProfile.Snapshot()
{
vbucks := user.CommonCoreProfile.Items.GetItemByTemplateID("Currency:MtxPurchased")
vbucks.Quantity = 200
vbucks.Favorite = true
user.CommonCoreProfile.Items.DeleteItem(user.CommonCoreProfile.Items.GetItemByTemplateID("Token:CampaignAccess").ID)
user.CommonCoreProfile.Items.AddItem(person.NewItem("Token:ReceiveMtxCurrency", 1))
}
user.CommonCoreProfile.Diff(snapshot)
```
## What's next? ## What's next?
- Every endpoint that is used by Fortnite. This includes all MCP Operations, extracting data from the telemetry and even the Party Service (maybe party v2). - Final Fortnite Operations, this includes: Battle Pass, Friends, XMPP and Gifting.
- Automatic storefront that uses previous data to generate a storefront. This would use item shops from history to make sure there are no blank spots in the storefront. Also battle pass tiers etc.
- Embed game assets into the backend e.g. Battle Pass, Quest Data etc. _This would mean a single binary that can be run anywhere without the need of external files._
- Interact with external Services like Amazon S3 Buckets to save player data externally. - Interact with external Services like Amazon S3 Buckets to save player data externally.
- A way to interact with accounts outside of the game. This is mainly for a web app and other services to interact with the backend. - A way to interact with accounts outside of the game. This is mainly for a web app and other services to interact with the backend.