Improve Display Asset accuracy

This commit is contained in:
eccentric 2023-12-10 23:54:31 +00:00
parent d84540b37b
commit 0c9b8cb6a0
8 changed files with 364 additions and 3462 deletions

View File

@ -1,11 +1,11 @@
root = "." root = "."
testdata_dir = "testdata" testdata_dir = "testdata"
tmp_dir = "." tmp_dir = "./tmp"
[build] [build]
args_bin = [] args_bin = []
bin = "main.exe" bin = "./tmp/main.exe"
cmd = "clear && go build -o ./main.exe ." cmd = "clear && go build -o ./tmp/main.exe ."
delay = 1000 delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"] exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = [] exclude_file = []
@ -40,5 +40,5 @@ tmp_dir = "."
clean_on_exit = false clean_on_exit = false
[screen] [screen]
clear_on_rebuild = true clear_on_rebuild = false
keep_scroll = true keep_scroll = true

View File

@ -77,6 +77,7 @@ type FAPI_Cosmetic struct {
ShowcaseVideo string `json:"showcaseVideo"` ShowcaseVideo string `json:"showcaseVideo"`
DynamicPakID string `json:"dynamicPakId"` DynamicPakID string `json:"dynamicPakId"`
DisplayAssetPath string `json:"displayAssetPath"` DisplayAssetPath string `json:"displayAssetPath"`
DisplayAssetPath2 string
ItemPreviewHeroPath string `json:"itemPreviewHeroPath"` ItemPreviewHeroPath string `json:"itemPreviewHeroPath"`
Backpack string `json:"backpack"` Backpack string `json:"backpack"`
Path string `json:"path"` Path string `json:"path"`
@ -170,7 +171,6 @@ var (
Items: make(map[string]FAPI_Cosmetic), Items: make(map[string]FAPI_Cosmetic),
Sets: make(map[string]Set), Sets: make(map[string]Set),
} }
KnownDisplayAssets = make(map[string]bool)
) )
func NewFortniteAPI() *FortniteAPI { func NewFortniteAPI() *FortniteAPI {
@ -276,6 +276,7 @@ func PreloadCosmetics(max int) error {
} }
character.Backpack = id character.Backpack = id
Cosmetics.Items[characterId] = character Cosmetics.Items[characterId] = character
if _, ok := Cosmetics.Sets[character.Set.BackendValue]; !ok { if _, ok := Cosmetics.Sets[character.Set.BackendValue]; !ok {
Cosmetics.Sets[character.Set.BackendValue] = Set{ Cosmetics.Sets[character.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic), Items: make(map[string]FAPI_Cosmetic),
@ -283,25 +284,320 @@ func PreloadCosmetics(max int) error {
BackendName: character.Set.BackendValue, BackendName: character.Set.BackendValue,
} }
} }
Cosmetics.Sets[character.Set.BackendValue].Items[characterId] = character Cosmetics.Sets[character.Set.BackendValue].Items[characterId] = character
found = append(found, id) found = append(found, id)
} }
aid.Print("Preloaded", len(found), "backpacks with characters", "(", float64(len(found))/float64(len(characters))*100, "% )") aid.Print("Preloaded", len(found), "backpacks with characters", "(", float64(len(found))/float64(len(characters))*100, "% ) coverage")
DAv2 := *storage.Asset("assets.json") assets := storage.HttpAsset("QKnwROGzQjYm1W9xu9uL3VrbSA0tnVj6NJJtEChUdAb3DF8uN.json")
if DAv2 == nil { if assets == nil {
aid.Print("Couldn't find DAv2.json") panic("Failed to load assets")
} }
var DAv2Data map[string]bool var assetData []string
err = json.Unmarshal(DAv2, &DAv2Data) err = json.Unmarshal(*assets, &assetData)
if err != nil { if err != nil {
return err return err
} }
KnownDisplayAssets = DAv2Data for _, asset := range assetData {
asset := strings.ReplaceAll(asset, "DAv2_", "")
parts := strings.Split(asset, "_")
switch {
case parts[0] == "CID":
addCharacterAsset(parts)
case parts[0] == "Character":
addCharacterAsset(parts)
case parts[0] == "BID":
addBackpackAsset(parts)
case parts[0] == "EID":
addEmoteAsset(parts)
case parts[0] == "Emote":
addEmoteAsset(parts)
case parts[0] == "Pickaxe":
addPickaxeAsset(parts)
case parts[0] == "Wrap":
addWrapAsset(parts)
case parts[0] == "Glider":
addGliderAsset(parts)
case parts[0] == "MusicPack":
addMusicAsset(parts)
}
}
withDisplayAssets := 0
for _, item := range Cosmetics.Items {
if item.DisplayAssetPath2 == "" {
continue
}
withDisplayAssets++
}
aid.Print("Preloaded", len(Cosmetics.Items), "cosmetics with", withDisplayAssets, "display assets", "(", float64(withDisplayAssets)/float64(len(assetData))*100, "% ) coverage" )
return nil return nil
}
func addCharacterAsset(parts []string) {
character := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "outfit" {
continue
}
if parts[0] == "CID" {
cid := ""
if parts[1] != "A" {
cid = parts[0] + "_" + parts[1]
}
if parts[1] == "A" {
cid = parts[0] + "_A_" + parts[2]
}
if strings.Contains(item.ID, cid) {
character = item
break
}
}
if parts[0] == "Character" {
if strings.Contains(item.ID, parts[1]) {
character = item
break
}
}
}
if character.ID == "" {
return
}
character.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[character.ID] = 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[character.ID] = character
}
func addBackpackAsset(parts []string) {
backpack := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "backpack" {
continue
}
bid := ""
if parts[1] != "A" {
bid = parts[0] + "_" + parts[1]
}
if parts[1] == "A" {
bid = parts[0] + "_A_" + parts[2]
}
if strings.Contains(item.ID, bid) {
backpack = item
break
}
}
if backpack.ID == "" {
return
}
backpack.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[backpack.ID] = backpack
if _, ok := Cosmetics.Sets[backpack.Set.BackendValue]; !ok {
Cosmetics.Sets[backpack.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: backpack.Set.Value,
BackendName: backpack.Set.BackendValue,
}
}
Cosmetics.Sets[backpack.Set.BackendValue].Items[backpack.ID] = backpack
}
func addEmoteAsset(parts []string) {
emote := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "emote" {
continue
}
if strings.Contains(item.ID, parts[1]) {
emote = item
break
}
}
if emote.ID == "" {
return
}
emote.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[emote.ID] = emote
if _, ok := Cosmetics.Sets[emote.Set.BackendValue]; !ok {
Cosmetics.Sets[emote.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: emote.Set.Value,
BackendName: emote.Set.BackendValue,
}
}
Cosmetics.Sets[emote.Set.BackendValue].Items[emote.ID] = emote
}
func addPickaxeAsset(parts []string) {
pickaxe := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "pickaxe" {
continue
}
pickaxeId := ""
if parts[1] != "ID" {
pickaxeId = parts[0] + "_" + parts[1]
}
if parts[1] == "ID" {
pickaxeId = parts[0] + "_ID_" + parts[2]
}
if strings.Contains(item.ID, pickaxeId) {
pickaxe = item
break
}
}
if pickaxe.ID == "" {
return
}
pickaxe.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[pickaxe.ID] = pickaxe
if _, ok := Cosmetics.Sets[pickaxe.Set.BackendValue]; !ok {
Cosmetics.Sets[pickaxe.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: pickaxe.Set.Value,
BackendName: pickaxe.Set.BackendValue,
}
}
Cosmetics.Sets[pickaxe.Set.BackendValue].Items[pickaxe.ID] = pickaxe
}
func addGliderAsset(parts []string) {
glider := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "glider" {
continue
}
gliderId := ""
if parts[1] != "ID" {
gliderId = parts[0] + "_" + parts[1]
}
if parts[1] == "ID" {
gliderId = parts[0] + "_ID_" + parts[2]
}
if strings.Contains(item.ID, gliderId) {
glider = item
break
}
}
if glider.ID == "" {
return
}
glider.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[glider.ID] = glider
if _, ok := Cosmetics.Sets[glider.Set.BackendValue]; !ok {
Cosmetics.Sets[glider.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: glider.Set.Value,
BackendName: glider.Set.BackendValue,
}
}
Cosmetics.Sets[glider.Set.BackendValue].Items[glider.ID] = glider
}
func addWrapAsset(parts []string) {
wrap := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "wrap" {
continue
}
if strings.Contains(item.ID, parts[1]) {
wrap = item
break
}
}
if wrap.ID == "" {
return
}
wrap.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[wrap.ID] = wrap
if _, ok := Cosmetics.Sets[wrap.Set.BackendValue]; !ok {
Cosmetics.Sets[wrap.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: wrap.Set.Value,
BackendName: wrap.Set.BackendValue,
}
}
Cosmetics.Sets[wrap.Set.BackendValue].Items[wrap.ID] = wrap
}
func addMusicAsset(parts []string) {
music := FAPI_Cosmetic{}
for _, item := range Cosmetics.Items {
if item.Type.Value != "music" {
continue
}
if strings.Contains(item.ID, parts[1]) {
music = item
break
}
}
if music.ID == "" {
return
}
music.DisplayAssetPath2 = "DAv2_" + strings.Join(parts, "_")
Cosmetics.Items[music.ID] = music
if _, ok := Cosmetics.Sets[music.Set.BackendValue]; !ok {
Cosmetics.Sets[music.Set.BackendValue] = Set{
Items: make(map[string]FAPI_Cosmetic),
Name: music.Set.Value,
BackendName: music.Set.BackendValue,
}
}
Cosmetics.Sets[music.Set.BackendValue].Items[music.ID] = music
} }

View File

@ -181,15 +181,8 @@ func (e *Entry) SetDisplayAsset(asset string) *Entry {
return e return e
} }
func (e *Entry) IsNewDisplayAssetValid(asset string) bool {
newDisplayAsset := "DAv2_" + strings.ReplaceAll(asset, "Athena_Commando_", "")
_, exists := KnownDisplayAssets[newDisplayAsset]
return exists
}
func (e *Entry) SetNewDisplayAsset(asset string) *Entry { func (e *Entry) SetNewDisplayAsset(asset string) *Entry {
newDisplayAsset := "DAv2_" + strings.ReplaceAll(asset, "Athena_Commando_", "") e.NewDisplayAssetPath = "/Game/Catalog/NewDisplayAssets/" + asset + "." + asset
e.NewDisplayAssetPath = "/Game/Catalog/NewDisplayAssets/" + newDisplayAsset + "." + newDisplayAsset
return e return e
} }
@ -322,12 +315,12 @@ func GenerateRandomStorefront() {
entry := NewCatalogEntry("athena") entry := NewCatalogEntry("athena")
entry.SetSection("Daily") entry.SetSection("Daily")
if !entry.IsNewDisplayAssetValid(item.ID) { if item.DisplayAssetPath2 == "" {
i-- i--
continue continue
} }
entry.SetNewDisplayAsset(item.DisplayAssetPath2)
entry.SetNewDisplayAsset(item.ID)
if item.DisplayAssetPath != "" { if item.DisplayAssetPath != "" {
entry.SetDisplayAssetPath(item.DisplayAssetPath) entry.SetDisplayAssetPath(item.DisplayAssetPath)
} }
@ -352,12 +345,12 @@ func GenerateRandomStorefront() {
entry := NewCatalogEntry("athena") entry := NewCatalogEntry("athena")
entry.SetSection("Daily") entry.SetSection("Daily")
if !entry.IsNewDisplayAssetValid(item.ID) { if item.DisplayAssetPath2 == "" {
i-- i--
continue continue
} }
entry.SetNewDisplayAsset(item.DisplayAssetPath2)
entry.SetNewDisplayAsset(item.ID)
if item.DisplayAssetPath != "" { if item.DisplayAssetPath != "" {
entry.SetDisplayAssetPath(item.DisplayAssetPath) entry.SetDisplayAssetPath(item.DisplayAssetPath)
} }
@ -393,9 +386,10 @@ func GenerateRandomStorefront() {
entry.SetSection("Featured") entry.SetSection("Featured")
entry.SetPanel(set.BackendName) entry.SetPanel(set.BackendName)
if !entry.IsNewDisplayAssetValid(item.ID) { if item.DisplayAssetPath2 == "" {
continue continue
} }
entry.SetNewDisplayAsset(item.DisplayAssetPath2)
if item.Type.BackendValue == "AthenaCharacter" { if item.Type.BackendValue == "AthenaCharacter" {
entry.SetTileSize("Normal") entry.SetTileSize("Normal")
@ -410,7 +404,6 @@ func GenerateRandomStorefront() {
itemsAdded += 1 itemsAdded += 1
} }
entry.SetNewDisplayAsset(item.ID)
if item.DisplayAssetPath != "" { if item.DisplayAssetPath != "" {
entry.SetDisplayAssetPath(item.DisplayAssetPath) entry.SetDisplayAssetPath(item.DisplayAssetPath)
} }

View File

@ -202,8 +202,10 @@ func (p *Person) ToDatabase() *storage.DB_Person {
DisplayName: p.DisplayName, DisplayName: p.DisplayName,
Profiles: []storage.DB_Profile{}, Profiles: []storage.DB_Profile{},
AccessKey: p.AccessKey, AccessKey: p.AccessKey,
Discord: *p.Discord, }
DiscordID: p.Discord.ID,
if p.Discord != nil {
dbPerson.Discord = *p.Discord
} }
profilesToConvert := map[string]*Profile{ profilesToConvert := map[string]*Profile{

View File

@ -2,6 +2,8 @@ package storage
import ( import (
"embed" "embed"
"io"
"net/http"
"strings" "strings"
) )
@ -16,5 +18,21 @@ func Asset(file string) (*[]byte) {
return nil return nil
} }
return &data
}
func HttpAsset(file string) (*[]byte) {
client := http.Client{}
resp, err := client.Get("https://raw.githubusercontent.com/ectrc/ectrc/main/" + file)
if err != nil {
return nil
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil
}
return &data return &data
} }

File diff suppressed because it is too large Load Diff

View File

@ -43,8 +43,9 @@ func (s *PostgresStorage) MigrateAll() {
s.Migrate(&DB_Loot{}, "Loot") s.Migrate(&DB_Loot{}, "Loot")
s.Migrate(&DB_VariantChannel{}, "Variants") s.Migrate(&DB_VariantChannel{}, "Variants")
s.Migrate(&DB_PAttribute{}, "Attributes") s.Migrate(&DB_PAttribute{}, "Attributes")
s.Migrate(&DB_TemporaryCode{}, "Exchange") s.Migrate(&DB_TemporaryCode{}, "Exchanges")
s.Migrate(&DB_DiscordPerson{}, "Discord") s.Migrate(&DB_DiscordPerson{}, "Discords")
s.Migrate(&DB_SeasonStat{}, "Stats")
} }
func (s *PostgresStorage) DropTables() { func (s *PostgresStorage) DropTables() {
@ -63,7 +64,7 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
Preload("Profiles.Items"). Preload("Profiles.Items").
Preload("Profiles.Gifts"). Preload("Profiles.Gifts").
Preload("Profiles.Quests"). Preload("Profiles.Quests").
Preload("Discord"). Preload("Discords").
Where("id = ?", personId). Where("id = ?", personId).
Find(&dbPerson) Find(&dbPerson)
@ -86,7 +87,7 @@ func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
Preload("Profiles.Items"). Preload("Profiles.Items").
Preload("Profiles.Gifts"). Preload("Profiles.Gifts").
Preload("Profiles.Quests"). Preload("Profiles.Quests").
Preload("Discord"). Preload("Discords").
Where("display_name = ?", displayName). Where("display_name = ?", displayName).
Find(&dbPerson) Find(&dbPerson)
@ -121,7 +122,7 @@ func (s *PostgresStorage) GetAllPersons() []*DB_Person {
Preload("Profiles.Items"). Preload("Profiles.Items").
Preload("Profiles.Gifts"). Preload("Profiles.Gifts").
Preload("Profiles.Quests"). Preload("Profiles.Quests").
Preload("Discord"). Preload("Discords").
Find(&dbPersons) Find(&dbPersons)
return dbPersons return dbPersons

View File

@ -11,8 +11,8 @@ type DB_Person struct {
DisplayName string DisplayName string
AccessKey string AccessKey string
Profiles []DB_Profile `gorm:"foreignkey:PersonID"` Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
Stats []DB_SeasonStat `gorm:"foreignkey:PersonID"`
Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"` Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"`
DiscordID string
} }
func (DB_Person) TableName() string { func (DB_Person) TableName() string {
@ -145,7 +145,7 @@ type DB_TemporaryCode struct {
} }
func (DB_TemporaryCode) TableName() string { func (DB_TemporaryCode) TableName() string {
return "Exchange" return "Exchanges"
} }
type DB_DiscordPerson struct { type DB_DiscordPerson struct {
@ -157,5 +157,21 @@ type DB_DiscordPerson struct {
} }
func (DB_DiscordPerson) TableName() string { func (DB_DiscordPerson) TableName() string {
return "Discord" return "Discords"
}
type DB_SeasonStat struct {
ID string `gorm:"primary_key"`
PersonID string
Build string
Level int
XP int
Tier int
Stars int
LevelClainmed int
TierClaimed int
}
func (DB_SeasonStat) TableName() string {
return "Stats"
} }