2023-10-31 22:40:14 +00:00
|
|
|
package person
|
|
|
|
|
|
|
|
import (
|
2023-11-01 00:05:17 +00:00
|
|
|
"fmt"
|
2023-10-31 22:40:14 +00:00
|
|
|
|
2023-11-03 23:48:50 +00:00
|
|
|
"github.com/ectrc/snow/aid"
|
2023-10-31 22:40:14 +00:00
|
|
|
"github.com/ectrc/snow/storage"
|
|
|
|
"github.com/google/uuid"
|
2023-10-31 23:19:52 +00:00
|
|
|
"github.com/r3labs/diff/v3"
|
2023-10-31 22:40:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Profile struct {
|
|
|
|
ID string
|
2023-11-03 23:48:50 +00:00
|
|
|
PersonID string
|
2023-10-31 22:40:14 +00:00
|
|
|
Items *ItemMutex
|
|
|
|
Gifts *GiftMutex
|
|
|
|
Quests *QuestMutex
|
2023-11-01 00:05:17 +00:00
|
|
|
Attributes *AttributeMutex
|
2023-10-31 23:19:52 +00:00
|
|
|
Type string
|
2023-11-02 17:50:52 +00:00
|
|
|
Revision int
|
2023-11-01 01:24:42 +00:00
|
|
|
Changes []interface{}
|
2023-10-31 22:40:14 +00:00
|
|
|
}
|
|
|
|
|
2023-10-31 23:19:52 +00:00
|
|
|
func NewProfile(profile string) *Profile {
|
2023-10-31 22:40:14 +00:00
|
|
|
return &Profile{
|
|
|
|
ID: uuid.New().String(),
|
2023-11-03 23:48:50 +00:00
|
|
|
PersonID: "",
|
2023-10-31 23:19:52 +00:00
|
|
|
Items: NewItemMutex(profile),
|
2023-10-31 22:40:14 +00:00
|
|
|
Gifts: NewGiftMutex(),
|
|
|
|
Quests: NewQuestMutex(),
|
2023-11-01 00:05:17 +00:00
|
|
|
Attributes: NewAttributeMutex(),
|
2023-11-01 01:24:42 +00:00
|
|
|
Type: profile,
|
|
|
|
Revision: 0,
|
2023-11-02 17:50:52 +00:00
|
|
|
Changes: []interface{}{},
|
2023-10-31 22:40:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
2023-10-31 23:19:52 +00:00
|
|
|
items := NewItemMutex(profile.Type)
|
2023-10-31 22:40:14 +00:00
|
|
|
gifts := NewGiftMutex()
|
|
|
|
quests := NewQuestMutex()
|
2023-11-01 00:05:17 +00:00
|
|
|
attributes := NewAttributeMutex()
|
2023-10-31 22:40:14 +00:00
|
|
|
|
|
|
|
for _, item := range profile.Items {
|
|
|
|
items.AddItem(FromDatabaseItem(&item, &profile.Type))
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, gift := range profile.Gifts {
|
|
|
|
gifts.AddGift(FromDatabaseGift(&gift))
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, quest := range profile.Quests {
|
|
|
|
quests.AddQuest(FromDatabaseQuest(&quest, &profile.Type))
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, attribute := range profile.Attributes {
|
2023-11-01 00:05:17 +00:00
|
|
|
parsed := FromDatabaseAttribute(&attribute)
|
|
|
|
if parsed == nil {
|
|
|
|
fmt.Printf("error getting attribute from database")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
attributes.AddAttribute(parsed)
|
2023-10-31 22:40:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &Profile{
|
|
|
|
ID: profile.ID,
|
2023-11-03 23:48:50 +00:00
|
|
|
PersonID: profile.PersonID,
|
2023-10-31 22:40:14 +00:00
|
|
|
Items: items,
|
|
|
|
Gifts: gifts,
|
|
|
|
Quests: quests,
|
|
|
|
Attributes: attributes,
|
2023-10-31 23:19:52 +00:00
|
|
|
Type: profile.Type,
|
2023-11-01 01:24:42 +00:00
|
|
|
Revision: profile.Revision,
|
2023-10-31 22:40:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-03 23:48:50 +00:00
|
|
|
func (p *Profile) GenerateFortniteProfileEntry() aid.JSON {
|
|
|
|
items := aid.JSON{}
|
|
|
|
attributes := aid.JSON{}
|
|
|
|
|
|
|
|
p.Items.RangeItems(func(id string, item *Item) bool {
|
|
|
|
items[id] = item.GenerateFortniteItemEntry()
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
p.Quests.RangeQuests(func(id string, quest *Quest) bool {
|
|
|
|
items[id] = quest.GenerateFortniteQuestEntry()
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
p.Gifts.RangeGifts(func(id string, gift *Gift) bool {
|
|
|
|
items[id] = gift.GenerateFortniteGiftEntry()
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
p.Attributes.RangeAttributes(func(id string, attribute *Attribute) bool {
|
|
|
|
attributes[attribute.Key] = attribute.Value
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
return aid.JSON{
|
|
|
|
"profileId": p.Type,
|
|
|
|
"accountId": p.PersonID,
|
|
|
|
"rvn": p.Revision,
|
|
|
|
"commandRevision": p.Revision,
|
|
|
|
"wipeNumber": 0,
|
|
|
|
"version": "",
|
|
|
|
"items": items,
|
|
|
|
"stats": aid.JSON{
|
|
|
|
"attributes": attributes,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-31 22:40:14 +00:00
|
|
|
func (p *Profile) Save() {
|
|
|
|
//storage.Repo.SaveProfile(p.ToDatabase())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Profile) Snapshot() *ProfileSnapshot {
|
|
|
|
items := map[string]ItemSnapshot{}
|
|
|
|
gifts := map[string]GiftSnapshot{}
|
|
|
|
quests := map[string]Quest{}
|
2023-11-01 00:05:17 +00:00
|
|
|
attributes := map[string]Attribute{}
|
2023-10-31 22:40:14 +00:00
|
|
|
|
|
|
|
p.Items.RangeItems(func(id string, item *Item) bool {
|
|
|
|
items[id] = item.Snapshot()
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
p.Gifts.RangeGifts(func(id string, gift *Gift) bool {
|
|
|
|
gifts[id] = gift.Snapshot()
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
p.Quests.RangeQuests(func(id string, quest *Quest) bool {
|
|
|
|
quests[id] = *quest
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
2023-11-01 01:24:42 +00:00
|
|
|
p.Attributes.RangeAttributes(func(key string, attribute *Attribute) bool {
|
|
|
|
attributes[key] = *attribute
|
2023-10-31 22:40:14 +00:00
|
|
|
return true
|
|
|
|
})
|
|
|
|
|
|
|
|
return &ProfileSnapshot{
|
|
|
|
ID: p.ID,
|
|
|
|
Items: items,
|
|
|
|
Gifts: gifts,
|
|
|
|
Quests: quests,
|
2023-11-01 00:05:17 +00:00
|
|
|
Attributes: attributes,
|
2023-11-01 01:24:42 +00:00
|
|
|
Type: p.Type,
|
|
|
|
Revision: p.Revision,
|
2023-10-31 22:40:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-31 23:19:52 +00:00
|
|
|
func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
2023-11-01 01:24:42 +00:00
|
|
|
changes, err := diff.Diff(snapshot, p.Snapshot())
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("error diffing profile: %v\n", err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, change := range changes {
|
|
|
|
switch change.Path[0] {
|
|
|
|
case "Items":
|
|
|
|
if change.Type == "create" && change.Path[2] == "ID" {
|
|
|
|
p.CreateItemAddedChange(p.Items.GetItem(change.Path[1]))
|
|
|
|
}
|
|
|
|
|
|
|
|
if change.Type == "delete" && change.Path[2] == "ID" {
|
|
|
|
p.CreateItemRemovedChange(change.Path[1])
|
|
|
|
}
|
|
|
|
|
|
|
|
if change.Type == "update" && change.Path[2] == "Quantity" {
|
|
|
|
p.CreateItemQuantityChangedChange(p.Items.GetItem(change.Path[1]))
|
|
|
|
}
|
|
|
|
|
|
|
|
if change.Type == "update" && change.Path[2] != "Quantity" {
|
|
|
|
p.CreateItemAttributeChangedChange(p.Items.GetItem(change.Path[1]), change.Path[2])
|
|
|
|
}
|
2023-11-02 17:50:52 +00:00
|
|
|
case "Quests":
|
|
|
|
if change.Type == "create" && change.Path[2] == "ID" {
|
|
|
|
p.CreateQuestAddedChange(p.Quests.GetQuest(change.Path[1]))
|
|
|
|
}
|
|
|
|
|
|
|
|
if change.Type == "delete" && change.Path[2] == "ID" {
|
|
|
|
p.CreateItemRemovedChange(change.Path[1])
|
|
|
|
}
|
|
|
|
case "Gifts":
|
|
|
|
if change.Type == "create" && change.Path[2] == "ID" {
|
|
|
|
p.CreateGiftAddedChange(p.Gifts.GetGift(change.Path[1]))
|
|
|
|
}
|
|
|
|
|
|
|
|
if change.Type == "delete" && change.Path[2] == "ID" {
|
|
|
|
p.CreateItemRemovedChange(change.Path[1])
|
|
|
|
}
|
|
|
|
case "Attributes":
|
|
|
|
if change.Type == "create" && change.Path[2] == "ID" {
|
|
|
|
p.CreateStatModifiedChange(p.Attributes.GetAttribute(change.Path[1]))
|
|
|
|
}
|
|
|
|
|
|
|
|
if change.Type == "update" && change.Path[2] == "Value" {
|
|
|
|
p.CreateStatModifiedChange(p.Attributes.GetAttribute(change.Path[1]))
|
|
|
|
}
|
2023-11-01 01:24:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-31 23:19:52 +00:00
|
|
|
return changes
|
|
|
|
}
|
|
|
|
|
2023-11-02 17:50:52 +00:00
|
|
|
func (p *Profile) CreateStatModifiedChange(attribute *Attribute) {
|
|
|
|
if attribute == nil {
|
|
|
|
fmt.Println("error getting attribute from profile", attribute.ID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Changes = append(p.Changes, StatModified{
|
|
|
|
ChangeType: "statModified",
|
|
|
|
Name: attribute.Key,
|
|
|
|
Value: attribute.Value,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Profile) CreateGiftAddedChange(gift *Gift) {
|
|
|
|
if gift == nil {
|
|
|
|
fmt.Println("error getting gift from profile", gift.ID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Changes = append(p.Changes, ItemAdded{
|
|
|
|
ChangeType: "itemAdded",
|
|
|
|
ItemId: gift.ID,
|
|
|
|
Item: gift.GenerateFortniteGiftEntry(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Profile) CreateQuestAddedChange(quest *Quest) {
|
|
|
|
if quest == nil {
|
|
|
|
fmt.Println("error getting quest from profile", quest.ID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Changes = append(p.Changes, ItemAdded{
|
|
|
|
ChangeType: "itemAdded",
|
|
|
|
ItemId: quest.ID,
|
|
|
|
Item: quest.GenerateFortniteQuestEntry(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-11-01 01:24:42 +00:00
|
|
|
func (p *Profile) CreateItemAddedChange(item *Item) {
|
|
|
|
if item == nil {
|
|
|
|
fmt.Println("error getting item from profile", item.ID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Changes = append(p.Changes, ItemAdded{
|
|
|
|
ChangeType: "itemAdded",
|
|
|
|
ItemId: item.ID,
|
|
|
|
Item: item.GenerateFortniteItemEntry(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Profile) CreateItemRemovedChange(itemId string) {
|
|
|
|
p.Changes = append(p.Changes, ItemRemoved{
|
|
|
|
ChangeType: "itemRemoved",
|
|
|
|
ItemId: itemId,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Profile) CreateItemQuantityChangedChange(item *Item) {
|
|
|
|
if item == nil {
|
|
|
|
fmt.Println("error getting item from profile", item.ID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Changes = append(p.Changes, ItemQuantityChanged{
|
|
|
|
ChangeType: "itemQuantityChanged",
|
|
|
|
ItemId: item.ID,
|
|
|
|
Quantity: item.Quantity,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Profile) CreateItemAttributeChangedChange(item *Item, attribute string) {
|
|
|
|
if item == nil {
|
|
|
|
fmt.Println("error getting item from profile", item.ID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
lookup := map[string]string{
|
|
|
|
"Favorite": "favorite",
|
|
|
|
"HasSeen": "item_seen",
|
|
|
|
"Variants": "variants",
|
|
|
|
}
|
|
|
|
|
|
|
|
p.Changes = append(p.Changes, ItemAttributeChanged{
|
|
|
|
ChangeType: "itemAttributeChanged",
|
|
|
|
ItemId: item.ID,
|
|
|
|
AttributeName: lookup[attribute],
|
|
|
|
AttributeValue: item.GetAttribute(attribute),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-11-03 23:48:50 +00:00
|
|
|
func (p *Profile) CreateFullProfileUpdateChange() {
|
|
|
|
p.Changes = append(p.Changes, FullProfileUpdate{
|
|
|
|
ChangeType: "fullProfileUpdate",
|
|
|
|
Profile: p.GenerateFortniteProfileEntry(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-10-31 22:40:14 +00:00
|
|
|
type Loadout struct {
|
|
|
|
ID string
|
|
|
|
Character string
|
|
|
|
Backpack string
|
|
|
|
Pickaxe string
|
|
|
|
Glider string
|
|
|
|
Dances []string
|
|
|
|
ItemWraps []string
|
|
|
|
LoadingScreen string
|
|
|
|
SkyDiveContrail string
|
|
|
|
MusicPack string
|
|
|
|
BannerIcon string
|
|
|
|
BannerColor string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewLoadout() *Loadout {
|
|
|
|
return &Loadout{
|
|
|
|
ID: uuid.New().String(),
|
|
|
|
Character: "",
|
|
|
|
Backpack: "",
|
|
|
|
Pickaxe: "",
|
|
|
|
Glider: "",
|
2023-11-01 01:24:42 +00:00
|
|
|
Dances: make([]string, 6),
|
|
|
|
ItemWraps: make([]string, 7),
|
2023-10-31 22:40:14 +00:00
|
|
|
LoadingScreen: "",
|
|
|
|
SkyDiveContrail: "",
|
|
|
|
MusicPack: "",
|
|
|
|
BannerIcon: "",
|
|
|
|
BannerColor: "",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-01 01:24:42 +00:00
|
|
|
func FromDatabaseLoadout(l *storage.DB_Loadout) *Loadout {
|
2023-10-31 22:40:14 +00:00
|
|
|
return &Loadout{
|
2023-11-01 01:24:42 +00:00
|
|
|
ID: l.ID,
|
|
|
|
Character: l.Character,
|
|
|
|
Backpack: l.Backpack,
|
|
|
|
Pickaxe: l.Pickaxe,
|
|
|
|
Glider: l.Glider,
|
|
|
|
Dances: l.Dances,
|
|
|
|
ItemWraps: l.ItemWraps,
|
|
|
|
LoadingScreen: l.LoadingScreen,
|
|
|
|
SkyDiveContrail: l.SkyDiveContrail,
|
|
|
|
MusicPack: l.MusicPack,
|
|
|
|
BannerIcon: l.BannerIcon,
|
|
|
|
BannerColor: l.BannerColor,
|
2023-10-31 22:40:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Loadout) ToDatabase() *storage.DB_Loadout {
|
|
|
|
return &storage.DB_Loadout{
|
|
|
|
ID: l.ID,
|
|
|
|
Character: l.Character,
|
|
|
|
Backpack: l.Backpack,
|
|
|
|
Pickaxe: l.Pickaxe,
|
|
|
|
Glider: l.Glider,
|
|
|
|
Dances: l.Dances,
|
|
|
|
ItemWraps: l.ItemWraps,
|
|
|
|
LoadingScreen: l.LoadingScreen,
|
|
|
|
SkyDiveContrail: l.SkyDiveContrail,
|
|
|
|
MusicPack: l.MusicPack,
|
|
|
|
BannerIcon: l.BannerIcon,
|
|
|
|
BannerColor: l.BannerColor,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Loadout) Save() {
|
|
|
|
//storage.Repo.SaveLoadout(l.ToDatabase())
|
|
|
|
}
|