Finish Loadouts on newer seasons; Add every item in the game.
This commit is contained in:
parent
5508ad4348
commit
f1d99b23c7
|
@ -27,6 +27,7 @@ type CS struct {
|
|||
Fortnite struct {
|
||||
Season int
|
||||
Build float64
|
||||
Everything bool
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,4 +105,5 @@ func LoadConfig() {
|
|||
}
|
||||
|
||||
Config.Fortnite.Season = parsedSeason
|
||||
Config.Fortnite.Everything = cfg.Section("fortnite").Key("everything").MustBool(false)
|
||||
}
|
|
@ -27,3 +27,5 @@ secret="secret"
|
|||
[fortnite]
|
||||
; used for account creation + lobby
|
||||
build=5.41
|
||||
; own every cosmetic in the game. this applies to all accounts
|
||||
everything=true
|
|
@ -17,8 +17,11 @@ var (
|
|||
"QueryProfile": PostQueryProfileAction,
|
||||
"ClientQuestLogin": PostQueryProfileAction,
|
||||
"MarkItemSeen": PostMarkItemSeenAction,
|
||||
"SetItemFavoriteStatusBatch": PostSetItemFavoriteStatusBatchAction,
|
||||
"EquipBattleRoyaleCustomization": PostEquipBattleRoyaleCustomizationAction,
|
||||
"SetBattleRoyaleBanner": PostSetBattleRoyaleBannerAction,
|
||||
"SetCosmeticLockerSlot": PostSetCosmeticLockerSlotAction,
|
||||
"SetCosmeticLockerBanner": PostSetCosmeticLockerBannerAction,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -178,3 +181,133 @@ func PostSetBattleRoyaleBannerAction(c *fiber.Ctx, person *p.Person, profile *p.
|
|||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func PostSetItemFavoriteStatusBatchAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
var body struct {
|
||||
ItemIds []string `json:"itemIds" binding:"required"`
|
||||
Favorite []bool `json:"itemFavStatus" binding:"required"`
|
||||
}
|
||||
|
||||
err := c.BodyParser(&body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid Body")
|
||||
}
|
||||
|
||||
for i, itemId := range body.ItemIds {
|
||||
item := profile.Items.GetItem(itemId)
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
item.Favorite = body.Favorite[i]
|
||||
go item.Save()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func PostSetCosmeticLockerSlotAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
var body struct {
|
||||
Category string `json:"category" binding:"required"` // item type e.g. Character
|
||||
ItemToSlot string `json:"itemToSlot" binding:"required"` // template id
|
||||
LockerItem string `json:"lockerItem" binding:"required"` // locker id
|
||||
SlotIndex int `json:"slotIndex" binding:"required"` // index of slot
|
||||
VariantUpdates []aid.JSON `json:"variantUpdates" binding:"required"` // variant updates
|
||||
}
|
||||
|
||||
err := c.BodyParser(&body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid Body")
|
||||
}
|
||||
|
||||
item := profile.Items.GetItemByTemplateID(body.ItemToSlot)
|
||||
if item == nil {
|
||||
if body.ItemToSlot != "" && !strings.Contains(strings.ToLower(body.ItemToSlot), "random") {
|
||||
return fmt.Errorf("item not found")
|
||||
}
|
||||
|
||||
item = &p.Item{
|
||||
ID: body.ItemToSlot,
|
||||
}
|
||||
}
|
||||
|
||||
currentLocker := profile.Loadouts.GetLoadout(body.LockerItem)
|
||||
if currentLocker == nil {
|
||||
return fmt.Errorf("current locker not found")
|
||||
}
|
||||
|
||||
switch body.Category {
|
||||
case "Character":
|
||||
currentLocker.CharacterID = item.ID
|
||||
case "Backpack":
|
||||
currentLocker.BackpackID = item.ID
|
||||
case "Pickaxe":
|
||||
currentLocker.PickaxeID = item.ID
|
||||
case "Glider":
|
||||
currentLocker.GliderID = item.ID
|
||||
case "ItemWrap":
|
||||
if body.SlotIndex == -1 {
|
||||
for i := range currentLocker.ItemWrapID {
|
||||
currentLocker.ItemWrapID[i] = item.ID
|
||||
}
|
||||
break
|
||||
}
|
||||
currentLocker.ItemWrapID[body.SlotIndex] = item.ID
|
||||
profile.CreateLoadoutChangedChange(currentLocker, "ItemWrapID")
|
||||
case "Dance":
|
||||
if body.SlotIndex == -1 {
|
||||
for i := range currentLocker.DanceID {
|
||||
currentLocker.DanceID[i] = item.ID
|
||||
}
|
||||
break
|
||||
}
|
||||
currentLocker.DanceID[body.SlotIndex] = item.ID
|
||||
profile.CreateLoadoutChangedChange(currentLocker, "DanceID")
|
||||
case "SkyDiveContrail":
|
||||
currentLocker.ContrailID = item.ID
|
||||
case "LoadingScreen":
|
||||
currentLocker.LoadingScreenID = item.ID
|
||||
case "MusicPack":
|
||||
currentLocker.MusicPackID = item.ID
|
||||
}
|
||||
|
||||
go currentLocker.Save()
|
||||
return nil
|
||||
}
|
||||
|
||||
func PostSetCosmeticLockerBannerAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
var body struct {
|
||||
LockerItem string `json:"lockerItem" binding:"required"` // locker id
|
||||
BannerColorTemplateName string `json:"bannerColorTemplateName" binding:"required"` // template id
|
||||
BannerIconTemplateName string `json:"bannerIconTemplateName" binding:"required"` // template id
|
||||
}
|
||||
|
||||
err := c.BodyParser(&body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid Body")
|
||||
}
|
||||
|
||||
color := person.CommonCoreProfile.Items.GetItemByTemplateID("HomebaseBannerColor:" + body.BannerColorTemplateName)
|
||||
if color == nil {
|
||||
return fmt.Errorf("color item not found")
|
||||
}
|
||||
|
||||
icon := profile.Items.GetItemByTemplateID("HomebaseBannerIcon:" + body.BannerIconTemplateName)
|
||||
if icon == nil {
|
||||
// return fmt.Errorf("icon item not found")
|
||||
icon = &p.Item{
|
||||
ID: body.BannerIconTemplateName,
|
||||
}
|
||||
}
|
||||
|
||||
currentLocker := profile.Loadouts.GetLoadout(body.LockerItem)
|
||||
if currentLocker == nil {
|
||||
return fmt.Errorf("current locker not found")
|
||||
}
|
||||
|
||||
currentLocker.BannerColorID = color.ID
|
||||
currentLocker.BannerID = icon.ID
|
||||
|
||||
go currentLocker.Save()
|
||||
return nil
|
||||
}
|
2
main.go
2
main.go
|
@ -47,7 +47,7 @@ func main() {
|
|||
r.Get("/content/api/pages/fortnite-game", handlers.GetContentPages)
|
||||
r.Get("/waitingroom/api/waitingroom", handlers.GetWaitingRoomStatus)
|
||||
r.Get("/region", handlers.GetRegion)
|
||||
r.Put("/profile/play_region", handlers.AnyNoContent)
|
||||
// r.Put("/profile/play_region", handlers.AnyNoContent)
|
||||
|
||||
r.Get("/snow/cache", func(c *fiber.Ctx) error {
|
||||
cache := person.AllFromCache()
|
||||
|
|
|
@ -67,8 +67,6 @@ func NewFortnitePerson(displayName string, key string) *Person {
|
|||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("season_update", 0)).Save()
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("season_num", aid.Config.Fortnite.Season)).Save()
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("permissions", []aid.JSON{})).Save()
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("last_applied_loadout", "")).Save()
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("active_loadout_index", 0)).Save()
|
||||
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("accountLevel", 1)).Save()
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("level", 1)).Save()
|
||||
|
@ -114,6 +112,7 @@ func NewFortnitePerson(displayName string, key string) *Person {
|
|||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("last_applied_loadout", loadout.ID)).Save()
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("active_loadout_index", 0)).Save()
|
||||
|
||||
if aid.Config.Fortnite.Everything {
|
||||
allItemsBytes := storage.Asset("cosmetics.json")
|
||||
var allItems []string
|
||||
json.Unmarshal(*allItemsBytes, &allItems)
|
||||
|
@ -121,6 +120,7 @@ func NewFortnitePerson(displayName string, key string) *Person {
|
|||
for _, item := range allItems {
|
||||
person.AthenaProfile.Items.AddItem(NewItem(item, 1)).Save()
|
||||
}
|
||||
}
|
||||
|
||||
person.Save()
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
type Loadout struct {
|
||||
ID string
|
||||
PersonID string
|
||||
ProfileID string
|
||||
TemplateID string
|
||||
LockerName string
|
||||
|
@ -65,7 +66,7 @@ func NewLoadout(name string, athena *Profile) *Loadout {
|
|||
|
||||
return &Loadout{
|
||||
ID: uuid.New().String(),
|
||||
ProfileID: athena.ID,
|
||||
PersonID: athena.ID,
|
||||
TemplateID: "CosmeticLocker:CosmeticLocker_Athena",
|
||||
LockerName: name,
|
||||
CharacterID: aid.JSONParse(character.ValueJSON).(string),
|
||||
|
@ -103,12 +104,26 @@ func FromDatabaseLoadout(loadout *storage.DB_Loadout) *Loadout {
|
|||
}
|
||||
|
||||
func (l *Loadout) GenerateFortniteLoadoutEntry() aid.JSON {
|
||||
bannerItem := Find(l.PersonID).AthenaProfile.Items.GetItem(l.BannerID)
|
||||
if bannerItem == nil {
|
||||
bannerItem = &Item{
|
||||
TemplateID: "HomebaseBannerIcon:StandardBanner1",
|
||||
}
|
||||
}
|
||||
|
||||
bannerColorItem := Find(l.PersonID).AthenaProfile.Items.GetItem(l.BannerColorID)
|
||||
if bannerColorItem == nil {
|
||||
bannerColorItem = &Item{
|
||||
TemplateID: "HomebaseBannerColor:DefaultColor1",
|
||||
}
|
||||
}
|
||||
|
||||
json := aid.JSON{
|
||||
"templateId": l.TemplateID,
|
||||
"attributes": aid.JSON{
|
||||
"locker_name": l.LockerName,
|
||||
"banner_icon_template": l.BannerID,
|
||||
"banner_color_template": l.BannerColorID,
|
||||
"banner_icon_template": bannerItem.TemplateID,
|
||||
"banner_color_template": bannerColorItem.TemplateID,
|
||||
"locker_slots_data": l.GenerateFortniteLockerSlotsData(),
|
||||
"item_seen": true,
|
||||
},
|
||||
|
@ -118,13 +133,27 @@ func (l *Loadout) GenerateFortniteLoadoutEntry() aid.JSON {
|
|||
}
|
||||
|
||||
func (l *Loadout) GetAttribute(attribute string) interface{} {
|
||||
bannerItem := Find(l.PersonID).AthenaProfile.Items.GetItem(l.BannerID)
|
||||
if bannerItem == nil {
|
||||
bannerItem = &Item{
|
||||
TemplateID: "HomebaseBannerIcon:StandardBanner1",
|
||||
}
|
||||
}
|
||||
|
||||
bannerColorItem := Find(l.PersonID).AthenaProfile.Items.GetItem(l.BannerColorID)
|
||||
if bannerColorItem == nil {
|
||||
bannerColorItem = &Item{
|
||||
TemplateID: "HomebaseBannerColor:DefaultColor5",
|
||||
}
|
||||
}
|
||||
|
||||
switch attribute {
|
||||
case "locker_name":
|
||||
return l.LockerName
|
||||
case "banner_icon_template":
|
||||
return l.BannerID
|
||||
return bannerItem.TemplateID
|
||||
case "banner_color_template":
|
||||
return l.BannerColorID
|
||||
return bannerColorItem.TemplateID
|
||||
case "locker_slots_data":
|
||||
return l.GenerateFortniteLockerSlotsData()
|
||||
}
|
||||
|
@ -154,7 +183,7 @@ func (l *Loadout) GetItemSlotData(itemId string) aid.JSON {
|
|||
"activeVariants": []aid.JSON{},
|
||||
}
|
||||
|
||||
person := Find(l.ProfileID)
|
||||
person := Find(l.PersonID)
|
||||
if person == nil {
|
||||
return json
|
||||
}
|
||||
|
@ -179,40 +208,38 @@ func (l *Loadout) GetItemSlotData(itemId string) aid.JSON {
|
|||
|
||||
func (l *Loadout) GetItemsSlotData(itemIds []string) aid.JSON {
|
||||
json := aid.JSON{
|
||||
"items": []string{},
|
||||
"activeVariants": []aid.JSON{},
|
||||
"items": make([]string, len(itemIds)),
|
||||
"activeVariants": make([]aid.JSON, len(itemIds)),
|
||||
}
|
||||
|
||||
person := Find(l.ProfileID)
|
||||
person := Find(l.PersonID)
|
||||
if person == nil {
|
||||
return json
|
||||
}
|
||||
|
||||
for _, itemId := range itemIds {
|
||||
for idx, itemId := range itemIds {
|
||||
item := person.AthenaProfile.Items.GetItem(itemId)
|
||||
if item == nil {
|
||||
item = &Item{
|
||||
ProfileID: l.ProfileID,
|
||||
TemplateID: "",
|
||||
Variants: []*VariantChannel{},
|
||||
}
|
||||
}
|
||||
|
||||
items := json["items"].([]string)
|
||||
items = append(items, item.TemplateID)
|
||||
items[idx] = item.TemplateID
|
||||
|
||||
|
||||
activeVariants := json["activeVariants"].([]aid.JSON)
|
||||
activeVariants = append(activeVariants, aid.JSON{
|
||||
"variants": item.GenerateFortniteItemVariantChannels(),
|
||||
})
|
||||
activeVariants[idx] = aid.JSON{
|
||||
"variants": []aid.JSON{},
|
||||
}
|
||||
|
||||
json["items"] = items
|
||||
json["activeVariants"] = activeVariants
|
||||
}
|
||||
|
||||
return aid.JSON{
|
||||
"items": itemIds,
|
||||
"activeVariants": []aid.JSON{},
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
func (l *Loadout) Delete() {
|
||||
|
|
|
@ -183,6 +183,8 @@ func (p *Profile) Diff(b *ProfileSnapshot) []diff.Change {
|
|||
return nil
|
||||
}
|
||||
|
||||
aid.PrintJSON(changes)
|
||||
|
||||
for _, change := range changes {
|
||||
switch change.Path[0] {
|
||||
case "Items":
|
||||
|
@ -333,20 +335,13 @@ func (p *Profile) CreateItemAttributeChangedChange(item *Item, attribute string)
|
|||
}
|
||||
|
||||
p.Changes = append(p.Changes, ItemAttributeChanged{
|
||||
ChangeType: "itemAttributeChanged",
|
||||
ChangeType: "itemAttrChanged",
|
||||
ItemId: item.ID,
|
||||
AttributeName: lookup[attribute],
|
||||
AttributeValue: item.GetAttribute(attribute),
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Profile) CreateFullProfileUpdateChange() {
|
||||
p.Changes = []interface{}{FullProfileUpdate{
|
||||
ChangeType: "fullProfileUpdate",
|
||||
Profile: p.GenerateFortniteProfileEntry(),
|
||||
}}
|
||||
}
|
||||
|
||||
func (p *Profile) CreateLoadoutAddedChange(loadout *Loadout) {
|
||||
if loadout == nil {
|
||||
fmt.Println("error getting item from profile", loadout.ID)
|
||||
|
@ -389,13 +384,20 @@ func (p *Profile) CreateLoadoutChangedChange(loadout *Loadout, attribute string)
|
|||
}
|
||||
|
||||
p.Changes = append(p.Changes, ItemAttributeChanged{
|
||||
ChangeType: "itemAttributeChanged",
|
||||
ChangeType: "itemAttrChanged",
|
||||
ItemId: loadout.ID,
|
||||
AttributeName: lookup[attribute],
|
||||
AttributeValue: loadout.GetAttribute(lookup[attribute]),
|
||||
})
|
||||
}
|
||||
|
||||
func (p *Profile) CreateFullProfileUpdateChange() {
|
||||
p.Changes = []interface{}{FullProfileUpdate{
|
||||
ChangeType: "fullProfileUpdate",
|
||||
Profile: p.GenerateFortniteProfileEntry(),
|
||||
}}
|
||||
}
|
||||
|
||||
func (p *Profile) ClearProfileChanges() {
|
||||
p.Changes = []interface{}{}
|
||||
}
|
|
@ -240,17 +240,19 @@ func (m *AttributeMutex) Count() int {
|
|||
|
||||
type LoadoutMutex struct {
|
||||
sync.Map
|
||||
ProfileType string
|
||||
PersonID string
|
||||
ProfileID string
|
||||
}
|
||||
|
||||
func NewLoadoutMutex(profile *storage.DB_Profile) *LoadoutMutex {
|
||||
return &LoadoutMutex{
|
||||
PersonID: profile.PersonID,
|
||||
ProfileID: profile.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LoadoutMutex) AddLoadout(loadout *Loadout) *Loadout {
|
||||
loadout.PersonID = m.PersonID
|
||||
loadout.ProfileID = m.ProfileID
|
||||
m.Store(loadout.ID, loadout)
|
||||
// storage.Repo.SaveLoadout(loadout.ToDatabase(m.ProfileID))
|
||||
|
|
|
@ -12,8 +12,13 @@ type PostgresStorage struct {
|
|||
}
|
||||
|
||||
func NewPostgresStorage() *PostgresStorage {
|
||||
l := logger.Default.LogMode(logger.Silent)
|
||||
if aid.Config.Output.Level == "time" {
|
||||
l = logger.Default.LogMode(logger.Info)
|
||||
}
|
||||
|
||||
db, err := gorm.Open(postgres.Open(aid.Config.Database.URI), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
Logger: l,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -34,10 +39,10 @@ func (s *PostgresStorage) MigrateAll() {
|
|||
s.Migrate(&DB_Item{}, "Items")
|
||||
s.Migrate(&DB_Gift{}, "Gifts")
|
||||
s.Migrate(&DB_Quest{}, "Quests")
|
||||
s.Migrate(&DB_Loadout{}, "Loadouts")
|
||||
s.Migrate(&DB_Loot{}, "Loot")
|
||||
s.Migrate(&DB_VariantChannel{}, "Variants")
|
||||
s.Migrate(&DB_PAttribute{}, "Attributes")
|
||||
s.Migrate(&DB_Loadout{}, "Loadouts")
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DropTables() {
|
||||
|
@ -48,13 +53,13 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
|||
var dbPerson DB_Person
|
||||
s.Postgres.
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
Preload("Profiles.Gifts").
|
||||
Preload("Profiles.Quests").
|
||||
Preload("Profiles.Loadouts").
|
||||
Where("id = ?", personId).
|
||||
Find(&dbPerson)
|
||||
|
||||
|
@ -68,14 +73,14 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
|||
func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
|
||||
var dbPerson DB_Person
|
||||
s.Postgres.
|
||||
// Preload("Profiles").
|
||||
// Preload("Profiles.Items.Variants").
|
||||
// Preload("Profiles.Gifts.Loot").
|
||||
// Preload("Profiles.Attributes").
|
||||
// Preload("Profiles.Items").
|
||||
// Preload("Profiles.Gifts").
|
||||
// Preload("Profiles.Quests").
|
||||
// Preload("Profiles.Loadouts").
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
Preload("Profiles.Gifts").
|
||||
Preload("Profiles.Quests").
|
||||
Where("display_name = ?", displayName).
|
||||
Find(&dbPerson)
|
||||
|
||||
|
@ -91,13 +96,13 @@ func (s *PostgresStorage) GetAllPersons() []*DB_Person {
|
|||
|
||||
s.Postgres.
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
Preload("Profiles.Gifts").
|
||||
Preload("Profiles.Quests").
|
||||
Preload("Profiles.Loadouts").
|
||||
Find(&dbPersons)
|
||||
|
||||
return dbPersons
|
||||
|
|
Loading…
Reference in New Issue
Block a user