Fix minor issues
This commit is contained in:
parent
f4fa7866fd
commit
045ac4ff1b
|
@ -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,20 +272,25 @@ 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
|
||||||
Cosmetics.Sets[character.Set.BackendValue].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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(notFound) > 0 {
|
Cosmetics.Sets[character.Set.BackendValue].Items[characterId] = character
|
||||||
aid.Print("Couldn't find", len(notFound), "backpacks for characters:", notFound)
|
found = append(found, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print the perecentage of backpacks that have a character
|
||||||
|
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 {
|
||||||
aid.Print("Couldn't find DAv2.json")
|
aid.Print("Couldn't find DAv2.json")
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
main.go
2
main.go
|
@ -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")
|
||||||
|
|
41
readme.md
41
readme.md
|
@ -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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user