Equip Item; Refactor Loadouts; Move Cache System; ...
Change up attribrutes again. Fix indent bug.
This commit is contained in:
parent
113c68a38d
commit
db9f92bd91
12
aid/aid.go
12
aid/aid.go
|
@ -1,6 +1,7 @@
|
|||
package aid
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
@ -11,3 +12,14 @@ func WaitForExit() {
|
|||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||
<-sc
|
||||
}
|
||||
|
||||
func JSONStringify(input interface{}) string {
|
||||
json, _ := json.Marshal(input)
|
||||
return string(json)
|
||||
}
|
||||
|
||||
func JSONParse(input string) interface{} {
|
||||
var output interface{}
|
||||
json.Unmarshal([]byte(input), &output)
|
||||
return output
|
||||
}
|
|
@ -2,6 +2,8 @@ package aid
|
|||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
@ -22,6 +24,10 @@ type CS struct {
|
|||
JWT struct {
|
||||
Secret string
|
||||
}
|
||||
Fortnite struct {
|
||||
Season int
|
||||
Build float64
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -74,4 +80,28 @@ func LoadConfig() {
|
|||
if Config.JWT.Secret == "" {
|
||||
panic("JWT Secret is empty")
|
||||
}
|
||||
|
||||
build, err := cfg.Section("fortnite").Key("build").Float64()
|
||||
if err != nil {
|
||||
panic("Fortnite Build is empty")
|
||||
}
|
||||
|
||||
Config.Fortnite.Build = build
|
||||
|
||||
buildStr := strconv.FormatFloat(build, 'f', -1, 64)
|
||||
if buildStr == "" {
|
||||
panic("Fortnite Build is empty")
|
||||
}
|
||||
|
||||
buildInfo := strings.Split(buildStr, ".")
|
||||
if len(buildInfo) < 2 {
|
||||
panic("Fortnite Build is invalid")
|
||||
}
|
||||
|
||||
parsedSeason, err := strconv.Atoi(buildInfo[0])
|
||||
if err != nil {
|
||||
panic("Fortnite Season is invalid")
|
||||
}
|
||||
|
||||
Config.Fortnite.Season = parsedSeason
|
||||
}
|
15
aid/time.go
Normal file
15
aid/time.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package aid
|
||||
|
||||
import "time"
|
||||
|
||||
func TimeStartOfDay() string {
|
||||
return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.Now().Location()).Format("2006-01-02T15:04:05.999Z")
|
||||
}
|
||||
|
||||
func TimeEndOfDay() string {
|
||||
return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 59, 59, 999999999, time.Now().Location()).Format("2006-01-02T15:04:05.999Z")
|
||||
}
|
||||
|
||||
func TimeEndOfWeekString() string {
|
||||
return time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 59, 59, 999999999, time.Now().Location()).AddDate(0, 0, 7).Format("2006-01-02T15:04:05.999Z")
|
||||
}
|
|
@ -23,3 +23,7 @@ host="0.0.0.0"
|
|||
[jwt]
|
||||
; secret for jwt signing
|
||||
secret="secret"
|
||||
|
||||
[fortnite]
|
||||
; the game build to use
|
||||
build=2.5
|
|
@ -34,3 +34,45 @@ func GetVersionCheck(c *fiber.Ctx) error {
|
|||
"type": "NO_UPDATE",
|
||||
})
|
||||
}
|
||||
|
||||
func GetContentPages(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||
"battlepassaboutmessages": aid.JSON{
|
||||
"news": aid.JSON{
|
||||
"messages": []aid.JSON{},
|
||||
},
|
||||
"lastModified": "0000-00-00T00:00:00.000Z",
|
||||
},
|
||||
"subgameselectdata": aid.JSON{
|
||||
"saveTheWorldUnowned": aid.JSON{
|
||||
"message": aid.JSON{
|
||||
"title": "Co-op PvE",
|
||||
"body": "Cooperative PvE storm-fighting adventure!",
|
||||
"spotlight": false,
|
||||
"hidden": true,
|
||||
"messagetype": "normal",
|
||||
},
|
||||
},
|
||||
"battleRoyale": aid.JSON{
|
||||
"message": aid.JSON{
|
||||
"title": "100 Player PvP",
|
||||
"body": "100 Player PvP Battle Royale.\n\nPvE progress does not affect Battle Royale.",
|
||||
"spotlight": false,
|
||||
"hidden": true,
|
||||
"messagetype": "normal",
|
||||
},
|
||||
},
|
||||
"creative": aid.JSON{
|
||||
"message": aid.JSON{
|
||||
"title": "New Featured Islands!",
|
||||
"body": "Your Island. Your Friends. Your Rules.\n\nDiscover new ways to play Fortnite, play community made games with friends and build your dream island.",
|
||||
"spotlight": false,
|
||||
"hidden": true,
|
||||
"messagetype": "normal",
|
||||
},
|
||||
},
|
||||
"lastModified": "0000-00-00T00:00:00.000Z",
|
||||
},
|
||||
"lastModified": "0000-00-00T00:00:00.000Z",
|
||||
})
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
@ -12,3 +15,50 @@ func GetLightswitchBulkStatus(c *fiber.Ctx) error {
|
|||
"banned": false,
|
||||
}})
|
||||
}
|
||||
|
||||
func GetTimelineCalendar(c *fiber.Ctx) error {
|
||||
events := []aid.JSON{
|
||||
{
|
||||
"activeUntil": aid.TimeEndOfWeekString(),
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"activeEventId": "EventFlag.Season" + strconv.Itoa(aid.Config.Fortnite.Season),
|
||||
},
|
||||
{
|
||||
"activeUntil": aid.TimeEndOfWeekString(),
|
||||
"activeSince": "0001-01-01T00:00:00Z",
|
||||
"activeEventId": "EventFlag.LobbySeason" + strconv.Itoa(aid.Config.Fortnite.Season),
|
||||
},
|
||||
}
|
||||
|
||||
state := aid.JSON{
|
||||
"seasonNumber": aid.Config.Fortnite.Season,
|
||||
"seasonTemplateId": "AthenaSeason:AthenaSeason" + strconv.Itoa(aid.Config.Fortnite.Season),
|
||||
"seasonBegin": time.Now().Add(-time.Hour * 24 * 7).Format("2006-01-02T15:04:05.000Z"),
|
||||
"seasonEnd": time.Now().Add(time.Hour * 24 * 7).Format("2006-01-02T15:04:05.000Z"),
|
||||
"seasonDisplayedEnd": time.Now().Add(time.Hour * 24 * 7).Format("2006-01-02T15:04:05.000Z"),
|
||||
"activeStorefronts": []aid.JSON{},
|
||||
"dailyStoreEnd": aid.TimeEndOfDay(),
|
||||
"weeklyStoreEnd": aid.TimeEndOfWeekString(),
|
||||
"sectionStoreEnds": aid.JSON{},
|
||||
"stwEventStoreEnd": aid.TimeEndOfWeekString(),
|
||||
"stwWeeklyStoreEnd": aid.TimeEndOfWeekString(),
|
||||
}
|
||||
|
||||
client := aid.JSON{
|
||||
"states": []aid.JSON{{
|
||||
"activeEvents": events,
|
||||
"state": state,
|
||||
"validFrom": "0001-01-01T00:00:00Z",
|
||||
}},
|
||||
"cacheExpire": "9999-12-31T23:59:59.999Z",
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||
"channels": aid.JSON{
|
||||
"client-events": client,
|
||||
},
|
||||
"currentTime": time.Now().Format("2006-01-02T15:04:05.000Z"),
|
||||
"cacheIntervalMins": 5,
|
||||
"eventsTimeOffsetHrs": 0,
|
||||
})
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
|
@ -13,6 +15,8 @@ var (
|
|||
profileActions = map[string]func(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
"QueryProfile": PostQueryProfileAction,
|
||||
"ClientQuestLogin": PostQueryProfileAction,
|
||||
"MarkItemSeen": PostMarkItemSeenAction,
|
||||
"EquipBattleRoyaleCustomization": PostEquipBattleRoyaleCustomizationAction,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -21,27 +25,33 @@ func PostProfileAction(c *fiber.Ctx) error {
|
|||
if person == nil {
|
||||
return c.Status(404).JSON(aid.ErrorBadRequest("No Account Found"))
|
||||
}
|
||||
defer person.Save()
|
||||
|
||||
profile := person.GetProfileFromType(c.Query("profileId"))
|
||||
if profile == nil {
|
||||
return c.Status(404).JSON(aid.ErrorBadRequest("No Profile Found"))
|
||||
}
|
||||
defer profile.ClearProfileChanges()
|
||||
|
||||
snapshot := profile.Snapshot()
|
||||
before := profile.Snapshot()
|
||||
if action, ok := profileActions[c.Params("action")]; ok {
|
||||
err := action(c, person, profile)
|
||||
if err != nil {
|
||||
if err := action(c, person, profile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
profile.Diff(snapshot)
|
||||
profile.Revision++
|
||||
changes := profile.Diff(before)
|
||||
|
||||
aid.Print("Changes: " + strconv.Itoa(len(changes)))
|
||||
aid.PrintJSON(changes)
|
||||
|
||||
revision, _ := strconv.Atoi(c.Query("rvn"))
|
||||
if revision == -1 {
|
||||
revision = profile.Revision
|
||||
}
|
||||
revision++
|
||||
|
||||
return c.Status(200).JSON(aid.JSON{
|
||||
"profileId": profile.Type,
|
||||
"profileRevision": profile.Revision,
|
||||
"profileCommandRevision": profile.Revision,
|
||||
"profileChangesBaseRevision": profile.Revision - 1,
|
||||
"profileRevision": revision,
|
||||
"profileCommandRevision": revision,
|
||||
"profileChangesBaseRevision": revision - 1,
|
||||
"profileChanges": profile.Changes,
|
||||
"multiUpdate": []aid.JSON{},
|
||||
"notifications": []aid.JSON{},
|
||||
|
@ -51,7 +61,66 @@ func PostProfileAction(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
func PostQueryProfileAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
profile.Changes = []interface{}{}
|
||||
profile.CreateFullProfileUpdateChange()
|
||||
return nil
|
||||
}
|
||||
|
||||
func PostMarkItemSeenAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
var body struct {
|
||||
ItemIds []string `json:"itemIds"`
|
||||
}
|
||||
|
||||
err := c.BodyParser(&body)
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(aid.ErrorBadRequest("Invalid Body"))
|
||||
}
|
||||
|
||||
for _, itemId := range body.ItemIds {
|
||||
item := profile.Items.GetItem(itemId)
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
item.HasSeen = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func PostEquipBattleRoyaleCustomizationAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||
var body struct {
|
||||
SlotName string `json:"slotName"`
|
||||
ItemToSlot string `json:"itemToSlot"`
|
||||
IndexWithinSlot int `json:"indexWithinSlot"`
|
||||
}
|
||||
|
||||
err := c.BodyParser(&body)
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(aid.ErrorBadRequest("Invalid Body"))
|
||||
}
|
||||
|
||||
item := profile.Items.GetItem(body.ItemToSlot)
|
||||
if item == nil {
|
||||
return c.Status(400).JSON(aid.ErrorBadRequest("Item not found"))
|
||||
}
|
||||
|
||||
attr := profile.Attributes.GetAttributeByKey("favorite_" + strings.ToLower(body.SlotName))
|
||||
if attr == nil {
|
||||
return c.Status(400).JSON(aid.ErrorBadRequest("Attribute not found"))
|
||||
}
|
||||
|
||||
switch body.SlotName {
|
||||
case "Dance":
|
||||
value := aid.JSONParse(attr.ValueJSON)
|
||||
value.([]any)[body.IndexWithinSlot] = item.ID
|
||||
attr.ValueJSON = aid.JSONStringify(value)
|
||||
case "ItemWrap":
|
||||
value := aid.JSONParse(attr.ValueJSON)
|
||||
value.([]any)[body.IndexWithinSlot] = item.ID
|
||||
attr.ValueJSON = aid.JSONStringify(value)
|
||||
default:
|
||||
attr.ValueJSON = aid.JSONStringify(item.ID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -17,7 +17,7 @@ func GetCloudStorageConfig(c *fiber.Ctx) error {
|
|||
"epicAppName": "Live",
|
||||
"isAuthenticated": true,
|
||||
"disableV2": true,
|
||||
"lastUpdated": "2021-01-01T00:00:00Z",
|
||||
"lastUpdated": "0000-00-00T00:00:00.000Z",
|
||||
"transports": []string{},
|
||||
})
|
||||
}
|
||||
|
@ -30,3 +30,15 @@ func GetCloudStorageFile(c *fiber.Ctx) error {
|
|||
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{})
|
||||
}
|
||||
|
||||
func GetUserStorageFiles(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON([]aid.JSON{})
|
||||
}
|
||||
|
||||
func GetUserStorageFile(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{})
|
||||
}
|
||||
|
||||
func PutUserStorageFile(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{})
|
||||
}
|
12
main.go
12
main.go
|
@ -22,7 +22,6 @@ func init() {
|
|||
}
|
||||
|
||||
postgresStorage.Migrate(&storage.DB_Person{}, "Persons")
|
||||
postgresStorage.Migrate(&storage.DB_Loadout{}, "Loadouts")
|
||||
postgresStorage.Migrate(&storage.DB_Profile{}, "Profiles")
|
||||
postgresStorage.Migrate(&storage.DB_Item{}, "Items")
|
||||
postgresStorage.Migrate(&storage.DB_Gift{}, "Gifts")
|
||||
|
@ -35,12 +34,11 @@ func init() {
|
|||
}
|
||||
|
||||
storage.Repo = storage.NewStorage(device)
|
||||
storage.Cache = storage.NewPersonsCacheMutex()
|
||||
}
|
||||
|
||||
func init() {
|
||||
if aid.Config.Database.DropAllTables {
|
||||
person.NewFortnitePerson("ac", "ket")
|
||||
person.NewFortnitePerson("ac", "1")
|
||||
}
|
||||
|
||||
aid.PrintTime("Loading all persons from database", func() {
|
||||
|
@ -49,7 +47,7 @@ func init() {
|
|||
}
|
||||
})
|
||||
|
||||
go storage.Cache.CacheKiller()
|
||||
// go storage.Cache.CacheKiller()
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -59,6 +57,8 @@ func main() {
|
|||
r.Use(aid.FiberLimiter())
|
||||
r.Use(aid.FiberCors())
|
||||
|
||||
r.Get("/content/api/pages/fortnite-game", handlers.GetContentPages)
|
||||
|
||||
account := r.Group("/account/api")
|
||||
account.Get("/public/account/:accountId", handlers.GetPublicAccount)
|
||||
account.Get("/public/account/:accountId/externalAuths", handlers.GetPublicAccountExternalAuths)
|
||||
|
@ -68,6 +68,7 @@ func main() {
|
|||
fortnite := r.Group("/fortnite/api")
|
||||
fortnite.Get("/receipts/v1/account/:accountId/receipts", handlers.GetAccountReceipts)
|
||||
fortnite.Get("/versioncheck/*", handlers.GetVersionCheck)
|
||||
fortnite.Get("/calendar/v1/timeline", handlers.GetTimelineCalendar)
|
||||
|
||||
matchmaking := fortnite.Group("/matchmaking")
|
||||
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetSessionFindPlayer)
|
||||
|
@ -76,6 +77,9 @@ func main() {
|
|||
storage.Get("/system", handlers.GetCloudStorageFiles)
|
||||
storage.Get("/system/config", handlers.GetCloudStorageConfig)
|
||||
storage.Get("/system/:fileName", handlers.GetCloudStorageFile)
|
||||
storage.Get("/user/:accountId", handlers.GetUserStorageFiles)
|
||||
storage.Get("/user/:accountId/:fileName", handlers.GetUserStorageFile)
|
||||
storage.Put("/user/:accountId/:fileName", handlers.PutUserStorageFile)
|
||||
|
||||
game := fortnite.Group("/game/v2")
|
||||
game.Post("/tryPlayOnPlatform/account/:accountId", handlers.PostTryPlayOnPlatform)
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package person
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
"github.com/ectrc/snow/storage"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Attribute struct {
|
||||
ID string
|
||||
ProfileID string
|
||||
Key string
|
||||
Value interface{}
|
||||
ValueJSON string
|
||||
Type string
|
||||
}
|
||||
|
||||
|
@ -19,37 +20,27 @@ func NewAttribute(key string, value interface{}) *Attribute {
|
|||
return &Attribute{
|
||||
ID: uuid.New().String(),
|
||||
Key: key,
|
||||
Value: value,
|
||||
ValueJSON: aid.JSONStringify(value),
|
||||
Type: reflect.TypeOf(value).String(),
|
||||
}
|
||||
}
|
||||
|
||||
func FromDatabaseAttribute(db *storage.DB_PAttribute) *Attribute {
|
||||
var value interface{}
|
||||
err := json.Unmarshal([]byte(db.ValueJSON), &value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &Attribute{
|
||||
ID: db.ID,
|
||||
ProfileID: db.ProfileID,
|
||||
Key: db.Key,
|
||||
Value: value,
|
||||
ValueJSON: db.ValueJSON,
|
||||
Type: db.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Attribute) ToDatabase(profileId string) *storage.DB_PAttribute {
|
||||
value, err := json.Marshal(a.Value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &storage.DB_PAttribute{
|
||||
ID: a.ID,
|
||||
ProfileID: profileId,
|
||||
Key: a.Key,
|
||||
ValueJSON: string(value),
|
||||
ValueJSON: a.ValueJSON,
|
||||
Type: a.Type,
|
||||
}
|
||||
}
|
||||
|
@ -57,3 +48,11 @@ func (a *Attribute) ToDatabase(profileId string) *storage.DB_PAttribute {
|
|||
func (a *Attribute) Delete() {
|
||||
storage.Repo.DeleteAttribute(a.ID)
|
||||
}
|
||||
|
||||
func (a *Attribute) Save() {
|
||||
if a.ProfileID == "" {
|
||||
aid.Print("error saving attribute", a.Key, "profile id is empty")
|
||||
return
|
||||
}
|
||||
storage.Repo.SaveAttribute(a.ToDatabase(a.ProfileID))
|
||||
}
|
|
@ -1,12 +1,17 @@
|
|||
package storage
|
||||
package person
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
cache *PersonsCache
|
||||
)
|
||||
|
||||
type CacheEntry struct {
|
||||
Entry interface{}
|
||||
Entry *Person
|
||||
LastAccessed time.Time
|
||||
}
|
||||
|
||||
|
@ -20,15 +25,15 @@ func NewPersonsCacheMutex() *PersonsCache {
|
|||
|
||||
func (m *PersonsCache) CacheKiller() {
|
||||
for {
|
||||
if Cache.Count() == 0 {
|
||||
if m.Count() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
Cache.Range(func(key, value interface{}) bool {
|
||||
m.Range(func(key, value interface{}) bool {
|
||||
cacheEntry := value.(*CacheEntry)
|
||||
|
||||
if time.Since(cacheEntry.LastAccessed) >= 30 * time.Minute {
|
||||
Cache.Delete(key)
|
||||
m.Delete(key)
|
||||
}
|
||||
|
||||
return true
|
||||
|
@ -38,20 +43,21 @@ func (m *PersonsCache) CacheKiller() {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *PersonsCache) GetPerson(id string) *DB_Person {
|
||||
func (m *PersonsCache) GetPerson(id string) *Person {
|
||||
if p, ok := m.Load(id); ok {
|
||||
fmt.Println("Cache hit", id)
|
||||
cacheEntry := p.(*CacheEntry)
|
||||
return cacheEntry.Entry.(*DB_Person)
|
||||
return cacheEntry.Entry
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *PersonsCache) GetPersonByDisplay(displayName string) *DB_Person {
|
||||
var person *DB_Person
|
||||
m.Range(func(key, value interface{}) bool {
|
||||
if value.(*CacheEntry).Entry.(*DB_Person).DisplayName == displayName {
|
||||
person = value.(*CacheEntry).Entry.(*DB_Person)
|
||||
func (m *PersonsCache) GetPersonByDisplay(displayName string) *Person {
|
||||
var person *Person
|
||||
m.RangeEntry(func(key string, value *CacheEntry) bool {
|
||||
if value.Entry.DisplayName == displayName {
|
||||
person = value.Entry
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -61,7 +67,7 @@ func (m *PersonsCache) GetPersonByDisplay(displayName string) *DB_Person {
|
|||
return person
|
||||
}
|
||||
|
||||
func (m *PersonsCache) SavePerson(p *DB_Person) {
|
||||
func (m *PersonsCache) SavePerson(p *Person) {
|
||||
m.Store(p.ID, &CacheEntry{
|
||||
Entry: p,
|
||||
LastAccessed: time.Now(),
|
||||
|
@ -72,9 +78,9 @@ func (m *PersonsCache) DeletePerson(id string) {
|
|||
m.Delete(id)
|
||||
}
|
||||
|
||||
func (m *PersonsCache) RangePersons(f func(key string, value *DB_Person) bool) {
|
||||
func (m *PersonsCache) RangeEntry(f func(key string, value *CacheEntry) bool) {
|
||||
m.Range(func(key, value interface{}) bool {
|
||||
return f(key.(string), value.(*CacheEntry).Entry.(*DB_Person))
|
||||
return f(key.(string), value.(*CacheEntry))
|
||||
})
|
||||
}
|
||||
|
|
@ -7,22 +7,14 @@ func NewFortnitePerson(displayName string, key string) {
|
|||
person.DisplayName = displayName
|
||||
person.AccessKey = key
|
||||
|
||||
character := NewItem("AthenaCharacter:CID_001_Athena_Commando_F_Default", 1)
|
||||
pickaxe := NewItem("AthenaPickaxe:DefaultPickaxe", 1)
|
||||
glider := NewItem("AthenaGlider:DefaultGlider", 1)
|
||||
default_dance := NewItem("AthenaDance:EID_DanceMoves", 1)
|
||||
|
||||
person.AthenaProfile.Items.AddItem(character)
|
||||
person.AthenaProfile.Items.AddItem(pickaxe)
|
||||
person.AthenaProfile.Items.AddItem(glider)
|
||||
person.AthenaProfile.Items.AddItem(default_dance)
|
||||
person.AthenaProfile.Items.AddItem(NewItem("AthenaCharacter:CID_001_Athena_Commando_F_Default", 1))
|
||||
person.AthenaProfile.Items.AddItem(NewItem("AthenaCharacter:CID_032_Athena_Commando_M_Medieval", 1))
|
||||
person.AthenaProfile.Items.AddItem(NewItem("AthenaCharacter:CID_033_Athena_Commando_F_Medieval", 1))
|
||||
person.AthenaProfile.Items.AddItem(NewItem("AthenaPickaxe:DefaultPickaxe", 1))
|
||||
person.AthenaProfile.Items.AddItem(NewItem("AthenaGlider:DefaultGlider", 1))
|
||||
person.AthenaProfile.Items.AddItem(NewItem("AthenaDance:EID_DanceMoves", 1))
|
||||
person.CommonCoreProfile.Items.AddItem(NewItem("Currency:MtxPurchased", 0))
|
||||
|
||||
person.Loadout.Character = character.ID
|
||||
person.Loadout.Pickaxe = pickaxe.ID
|
||||
person.Loadout.Glider = glider.ID
|
||||
person.Loadout.Dances[0] = default_dance.ID
|
||||
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("mfa_reward_claimed", true))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("rested_xp_overflow", 0))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("lifetime_wins", 0))
|
||||
|
@ -32,7 +24,7 @@ func NewFortnitePerson(displayName string, key string) {
|
|||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("daily_rewards", []aid.JSON{}))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("competitive_identity", aid.JSON{}))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("season_update", 0))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("season_num", 2))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("season_num", aid.Config.Fortnite.Season))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("permissions", []aid.JSON{}))
|
||||
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("loadouts", []aid.JSON{}))
|
||||
|
@ -51,17 +43,17 @@ func NewFortnitePerson(displayName string, key string) {
|
|||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("book_level", 1))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("book_xp", 0))
|
||||
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_character", person.Loadout.Character))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_backpack", person.Loadout.Backpack))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_pickaxe", person.Loadout.Pickaxe))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_glider", person.Loadout.Glider))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_skydivecontrail", person.Loadout.SkyDiveContrail))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_dance", person.Loadout.Dances))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_itemwraps", person.Loadout.ItemWraps))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_loadingscreen", person.Loadout.LoadingScreen))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_musicpack", person.Loadout.MusicPack))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_icon", person.Loadout.BannerIcon))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_color", person.Loadout.BannerColor))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_character", person.AthenaProfile.Items.GetItemByTemplateID("AthenaCharacter:CID_001_Athena_Commando_F_Default").ID))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_backpack", ""))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_pickaxe", person.AthenaProfile.Items.GetItemByTemplateID("AthenaPickaxe:DefaultPickaxe").ID))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_glider", person.AthenaProfile.Items.GetItemByTemplateID("AthenaGlider:DefaultGlider").ID))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_skydivecontrail", ""))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_dance", make([]string, 6)))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_itemwraps", make([]string, 7)))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_loadingscreen", ""))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_musicpack", ""))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_icon", ""))
|
||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_color", ""))
|
||||
|
||||
person.CommonCoreProfile.Attributes.AddAttribute(NewAttribute("mfa_enabled", true))
|
||||
person.CommonCoreProfile.Attributes.AddAttribute(NewAttribute("mtx_affiliate", ""))
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
type Gift struct {
|
||||
ID string
|
||||
ProfileID string
|
||||
TemplateID string
|
||||
Quantity int
|
||||
FromID string
|
||||
|
@ -39,6 +40,7 @@ func FromDatabaseGift(gift *storage.DB_Gift) *Gift {
|
|||
|
||||
return &Gift{
|
||||
ID: gift.ID,
|
||||
ProfileID: gift.ProfileID,
|
||||
TemplateID: gift.TemplateID,
|
||||
Quantity: gift.Quantity,
|
||||
FromID: gift.FromID,
|
||||
|
@ -101,8 +103,8 @@ func (g *Gift) ToDatabase(profileId string) *storage.DB_Gift {
|
|||
}
|
||||
|
||||
return &storage.DB_Gift{
|
||||
ProfileID: profileId,
|
||||
ID: g.ID,
|
||||
ProfileID: profileId,
|
||||
TemplateID: g.TemplateID,
|
||||
Quantity: g.Quantity,
|
||||
FromID: g.FromID,
|
||||
|
@ -113,7 +115,12 @@ func (g *Gift) ToDatabase(profileId string) *storage.DB_Gift {
|
|||
}
|
||||
|
||||
func (g *Gift) Save() {
|
||||
//storage.Repo.SaveGift(g.ToDatabase())
|
||||
if g.ProfileID == "" {
|
||||
aid.Print("error saving gift", g.ID, "no profile id")
|
||||
return
|
||||
}
|
||||
|
||||
storage.Repo.SaveGift(g.ToDatabase(g.ProfileID))
|
||||
}
|
||||
|
||||
func (g *Gift) Snapshot() GiftSnapshot {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
type Item struct {
|
||||
ID string
|
||||
ProfileID string
|
||||
TemplateID string
|
||||
Quantity int
|
||||
Favorite bool
|
||||
|
@ -39,7 +40,7 @@ func NewItemWithType(templateID string, quantity int, profile string) *Item {
|
|||
}
|
||||
}
|
||||
|
||||
func FromDatabaseItem(item *storage.DB_Item, profileType *string) *Item {
|
||||
func FromDatabaseItem(item *storage.DB_Item) *Item {
|
||||
variants := []*VariantChannel{}
|
||||
|
||||
for _, variant := range item.Variants {
|
||||
|
@ -53,7 +54,6 @@ func FromDatabaseItem(item *storage.DB_Item, profileType *string) *Item {
|
|||
Favorite: item.Favorite,
|
||||
HasSeen: item.HasSeen,
|
||||
Variants: variants,
|
||||
ProfileType: *profileType,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,12 @@ func (i *Item) ToDatabase(profileId string) *storage.DB_Item {
|
|||
}
|
||||
|
||||
func (i *Item) Save() {
|
||||
//storage.Repo.SaveItem(i.ToDatabase())
|
||||
if i.ProfileID == "" {
|
||||
aid.Print("error saving item", i.ID, "no profile id")
|
||||
return
|
||||
}
|
||||
|
||||
storage.Repo.SaveItem(i.ToDatabase(i.ProfileID))
|
||||
}
|
||||
|
||||
func (i *Item) ToLootDatabase(giftId string) *storage.DB_Loot {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package person
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ectrc/snow/storage"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
@ -13,7 +15,6 @@ type Person struct {
|
|||
CommonCoreProfile *Profile
|
||||
CommonPublicProfile *Profile
|
||||
Profile0 *Profile
|
||||
Loadout *Loadout
|
||||
}
|
||||
|
||||
type Option struct {
|
||||
|
@ -30,69 +31,52 @@ func NewPerson() *Person {
|
|||
CommonCoreProfile: NewProfile("common_core"),
|
||||
CommonPublicProfile: NewProfile("common_public"),
|
||||
Profile0: NewProfile("profile0"),
|
||||
Loadout: NewLoadout(),
|
||||
}
|
||||
}
|
||||
|
||||
func Find(personId string) *Person {
|
||||
person := storage.Repo.GetPerson(personId)
|
||||
if cache == nil {
|
||||
cache = NewPersonsCacheMutex()
|
||||
}
|
||||
|
||||
cachedPerson := cache.GetPerson(personId)
|
||||
if cachedPerson != nil {
|
||||
return cachedPerson
|
||||
}
|
||||
|
||||
person := storage.Repo.GetPersonFromDB(personId)
|
||||
if person == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
loadout := FromDatabaseLoadout(&person.Loadout)
|
||||
athenaProfile := NewProfile("athena")
|
||||
commonCoreProfile := NewProfile("common_core")
|
||||
commonPublicProfile := NewProfile("common_public")
|
||||
profile0 := NewProfile("profile0")
|
||||
|
||||
for _, profile := range person.Profiles {
|
||||
if profile.Type == "athena" {
|
||||
athenaProfile.ID = profile.ID
|
||||
athenaProfile = FromDatabaseProfile(&profile)
|
||||
}
|
||||
|
||||
if profile.Type == "common_core" {
|
||||
commonCoreProfile.ID = profile.ID
|
||||
commonCoreProfile = FromDatabaseProfile(&profile)
|
||||
}
|
||||
|
||||
if profile.Type == "common_public" {
|
||||
commonPublicProfile.ID = profile.ID
|
||||
commonPublicProfile = FromDatabaseProfile(&profile)
|
||||
}
|
||||
|
||||
if profile.Type == "profile0" {
|
||||
profile0.ID = profile.ID
|
||||
profile0 = FromDatabaseProfile(&profile)
|
||||
}
|
||||
}
|
||||
|
||||
return &Person{
|
||||
ID: person.ID,
|
||||
DisplayName: person.DisplayName,
|
||||
AccessKey: person.AccessKey,
|
||||
AthenaProfile: athenaProfile,
|
||||
CommonCoreProfile: commonCoreProfile,
|
||||
CommonPublicProfile: commonPublicProfile,
|
||||
Profile0: profile0,
|
||||
Loadout: loadout,
|
||||
}
|
||||
return findHelper(person)
|
||||
}
|
||||
|
||||
func FindByDisplay(displayName string) *Person {
|
||||
person := storage.Repo.GetPersonByDisplay(displayName)
|
||||
if cache == nil {
|
||||
cache = NewPersonsCacheMutex()
|
||||
}
|
||||
|
||||
person := storage.Repo.GetPersonByDisplayFromDB(displayName)
|
||||
if person == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
loadout := FromDatabaseLoadout(&person.Loadout)
|
||||
cachedPerson := cache.GetPerson(person.ID)
|
||||
if cachedPerson != nil {
|
||||
return cachedPerson
|
||||
}
|
||||
|
||||
return findHelper(person)
|
||||
}
|
||||
|
||||
func findHelper(databasePerson *storage.DB_Person) *Person {
|
||||
athenaProfile := NewProfile("athena")
|
||||
commonCoreProfile := NewProfile("common_core")
|
||||
commonPublicProfile := NewProfile("common_public")
|
||||
profile0 := NewProfile("profile0")
|
||||
|
||||
for _, profile := range person.Profiles {
|
||||
for _, profile := range databasePerson.Profiles {
|
||||
if profile.Type == "athena" {
|
||||
athenaProfile.ID = profile.ID
|
||||
athenaProfile = FromDatabaseProfile(&profile)
|
||||
|
@ -114,16 +98,22 @@ func FindByDisplay(displayName string) *Person {
|
|||
}
|
||||
}
|
||||
|
||||
return &Person{
|
||||
ID: person.ID,
|
||||
DisplayName: person.DisplayName,
|
||||
AccessKey: person.AccessKey,
|
||||
person := &Person{
|
||||
ID: databasePerson.ID,
|
||||
DisplayName: databasePerson.DisplayName,
|
||||
AccessKey: databasePerson.AccessKey,
|
||||
AthenaProfile: athenaProfile,
|
||||
CommonCoreProfile: commonCoreProfile,
|
||||
CommonPublicProfile: commonPublicProfile,
|
||||
Profile0: profile0,
|
||||
Loadout: loadout,
|
||||
}
|
||||
|
||||
cache.Store(person.ID, &CacheEntry{
|
||||
Entry: person,
|
||||
LastAccessed: time.Now(),
|
||||
})
|
||||
|
||||
return person
|
||||
}
|
||||
|
||||
func AllFromDatabase() []*Person {
|
||||
|
@ -152,7 +142,8 @@ func (p *Person) GetProfileFromType(profileType string) *Profile {
|
|||
}
|
||||
|
||||
func (p *Person) Save() {
|
||||
storage.Repo.SavePerson(p.ToDatabase())
|
||||
dbPerson := p.ToDatabase()
|
||||
storage.Repo.SavePerson(dbPerson)
|
||||
}
|
||||
|
||||
func (p *Person) ToDatabase() *storage.DB_Person {
|
||||
|
@ -160,7 +151,6 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
|||
ID: p.ID,
|
||||
DisplayName: p.DisplayName,
|
||||
Profiles: []storage.DB_Profile{},
|
||||
Loadout: *p.Loadout.ToDatabase(),
|
||||
AccessKey: p.AccessKey,
|
||||
}
|
||||
|
||||
|
@ -178,7 +168,9 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
|||
Type: profileType,
|
||||
Items: []storage.DB_Item{},
|
||||
Gifts: []storage.DB_Gift{},
|
||||
Quests: []storage.DB_Quest{},
|
||||
Attributes: []storage.DB_PAttribute{},
|
||||
Revision: profile.Revision,
|
||||
}
|
||||
|
||||
profile.Items.RangeItems(func(id string, item *Item) bool {
|
||||
|
@ -226,6 +218,5 @@ func (p *Person) Snapshot() *PersonSnapshot {
|
|||
DisplayName: p.DisplayName,
|
||||
AthenaProfile: *p.AthenaProfile.Snapshot(),
|
||||
CommonCoreProfile: *p.CommonCoreProfile.Snapshot(),
|
||||
Loadout: *p.Loadout,
|
||||
}
|
||||
}
|
|
@ -22,13 +22,14 @@ type Profile struct {
|
|||
}
|
||||
|
||||
func NewProfile(profile string) *Profile {
|
||||
id := uuid.New().String()
|
||||
return &Profile{
|
||||
ID: uuid.New().String(),
|
||||
ID: id,
|
||||
PersonID: "",
|
||||
Items: NewItemMutex(profile),
|
||||
Gifts: NewGiftMutex(),
|
||||
Quests: NewQuestMutex(),
|
||||
Attributes: NewAttributeMutex(),
|
||||
Items: NewItemMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||
Gifts: NewGiftMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||
Quests: NewQuestMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||
Attributes: NewAttributeMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||
Type: profile,
|
||||
Revision: 0,
|
||||
Changes: []interface{}{},
|
||||
|
@ -36,13 +37,13 @@ func NewProfile(profile string) *Profile {
|
|||
}
|
||||
|
||||
func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
||||
items := NewItemMutex(profile.Type)
|
||||
gifts := NewGiftMutex()
|
||||
quests := NewQuestMutex()
|
||||
attributes := NewAttributeMutex()
|
||||
items := NewItemMutex(profile)
|
||||
gifts := NewGiftMutex(profile)
|
||||
quests := NewQuestMutex(profile)
|
||||
attributes := NewAttributeMutex(profile)
|
||||
|
||||
for _, item := range profile.Items {
|
||||
items.AddItem(FromDatabaseItem(&item, &profile.Type))
|
||||
items.AddItem(FromDatabaseItem(&item))
|
||||
}
|
||||
|
||||
for _, gift := range profile.Gifts {
|
||||
|
@ -50,7 +51,7 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
|||
}
|
||||
|
||||
for _, quest := range profile.Quests {
|
||||
quests.AddQuest(FromDatabaseQuest(&quest, &profile.Type))
|
||||
quests.AddQuest(FromDatabaseQuest(&quest))
|
||||
}
|
||||
|
||||
for _, attribute := range profile.Attributes {
|
||||
|
@ -72,6 +73,7 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
|||
Attributes: attributes,
|
||||
Type: profile.Type,
|
||||
Revision: profile.Revision,
|
||||
Changes: []interface{}{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +97,7 @@ func (p *Profile) GenerateFortniteProfileEntry() aid.JSON {
|
|||
})
|
||||
|
||||
p.Attributes.RangeAttributes(func(id string, attribute *Attribute) bool {
|
||||
attributes[attribute.Key] = attribute.Value
|
||||
attributes[attribute.Key] = aid.JSONParse(attribute.ValueJSON)
|
||||
return true
|
||||
})
|
||||
|
||||
|
@ -154,8 +156,8 @@ func (p *Profile) Snapshot() *ProfileSnapshot {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
||||
changes, err := diff.Diff(snapshot, p.Snapshot())
|
||||
func (p *Profile) Diff(b *ProfileSnapshot) []diff.Change {
|
||||
changes, err := diff.Diff(*b, *p.Snapshot())
|
||||
if err != nil {
|
||||
fmt.Printf("error diffing profile: %v\n", err)
|
||||
return nil
|
||||
|
@ -200,7 +202,7 @@ func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
|||
p.CreateStatModifiedChange(p.Attributes.GetAttribute(change.Path[1]))
|
||||
}
|
||||
|
||||
if change.Type == "update" && change.Path[2] == "Value" {
|
||||
if change.Type == "update" && change.Path[2] == "ValueJSON" {
|
||||
p.CreateStatModifiedChange(p.Attributes.GetAttribute(change.Path[1]))
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +211,11 @@ func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
|||
return changes
|
||||
}
|
||||
|
||||
func (p *Profile) CreateAttribute(key string, value interface{}) *Attribute {
|
||||
p.Attributes.AddAttribute(NewAttribute(key, value))
|
||||
return p.Attributes.GetAttribute(key)
|
||||
}
|
||||
|
||||
func (p *Profile) CreateStatModifiedChange(attribute *Attribute) {
|
||||
if attribute == nil {
|
||||
fmt.Println("error getting attribute from profile", attribute.ID)
|
||||
|
@ -218,7 +225,7 @@ func (p *Profile) CreateStatModifiedChange(attribute *Attribute) {
|
|||
p.Changes = append(p.Changes, StatModified{
|
||||
ChangeType: "statModified",
|
||||
Name: attribute.Key,
|
||||
Value: attribute.Value,
|
||||
Value: aid.JSONParse(attribute.ValueJSON),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -302,78 +309,12 @@ func (p *Profile) CreateItemAttributeChangedChange(item *Item, attribute string)
|
|||
}
|
||||
|
||||
func (p *Profile) CreateFullProfileUpdateChange() {
|
||||
p.Changes = append(p.Changes, FullProfileUpdate{
|
||||
p.Changes = []interface{}{FullProfileUpdate{
|
||||
ChangeType: "fullProfileUpdate",
|
||||
Profile: p.GenerateFortniteProfileEntry(),
|
||||
})
|
||||
}}
|
||||
}
|
||||
|
||||
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: "",
|
||||
Dances: make([]string, 6),
|
||||
ItemWraps: make([]string, 7),
|
||||
LoadingScreen: "",
|
||||
SkyDiveContrail: "",
|
||||
MusicPack: "",
|
||||
BannerIcon: "",
|
||||
BannerColor: "",
|
||||
}
|
||||
}
|
||||
|
||||
func FromDatabaseLoadout(l *storage.DB_Loadout) *Loadout {
|
||||
return &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) 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())
|
||||
func (p *Profile) ClearProfileChanges() {
|
||||
p.Changes = []interface{}{}
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
type Quest struct {
|
||||
ID string
|
||||
ProfileID string
|
||||
TemplateID string
|
||||
State string
|
||||
Objectives []string
|
||||
|
@ -38,9 +39,10 @@ func NewDailyQuest(templateID string) *Quest {
|
|||
}
|
||||
}
|
||||
|
||||
func FromDatabaseQuest(quest *storage.DB_Quest, profileType *string) *Quest {
|
||||
func FromDatabaseQuest(quest *storage.DB_Quest) *Quest {
|
||||
return &Quest{
|
||||
ID: quest.ID,
|
||||
ProfileID: quest.ProfileID,
|
||||
TemplateID: quest.TemplateID,
|
||||
State: quest.State,
|
||||
Objectives: quest.Objectives,
|
||||
|
@ -126,8 +128,8 @@ func (q *Quest) RemoveObjective(objective string) {
|
|||
|
||||
func (q *Quest) ToDatabase(profileId string) *storage.DB_Quest {
|
||||
return &storage.DB_Quest{
|
||||
ProfileID: profileId,
|
||||
ID: q.ID,
|
||||
ProfileID: profileId,
|
||||
TemplateID: q.TemplateID,
|
||||
State: q.State,
|
||||
Objectives: q.Objectives,
|
||||
|
@ -138,5 +140,5 @@ func (q *Quest) ToDatabase(profileId string) *storage.DB_Quest {
|
|||
}
|
||||
|
||||
func (q *Quest) Save() {
|
||||
//storage.Repo.SaveQuest(q.ToDatabase())
|
||||
storage.Repo.SaveQuest(q.ToDatabase(q.ProfileID))
|
||||
}
|
|
@ -5,7 +5,6 @@ type PersonSnapshot struct {
|
|||
DisplayName string
|
||||
AthenaProfile ProfileSnapshot
|
||||
CommonCoreProfile ProfileSnapshot
|
||||
Loadout Loadout
|
||||
}
|
||||
|
||||
type ProfileSnapshot struct {
|
||||
|
|
|
@ -2,23 +2,28 @@ package person
|
|||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/ectrc/snow/storage"
|
||||
)
|
||||
|
||||
type ItemMutex struct {
|
||||
sync.Map
|
||||
ProfileType string
|
||||
ProfileID string
|
||||
}
|
||||
|
||||
func NewItemMutex(profile string) *ItemMutex {
|
||||
func NewItemMutex(profile *storage.DB_Profile) *ItemMutex {
|
||||
return &ItemMutex{
|
||||
ProfileType: profile,
|
||||
ProfileType: profile.Type,
|
||||
ProfileID: profile.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ItemMutex) AddItem(item *Item) {
|
||||
item.ProfileType = m.ProfileType
|
||||
item.ProfileID = m.ProfileID
|
||||
m.Store(item.ID, item)
|
||||
// storage.Repo.SaveItem(item)
|
||||
storage.Repo.SaveItem(item.ToDatabase(m.ProfileID))
|
||||
}
|
||||
|
||||
func (m *ItemMutex) DeleteItem(id string) {
|
||||
|
@ -29,7 +34,7 @@ func (m *ItemMutex) DeleteItem(id string) {
|
|||
|
||||
item.Delete()
|
||||
m.Delete(id)
|
||||
// storage.Repo.DeleteItem(id)
|
||||
storage.Repo.DeleteItem(id)
|
||||
}
|
||||
|
||||
func (m *ItemMutex) GetItem(id string) *Item {
|
||||
|
@ -74,20 +79,25 @@ func (m *ItemMutex) Count() int {
|
|||
type GiftMutex struct {
|
||||
sync.Map
|
||||
ProfileType string
|
||||
ProfileID string
|
||||
}
|
||||
|
||||
func NewGiftMutex() *GiftMutex {
|
||||
return &GiftMutex{}
|
||||
func NewGiftMutex(profile *storage.DB_Profile) *GiftMutex {
|
||||
return &GiftMutex{
|
||||
ProfileType: profile.Type,
|
||||
ProfileID: profile.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *GiftMutex) AddGift(gift *Gift) {
|
||||
gift.ProfileID = m.ProfileID
|
||||
m.Store(gift.ID, gift)
|
||||
// storage.Repo.SaveGift(gift)
|
||||
storage.Repo.SaveGift(gift.ToDatabase(m.ProfileID))
|
||||
}
|
||||
|
||||
func (m *GiftMutex) DeleteGift(id string) {
|
||||
m.Delete(id)
|
||||
// storage.Repo.DeleteGift(id)
|
||||
storage.Repo.DeleteGift(id)
|
||||
}
|
||||
|
||||
func (m *GiftMutex) GetGift(id string) *Gift {
|
||||
|
@ -116,20 +126,26 @@ func (m *GiftMutex) Count() int {
|
|||
|
||||
type QuestMutex struct {
|
||||
sync.Map
|
||||
ProfileType string
|
||||
ProfileID string
|
||||
}
|
||||
|
||||
func NewQuestMutex() *QuestMutex {
|
||||
return &QuestMutex{}
|
||||
func NewQuestMutex(profile *storage.DB_Profile) *QuestMutex {
|
||||
return &QuestMutex{
|
||||
ProfileType: profile.Type,
|
||||
ProfileID: profile.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *QuestMutex) AddQuest(quest *Quest) {
|
||||
quest.ProfileID = m.ProfileID
|
||||
m.Store(quest.ID, quest)
|
||||
// storage.Repo.SaveQuest(quest)
|
||||
storage.Repo.SaveQuest(quest.ToDatabase(m.ProfileID))
|
||||
}
|
||||
|
||||
func (m *QuestMutex) DeleteQuest(id string) {
|
||||
m.Delete(id)
|
||||
// storage.Repo.DeleteQuest(id)
|
||||
storage.Repo.DeleteQuest(id)
|
||||
}
|
||||
|
||||
func (m *QuestMutex) GetQuest(id string) *Quest {
|
||||
|
@ -158,20 +174,25 @@ func (m *QuestMutex) Count() int {
|
|||
|
||||
type AttributeMutex struct {
|
||||
sync.Map
|
||||
ProfileType string
|
||||
ProfileID string
|
||||
}
|
||||
|
||||
func NewAttributeMutex() *AttributeMutex {
|
||||
return &AttributeMutex{}
|
||||
func NewAttributeMutex(profile *storage.DB_Profile) *AttributeMutex {
|
||||
return &AttributeMutex{
|
||||
ProfileID: profile.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AttributeMutex) AddAttribute(attribute *Attribute) {
|
||||
attribute.ProfileID = m.ProfileID
|
||||
m.Store(attribute.ID, attribute)
|
||||
// storage.Repo.SaveAttribute(key, value)
|
||||
storage.Repo.SaveAttribute(attribute.ToDatabase(m.ProfileID))
|
||||
}
|
||||
|
||||
func (m *AttributeMutex) DeleteAttribute(id string) {
|
||||
m.Delete(id)
|
||||
// storage.Repo.DeleteAttribute(key)
|
||||
storage.Repo.DeleteAttribute(id)
|
||||
}
|
||||
|
||||
func (m *AttributeMutex) GetAttribute(id string) *Attribute {
|
||||
|
|
|
@ -88,22 +88,54 @@ func (s *PostgresStorage) SavePerson(person *DB_Person) {
|
|||
s.Postgres.Save(person)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeletePerson(personId string) {
|
||||
s.Postgres.Delete(&DB_Person{}, "id = ?", personId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveProfile(profile *DB_Profile) {
|
||||
s.Postgres.Save(profile)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteProfile(profileId string) {
|
||||
s.Postgres.Delete(&DB_Profile{}, "id = ?", profileId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveItem(item *DB_Item) {
|
||||
s.Postgres.Save(item)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteItem(itemId string) {
|
||||
s.Postgres.Delete(&DB_Item{}, "id = ?", itemId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveVariant(variant *DB_VariantChannel) {
|
||||
s.Postgres.Save(variant)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteVariant(variantId string) {
|
||||
s.Postgres.Delete(&DB_VariantChannel{}, "id = ?", variantId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveQuest(quest *DB_Quest) {
|
||||
s.Postgres.Save(quest)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteQuest(questId string) {
|
||||
s.Postgres.Delete(&DB_Quest{}, "id = ?", questId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveLoot(loot *DB_Loot) {
|
||||
s.Postgres.Save(loot)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteLoot(lootId string) {
|
||||
s.Postgres.Delete(&DB_Loot{}, "id = ?", lootId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveGift(gift *DB_Gift) {
|
||||
s.Postgres.Save(gift)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) DeleteGift(giftId string) {
|
||||
s.Postgres.Delete(&DB_Gift{}, "id = ?", giftId)
|
||||
}
|
||||
|
@ -111,3 +143,8 @@ func (s *PostgresStorage) DeleteGift(giftId string) {
|
|||
func (s *PostgresStorage) DeleteAttribute(attributeId string) {
|
||||
s.Postgres.Delete(&DB_PAttribute{}, "id = ?", attributeId)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) SaveAttribute(attribute *DB_PAttribute) {
|
||||
aid.Print("saving attribute", attribute.Key, attribute.ValueJSON)
|
||||
s.Postgres.Save(attribute)
|
||||
}
|
|
@ -2,7 +2,6 @@ package storage
|
|||
|
||||
var (
|
||||
Repo *Repository
|
||||
Cache *PersonsCache
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
|
@ -13,11 +12,25 @@ type Storage interface {
|
|||
GetAllPersons() []*DB_Person
|
||||
SavePerson(person *DB_Person)
|
||||
|
||||
SaveProfile(profile *DB_Profile)
|
||||
DeleteProfile(profileId string)
|
||||
|
||||
SaveItem(item *DB_Item)
|
||||
DeleteItem(itemId string)
|
||||
|
||||
SaveVariant(variant *DB_VariantChannel)
|
||||
DeleteVariant(variantId string)
|
||||
|
||||
SaveQuest(quest *DB_Quest)
|
||||
DeleteQuest(questId string)
|
||||
|
||||
SaveLoot(loot *DB_Loot)
|
||||
DeleteLoot(lootId string)
|
||||
|
||||
SaveGift(gift *DB_Gift)
|
||||
DeleteGift(giftId string)
|
||||
|
||||
SaveAttribute(attribute *DB_PAttribute)
|
||||
DeleteAttribute(attributeId string)
|
||||
}
|
||||
|
||||
|
@ -31,30 +44,18 @@ func NewStorage(s Storage) *Repository {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Repository) GetPerson(personId string) *DB_Person {
|
||||
cachePerson := Cache.GetPerson(personId)
|
||||
if cachePerson != nil {
|
||||
return cachePerson
|
||||
}
|
||||
|
||||
func (r *Repository) GetPersonFromDB(personId string) *DB_Person {
|
||||
storagePerson := r.Storage.GetPerson(personId)
|
||||
if storagePerson != nil {
|
||||
Cache.SavePerson(storagePerson)
|
||||
return storagePerson
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetPersonByDisplay(displayName string) *DB_Person {
|
||||
cachePerson := Cache.GetPersonByDisplay(displayName)
|
||||
if cachePerson != nil {
|
||||
return cachePerson
|
||||
}
|
||||
|
||||
func (r *Repository) GetPersonByDisplayFromDB(displayName string) *DB_Person {
|
||||
storagePerson := r.Storage.GetPersonByDisplay(displayName)
|
||||
if storagePerson != nil {
|
||||
Cache.SavePerson(storagePerson)
|
||||
return storagePerson
|
||||
}
|
||||
|
||||
|
@ -66,30 +67,61 @@ func (r *Repository) GetAllPersons() []*DB_Person {
|
|||
}
|
||||
|
||||
func (r *Repository) SavePerson(person *DB_Person) {
|
||||
Cache.SavePerson(person)
|
||||
r.Storage.SavePerson(person)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveProfile(profile *DB_Profile) {
|
||||
r.Storage.SaveProfile(profile)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteProfile(profileId string) {
|
||||
r.Storage.DeleteProfile(profileId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveItem(item *DB_Item) {
|
||||
r.Storage.SaveItem(item)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteItem(itemId string) {
|
||||
r.Storage.DeleteItem(itemId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveVariant(variant *DB_VariantChannel) {
|
||||
r.Storage.SaveVariant(variant)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteVariant(variantId string) {
|
||||
r.Storage.DeleteVariant(variantId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveQuest(quest *DB_Quest) {
|
||||
r.Storage.SaveQuest(quest)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteQuest(questId string) {
|
||||
r.Storage.DeleteQuest(questId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveLoot(loot *DB_Loot) {
|
||||
r.Storage.SaveLoot(loot)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteLoot(lootId string) {
|
||||
r.Storage.DeleteLoot(lootId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveGift(gift *DB_Gift) {
|
||||
r.Storage.SaveGift(gift)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteGift(giftId string) {
|
||||
r.Storage.DeleteGift(giftId)
|
||||
}
|
||||
|
||||
func (r *Repository) SaveAttribute(attribute *DB_PAttribute) {
|
||||
r.Storage.SaveAttribute(attribute)
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteAttribute(attributeId string) {
|
||||
r.Storage.DeleteAttribute(attributeId)
|
||||
}
|
|
@ -11,33 +11,12 @@ type DB_Person struct {
|
|||
DisplayName string
|
||||
AccessKey string
|
||||
Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
|
||||
Loadout DB_Loadout `gorm:"foreignkey:PersonID"`
|
||||
}
|
||||
|
||||
func (DB_Person) TableName() string {
|
||||
return "Persons"
|
||||
}
|
||||
|
||||
type DB_Loadout struct {
|
||||
ID string `gorm:"primary_key"`
|
||||
PersonID string
|
||||
Character string
|
||||
Backpack string
|
||||
Pickaxe string
|
||||
Glider string
|
||||
Dances pq.StringArray `gorm:"type:text[]"`
|
||||
ItemWraps pq.StringArray `gorm:"type:text[]"`
|
||||
LoadingScreen string
|
||||
SkyDiveContrail string
|
||||
MusicPack string
|
||||
BannerIcon string
|
||||
BannerColor string
|
||||
}
|
||||
|
||||
func (DB_Loadout) TableName() string {
|
||||
return "Loadouts"
|
||||
}
|
||||
|
||||
type DB_Profile struct {
|
||||
ID string `gorm:"primary_key"`
|
||||
PersonID string
|
||||
|
|
Loading…
Reference in New Issue
Block a user