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
|
package aid
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
@ -10,4 +11,15 @@ func WaitForExit() {
|
||||||
sc := make(chan os.Signal, 1)
|
sc := make(chan os.Signal, 1)
|
||||||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||||
<-sc
|
<-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 (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
@ -22,6 +24,10 @@ type CS struct {
|
||||||
JWT struct {
|
JWT struct {
|
||||||
Secret string
|
Secret string
|
||||||
}
|
}
|
||||||
|
Fortnite struct {
|
||||||
|
Season int
|
||||||
|
Build float64
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -74,4 +80,28 @@ func LoadConfig() {
|
||||||
if Config.JWT.Secret == "" {
|
if Config.JWT.Secret == "" {
|
||||||
panic("JWT Secret is empty")
|
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")
|
||||||
|
}
|
|
@ -22,4 +22,8 @@ host="0.0.0.0"
|
||||||
|
|
||||||
[jwt]
|
[jwt]
|
||||||
; secret for jwt signing
|
; secret for jwt signing
|
||||||
secret="secret"
|
secret="secret"
|
||||||
|
|
||||||
|
[fortnite]
|
||||||
|
; the game build to use
|
||||||
|
build=2.5
|
|
@ -40,14 +40,14 @@ func PostOAuthToken(c *fiber.Ctx) error {
|
||||||
|
|
||||||
func PostOAuthTokenClientCredentials(c *fiber.Ctx, body *OAuthTokenBody) error {
|
func PostOAuthTokenClientCredentials(c *fiber.Ctx, body *OAuthTokenBody) error {
|
||||||
credentials, err := aid.JWTSign(aid.JSON{
|
credentials, err := aid.JWTSign(aid.JSON{
|
||||||
"snow_id": 0, // custom
|
"snow_id": 0, // custom
|
||||||
"t": "s",
|
"t": "s",
|
||||||
"am": "client_credentials", // authorization method
|
"am": "client_credentials", // authorization method
|
||||||
"ic": true, // internal client
|
"ic": true, // internal client
|
||||||
"mver": false, // mobile version
|
"mver": false, // mobile version
|
||||||
"clsvc": "snow", // client service
|
"clsvc": "snow", // client service
|
||||||
"clid": c.IP(), // client id
|
"clid": c.IP(), // client id
|
||||||
"jti": rand.Int63(), // jwt id
|
"jti": rand.Int63(), // jwt id
|
||||||
"p": base64.StdEncoding.EncodeToString([]byte(c.IP())), // payload
|
"p": base64.StdEncoding.EncodeToString([]byte(c.IP())), // payload
|
||||||
"hours_expire": 1,
|
"hours_expire": 1,
|
||||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||||
|
@ -86,20 +86,20 @@ func PostOAuthTokenPassword(c *fiber.Ctx, body *OAuthTokenBody) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
access, err := aid.JWTSign(aid.JSON{
|
access, err := aid.JWTSign(aid.JSON{
|
||||||
"snow_id": person.ID, // custom
|
"snow_id": person.ID, // custom
|
||||||
"iai": person.ID, // account id
|
"iai": person.ID, // account id
|
||||||
"dn": person.DisplayName, // display name
|
"dn": person.DisplayName, // display name
|
||||||
"t": "s",
|
"t": "s",
|
||||||
"am": "password", // authorization method
|
"am": "password", // authorization method
|
||||||
"ic": true, // internal client
|
"ic": true, // internal client
|
||||||
"mver": false, // mobile version
|
"mver": false, // mobile version
|
||||||
"clsvc": "snow", // client service
|
"clsvc": "snow", // client service
|
||||||
"app": "com.epicgames.fortnite", // app name
|
"app": "com.epicgames.fortnite", // app name
|
||||||
"clid": c.IP(), // client id
|
"clid": c.IP(), // client id
|
||||||
"dvid": "default", // device id
|
"dvid": "default", // device id
|
||||||
"jti": rand.Int63(), // jwt id
|
"jti": rand.Int63(), // jwt id
|
||||||
"p": base64.StdEncoding.EncodeToString([]byte(c.IP())), // payload
|
"p": base64.StdEncoding.EncodeToString([]byte(c.IP())), // payload
|
||||||
"sec": 1, // security level
|
"sec": 1, // security level
|
||||||
"hours_expire": 24,
|
"hours_expire": 24,
|
||||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||||
})
|
})
|
||||||
|
@ -108,12 +108,12 @@ func PostOAuthTokenPassword(c *fiber.Ctx, body *OAuthTokenBody) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh, err := aid.JWTSign(aid.JSON{
|
refresh, err := aid.JWTSign(aid.JSON{
|
||||||
"snow_id": person.ID, // custom
|
"snow_id": person.ID, // custom
|
||||||
"sub": person.ID, // account id
|
"sub": person.ID, // account id
|
||||||
"clid": c.IP(), // client id
|
"clid": c.IP(), // client id
|
||||||
"jti": rand.Int63(), // jwt id
|
"jti": rand.Int63(), // jwt id
|
||||||
"t": "s",
|
"t": "s",
|
||||||
"am": "refresh_token", // authorization method
|
"am": "refresh_token", // authorization method
|
||||||
"hours_expire": 24,
|
"hours_expire": 24,
|
||||||
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
"creation_date": time.Now().Format("2006-01-02T15:04:05.999Z"),
|
||||||
})
|
})
|
||||||
|
|
|
@ -33,4 +33,46 @@ func GetVersionCheck(c *fiber.Ctx) error {
|
||||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||||
"type": "NO_UPDATE",
|
"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
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
)
|
)
|
||||||
|
@ -11,4 +14,51 @@ func GetLightswitchBulkStatus(c *fiber.Ctx) error {
|
||||||
"status": "UP",
|
"status": "UP",
|
||||||
"banned": false,
|
"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
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
|
@ -13,6 +15,8 @@ var (
|
||||||
profileActions = map[string]func(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
profileActions = map[string]func(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||||
"QueryProfile": PostQueryProfileAction,
|
"QueryProfile": PostQueryProfileAction,
|
||||||
"ClientQuestLogin": PostQueryProfileAction,
|
"ClientQuestLogin": PostQueryProfileAction,
|
||||||
|
"MarkItemSeen": PostMarkItemSeenAction,
|
||||||
|
"EquipBattleRoyaleCustomization": PostEquipBattleRoyaleCustomizationAction,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,27 +25,33 @@ func PostProfileAction(c *fiber.Ctx) error {
|
||||||
if person == nil {
|
if person == nil {
|
||||||
return c.Status(404).JSON(aid.ErrorBadRequest("No Account Found"))
|
return c.Status(404).JSON(aid.ErrorBadRequest("No Account Found"))
|
||||||
}
|
}
|
||||||
|
defer person.Save()
|
||||||
|
|
||||||
profile := person.GetProfileFromType(c.Query("profileId"))
|
profile := person.GetProfileFromType(c.Query("profileId"))
|
||||||
if profile == nil {
|
defer profile.ClearProfileChanges()
|
||||||
return c.Status(404).JSON(aid.ErrorBadRequest("No Profile Found"))
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshot := profile.Snapshot()
|
before := profile.Snapshot()
|
||||||
if action, ok := profileActions[c.Params("action")]; ok {
|
if action, ok := profileActions[c.Params("action")]; ok {
|
||||||
err := action(c, person, profile)
|
if err := action(c, person, profile); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profile.Diff(snapshot)
|
changes := profile.Diff(before)
|
||||||
profile.Revision++
|
|
||||||
|
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{
|
return c.Status(200).JSON(aid.JSON{
|
||||||
"profileId": profile.Type,
|
"profileId": profile.Type,
|
||||||
"profileRevision": profile.Revision,
|
"profileRevision": revision,
|
||||||
"profileCommandRevision": profile.Revision,
|
"profileCommandRevision": revision,
|
||||||
"profileChangesBaseRevision": profile.Revision - 1,
|
"profileChangesBaseRevision": revision - 1,
|
||||||
"profileChanges": profile.Changes,
|
"profileChanges": profile.Changes,
|
||||||
"multiUpdate": []aid.JSON{},
|
"multiUpdate": []aid.JSON{},
|
||||||
"notifications": []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 {
|
func PostQueryProfileAction(c *fiber.Ctx, person *p.Person, profile *p.Profile) error {
|
||||||
profile.Changes = []interface{}{}
|
|
||||||
profile.CreateFullProfileUpdateChange()
|
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
|
return nil
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ func GetCloudStorageConfig(c *fiber.Ctx) error {
|
||||||
"epicAppName": "Live",
|
"epicAppName": "Live",
|
||||||
"isAuthenticated": true,
|
"isAuthenticated": true,
|
||||||
"disableV2": true,
|
"disableV2": true,
|
||||||
"lastUpdated": "2021-01-01T00:00:00Z",
|
"lastUpdated": "0000-00-00T00:00:00.000Z",
|
||||||
"transports": []string{},
|
"transports": []string{},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -28,5 +28,17 @@ func GetCloudStorageFile(c *fiber.Ctx) error {
|
||||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest)
|
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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{})
|
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_Person{}, "Persons")
|
||||||
postgresStorage.Migrate(&storage.DB_Loadout{}, "Loadouts")
|
|
||||||
postgresStorage.Migrate(&storage.DB_Profile{}, "Profiles")
|
postgresStorage.Migrate(&storage.DB_Profile{}, "Profiles")
|
||||||
postgresStorage.Migrate(&storage.DB_Item{}, "Items")
|
postgresStorage.Migrate(&storage.DB_Item{}, "Items")
|
||||||
postgresStorage.Migrate(&storage.DB_Gift{}, "Gifts")
|
postgresStorage.Migrate(&storage.DB_Gift{}, "Gifts")
|
||||||
|
@ -35,12 +34,11 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
storage.Repo = storage.NewStorage(device)
|
storage.Repo = storage.NewStorage(device)
|
||||||
storage.Cache = storage.NewPersonsCacheMutex()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if aid.Config.Database.DropAllTables {
|
if aid.Config.Database.DropAllTables {
|
||||||
person.NewFortnitePerson("ac", "ket")
|
person.NewFortnitePerson("ac", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
aid.PrintTime("Loading all persons from database", func() {
|
aid.PrintTime("Loading all persons from database", func() {
|
||||||
|
@ -49,7 +47,7 @@ func init() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
go storage.Cache.CacheKiller()
|
// go storage.Cache.CacheKiller()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -59,6 +57,8 @@ func main() {
|
||||||
r.Use(aid.FiberLimiter())
|
r.Use(aid.FiberLimiter())
|
||||||
r.Use(aid.FiberCors())
|
r.Use(aid.FiberCors())
|
||||||
|
|
||||||
|
r.Get("/content/api/pages/fortnite-game", handlers.GetContentPages)
|
||||||
|
|
||||||
account := r.Group("/account/api")
|
account := r.Group("/account/api")
|
||||||
account.Get("/public/account/:accountId", handlers.GetPublicAccount)
|
account.Get("/public/account/:accountId", handlers.GetPublicAccount)
|
||||||
account.Get("/public/account/:accountId/externalAuths", handlers.GetPublicAccountExternalAuths)
|
account.Get("/public/account/:accountId/externalAuths", handlers.GetPublicAccountExternalAuths)
|
||||||
|
@ -68,6 +68,7 @@ func main() {
|
||||||
fortnite := r.Group("/fortnite/api")
|
fortnite := r.Group("/fortnite/api")
|
||||||
fortnite.Get("/receipts/v1/account/:accountId/receipts", handlers.GetAccountReceipts)
|
fortnite.Get("/receipts/v1/account/:accountId/receipts", handlers.GetAccountReceipts)
|
||||||
fortnite.Get("/versioncheck/*", handlers.GetVersionCheck)
|
fortnite.Get("/versioncheck/*", handlers.GetVersionCheck)
|
||||||
|
fortnite.Get("/calendar/v1/timeline", handlers.GetTimelineCalendar)
|
||||||
|
|
||||||
matchmaking := fortnite.Group("/matchmaking")
|
matchmaking := fortnite.Group("/matchmaking")
|
||||||
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetSessionFindPlayer)
|
matchmaking.Get("/session/findPlayer/:accountId", handlers.GetSessionFindPlayer)
|
||||||
|
@ -76,6 +77,9 @@ func main() {
|
||||||
storage.Get("/system", handlers.GetCloudStorageFiles)
|
storage.Get("/system", handlers.GetCloudStorageFiles)
|
||||||
storage.Get("/system/config", handlers.GetCloudStorageConfig)
|
storage.Get("/system/config", handlers.GetCloudStorageConfig)
|
||||||
storage.Get("/system/:fileName", handlers.GetCloudStorageFile)
|
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 := fortnite.Group("/game/v2")
|
||||||
game.Post("/tryPlayOnPlatform/account/:accountId", handlers.PostTryPlayOnPlatform)
|
game.Post("/tryPlayOnPlatform/account/:accountId", handlers.PostTryPlayOnPlatform)
|
||||||
|
|
|
@ -1,59 +1,58 @@
|
||||||
package person
|
package person
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/ectrc/snow/aid"
|
||||||
"github.com/ectrc/snow/storage"
|
"github.com/ectrc/snow/storage"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Attribute struct {
|
type Attribute struct {
|
||||||
ID string
|
ID string
|
||||||
Key string
|
ProfileID string
|
||||||
Value interface{}
|
Key string
|
||||||
|
ValueJSON string
|
||||||
Type string
|
Type string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAttribute(key string, value interface{}) *Attribute {
|
func NewAttribute(key string, value interface{}) *Attribute {
|
||||||
return &Attribute{
|
return &Attribute{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
Key: key,
|
Key: key,
|
||||||
Value: value,
|
ValueJSON: aid.JSONStringify(value),
|
||||||
Type: reflect.TypeOf(value).String(),
|
Type: reflect.TypeOf(value).String(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromDatabaseAttribute(db *storage.DB_PAttribute) *Attribute {
|
func FromDatabaseAttribute(db *storage.DB_PAttribute) *Attribute {
|
||||||
var value interface{}
|
|
||||||
err := json.Unmarshal([]byte(db.ValueJSON), &value)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Attribute{
|
return &Attribute{
|
||||||
ID: db.ID,
|
ID: db.ID,
|
||||||
Key: db.Key,
|
ProfileID: db.ProfileID,
|
||||||
Value: value,
|
Key: db.Key,
|
||||||
Type: db.Type,
|
ValueJSON: db.ValueJSON,
|
||||||
|
Type: db.Type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Attribute) ToDatabase(profileId string) *storage.DB_PAttribute {
|
func (a *Attribute) ToDatabase(profileId string) *storage.DB_PAttribute {
|
||||||
value, err := json.Marshal(a.Value)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &storage.DB_PAttribute{
|
return &storage.DB_PAttribute{
|
||||||
ID: a.ID,
|
ID: a.ID,
|
||||||
ProfileID: profileId,
|
ProfileID: profileId,
|
||||||
Key: a.Key,
|
Key: a.Key,
|
||||||
ValueJSON: string(value),
|
ValueJSON: a.ValueJSON,
|
||||||
Type: a.Type,
|
Type: a.Type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Attribute) Delete() {
|
func (a *Attribute) Delete() {
|
||||||
storage.Repo.DeleteAttribute(a.ID)
|
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 (
|
import (
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cache *PersonsCache
|
||||||
|
)
|
||||||
|
|
||||||
type CacheEntry struct {
|
type CacheEntry struct {
|
||||||
Entry interface{}
|
Entry *Person
|
||||||
LastAccessed time.Time
|
LastAccessed time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,15 +25,15 @@ func NewPersonsCacheMutex() *PersonsCache {
|
||||||
|
|
||||||
func (m *PersonsCache) CacheKiller() {
|
func (m *PersonsCache) CacheKiller() {
|
||||||
for {
|
for {
|
||||||
if Cache.Count() == 0 {
|
if m.Count() == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache.Range(func(key, value interface{}) bool {
|
m.Range(func(key, value interface{}) bool {
|
||||||
cacheEntry := value.(*CacheEntry)
|
cacheEntry := value.(*CacheEntry)
|
||||||
|
|
||||||
if time.Since(cacheEntry.LastAccessed) >= 30 * time.Minute {
|
if time.Since(cacheEntry.LastAccessed) >= 30 * time.Minute {
|
||||||
Cache.Delete(key)
|
m.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
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 {
|
if p, ok := m.Load(id); ok {
|
||||||
|
fmt.Println("Cache hit", id)
|
||||||
cacheEntry := p.(*CacheEntry)
|
cacheEntry := p.(*CacheEntry)
|
||||||
return cacheEntry.Entry.(*DB_Person)
|
return cacheEntry.Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PersonsCache) GetPersonByDisplay(displayName string) *DB_Person {
|
func (m *PersonsCache) GetPersonByDisplay(displayName string) *Person {
|
||||||
var person *DB_Person
|
var person *Person
|
||||||
m.Range(func(key, value interface{}) bool {
|
m.RangeEntry(func(key string, value *CacheEntry) bool {
|
||||||
if value.(*CacheEntry).Entry.(*DB_Person).DisplayName == displayName {
|
if value.Entry.DisplayName == displayName {
|
||||||
person = value.(*CacheEntry).Entry.(*DB_Person)
|
person = value.Entry
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +67,7 @@ func (m *PersonsCache) GetPersonByDisplay(displayName string) *DB_Person {
|
||||||
return person
|
return person
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *PersonsCache) SavePerson(p *DB_Person) {
|
func (m *PersonsCache) SavePerson(p *Person) {
|
||||||
m.Store(p.ID, &CacheEntry{
|
m.Store(p.ID, &CacheEntry{
|
||||||
Entry: p,
|
Entry: p,
|
||||||
LastAccessed: time.Now(),
|
LastAccessed: time.Now(),
|
||||||
|
@ -72,9 +78,9 @@ func (m *PersonsCache) DeletePerson(id string) {
|
||||||
m.Delete(id)
|
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 {
|
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.DisplayName = displayName
|
||||||
person.AccessKey = key
|
person.AccessKey = key
|
||||||
|
|
||||||
character := NewItem("AthenaCharacter:CID_001_Athena_Commando_F_Default", 1)
|
person.AthenaProfile.Items.AddItem(NewItem("AthenaCharacter:CID_001_Athena_Commando_F_Default", 1))
|
||||||
pickaxe := NewItem("AthenaPickaxe:DefaultPickaxe", 1)
|
person.AthenaProfile.Items.AddItem(NewItem("AthenaCharacter:CID_032_Athena_Commando_M_Medieval", 1))
|
||||||
glider := NewItem("AthenaGlider:DefaultGlider", 1)
|
person.AthenaProfile.Items.AddItem(NewItem("AthenaCharacter:CID_033_Athena_Commando_F_Medieval", 1))
|
||||||
default_dance := NewItem("AthenaDance:EID_DanceMoves", 1)
|
person.AthenaProfile.Items.AddItem(NewItem("AthenaPickaxe:DefaultPickaxe", 1))
|
||||||
|
person.AthenaProfile.Items.AddItem(NewItem("AthenaGlider:DefaultGlider", 1))
|
||||||
person.AthenaProfile.Items.AddItem(character)
|
person.AthenaProfile.Items.AddItem(NewItem("AthenaDance:EID_DanceMoves", 1))
|
||||||
person.AthenaProfile.Items.AddItem(pickaxe)
|
|
||||||
person.AthenaProfile.Items.AddItem(glider)
|
|
||||||
person.AthenaProfile.Items.AddItem(default_dance)
|
|
||||||
person.CommonCoreProfile.Items.AddItem(NewItem("Currency:MtxPurchased", 0))
|
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("mfa_reward_claimed", true))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("rested_xp_overflow", 0))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("rested_xp_overflow", 0))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("lifetime_wins", 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("daily_rewards", []aid.JSON{}))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("competitive_identity", 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_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("permissions", []aid.JSON{}))
|
||||||
|
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("loadouts", []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_level", 1))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("book_xp", 0))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("book_xp", 0))
|
||||||
|
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_character", person.Loadout.Character))
|
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.Loadout.Backpack))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_backpack", ""))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_pickaxe", person.Loadout.Pickaxe))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_pickaxe", person.AthenaProfile.Items.GetItemByTemplateID("AthenaPickaxe:DefaultPickaxe").ID))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_glider", person.Loadout.Glider))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_glider", person.AthenaProfile.Items.GetItemByTemplateID("AthenaGlider:DefaultGlider").ID))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_skydivecontrail", person.Loadout.SkyDiveContrail))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_skydivecontrail", ""))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_dance", person.Loadout.Dances))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_dance", make([]string, 6)))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_itemwraps", person.Loadout.ItemWraps))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_itemwraps", make([]string, 7)))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_loadingscreen", person.Loadout.LoadingScreen))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_loadingscreen", ""))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_musicpack", person.Loadout.MusicPack))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("favorite_musicpack", ""))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_icon", person.Loadout.BannerIcon))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_icon", ""))
|
||||||
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_color", person.Loadout.BannerColor))
|
person.AthenaProfile.Attributes.AddAttribute(NewAttribute("banner_color", ""))
|
||||||
|
|
||||||
person.CommonCoreProfile.Attributes.AddAttribute(NewAttribute("mfa_enabled", true))
|
person.CommonCoreProfile.Attributes.AddAttribute(NewAttribute("mfa_enabled", true))
|
||||||
person.CommonCoreProfile.Attributes.AddAttribute(NewAttribute("mtx_affiliate", ""))
|
person.CommonCoreProfile.Attributes.AddAttribute(NewAttribute("mtx_affiliate", ""))
|
||||||
|
|
|
@ -9,24 +9,25 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Gift struct {
|
type Gift struct {
|
||||||
ID string
|
ID string
|
||||||
|
ProfileID string
|
||||||
TemplateID string
|
TemplateID string
|
||||||
Quantity int
|
Quantity int
|
||||||
FromID string
|
FromID string
|
||||||
GiftedAt int64
|
GiftedAt int64
|
||||||
Message string
|
Message string
|
||||||
Loot []*Item
|
Loot []*Item
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGift(templateID string, quantity int, fromID string, message string) *Gift {
|
func NewGift(templateID string, quantity int, fromID string, message string) *Gift {
|
||||||
return &Gift{
|
return &Gift{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
TemplateID: templateID,
|
TemplateID: templateID,
|
||||||
Quantity: quantity,
|
Quantity: quantity,
|
||||||
FromID: fromID,
|
FromID: fromID,
|
||||||
GiftedAt: time.Now().Unix(),
|
GiftedAt: time.Now().Unix(),
|
||||||
Message: message,
|
Message: message,
|
||||||
Loot: []*Item{},
|
Loot: []*Item{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,13 +39,14 @@ func FromDatabaseGift(gift *storage.DB_Gift) *Gift {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Gift{
|
return &Gift{
|
||||||
ID: gift.ID,
|
ID: gift.ID,
|
||||||
|
ProfileID: gift.ProfileID,
|
||||||
TemplateID: gift.TemplateID,
|
TemplateID: gift.TemplateID,
|
||||||
Quantity: gift.Quantity,
|
Quantity: gift.Quantity,
|
||||||
FromID: gift.FromID,
|
FromID: gift.FromID,
|
||||||
GiftedAt: gift.GiftedAt,
|
GiftedAt: gift.GiftedAt,
|
||||||
Message: gift.Message,
|
Message: gift.Message,
|
||||||
Loot: loot,
|
Loot: loot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,19 +103,24 @@ func (g *Gift) ToDatabase(profileId string) *storage.DB_Gift {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &storage.DB_Gift{
|
return &storage.DB_Gift{
|
||||||
|
ID: g.ID,
|
||||||
ProfileID: profileId,
|
ProfileID: profileId,
|
||||||
ID: g.ID,
|
|
||||||
TemplateID: g.TemplateID,
|
TemplateID: g.TemplateID,
|
||||||
Quantity: g.Quantity,
|
Quantity: g.Quantity,
|
||||||
FromID: g.FromID,
|
FromID: g.FromID,
|
||||||
GiftedAt: g.GiftedAt,
|
GiftedAt: g.GiftedAt,
|
||||||
Message: g.Message,
|
Message: g.Message,
|
||||||
Loot: profileLoot,
|
Loot: profileLoot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Gift) Save() {
|
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 {
|
func (g *Gift) Snapshot() GiftSnapshot {
|
||||||
|
@ -124,12 +131,12 @@ func (g *Gift) Snapshot() GiftSnapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
return GiftSnapshot{
|
return GiftSnapshot{
|
||||||
ID: g.ID,
|
ID: g.ID,
|
||||||
TemplateID: g.TemplateID,
|
TemplateID: g.TemplateID,
|
||||||
Quantity: g.Quantity,
|
Quantity: g.Quantity,
|
||||||
FromID: g.FromID,
|
FromID: g.FromID,
|
||||||
GiftedAt: g.GiftedAt,
|
GiftedAt: g.GiftedAt,
|
||||||
Message: g.Message,
|
Message: g.Message,
|
||||||
Loot: loot,
|
Loot: loot,
|
||||||
}
|
}
|
||||||
}
|
}
|
109
person/item.go
109
person/item.go
|
@ -7,39 +7,40 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
ID string
|
ID string
|
||||||
TemplateID string
|
ProfileID string
|
||||||
Quantity int
|
TemplateID string
|
||||||
Favorite bool
|
Quantity int
|
||||||
HasSeen bool
|
Favorite bool
|
||||||
Variants []*VariantChannel
|
HasSeen bool
|
||||||
|
Variants []*VariantChannel
|
||||||
ProfileType string
|
ProfileType string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewItem(templateID string, quantity int) *Item {
|
func NewItem(templateID string, quantity int) *Item {
|
||||||
return &Item{
|
return &Item{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
TemplateID: templateID,
|
TemplateID: templateID,
|
||||||
Quantity: quantity,
|
Quantity: quantity,
|
||||||
Favorite: false,
|
Favorite: false,
|
||||||
HasSeen: false,
|
HasSeen: false,
|
||||||
Variants: []*VariantChannel{},
|
Variants: []*VariantChannel{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewItemWithType(templateID string, quantity int, profile string) *Item {
|
func NewItemWithType(templateID string, quantity int, profile string) *Item {
|
||||||
return &Item{
|
return &Item{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
TemplateID: templateID,
|
TemplateID: templateID,
|
||||||
Quantity: quantity,
|
Quantity: quantity,
|
||||||
Favorite: false,
|
Favorite: false,
|
||||||
HasSeen: false,
|
HasSeen: false,
|
||||||
Variants: []*VariantChannel{},
|
Variants: []*VariantChannel{},
|
||||||
ProfileType: profile,
|
ProfileType: profile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromDatabaseItem(item *storage.DB_Item, profileType *string) *Item {
|
func FromDatabaseItem(item *storage.DB_Item) *Item {
|
||||||
variants := []*VariantChannel{}
|
variants := []*VariantChannel{}
|
||||||
|
|
||||||
for _, variant := range item.Variants {
|
for _, variant := range item.Variants {
|
||||||
|
@ -47,13 +48,12 @@ func FromDatabaseItem(item *storage.DB_Item, profileType *string) *Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Item{
|
return &Item{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
TemplateID: item.TemplateID,
|
TemplateID: item.TemplateID,
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
Favorite: item.Favorite,
|
Favorite: item.Favorite,
|
||||||
HasSeen: item.HasSeen,
|
HasSeen: item.HasSeen,
|
||||||
Variants: variants,
|
Variants: variants,
|
||||||
ProfileType: *profileType,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,10 +114,10 @@ func (i *Item) DeleteLoot() {
|
||||||
|
|
||||||
func (i *Item) NewChannel(channel string, owned []string, active string) *VariantChannel {
|
func (i *Item) NewChannel(channel string, owned []string, active string) *VariantChannel {
|
||||||
return &VariantChannel{
|
return &VariantChannel{
|
||||||
ItemID: i.ID,
|
ItemID: i.ID,
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
Owned: owned,
|
Owned: owned,
|
||||||
Active: active,
|
Active: active,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,27 +160,32 @@ func (i *Item) ToDatabase(profileId string) *storage.DB_Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &storage.DB_Item{
|
return &storage.DB_Item{
|
||||||
ProfileID: profileId,
|
ProfileID: profileId,
|
||||||
ID: i.ID,
|
ID: i.ID,
|
||||||
TemplateID: i.TemplateID,
|
TemplateID: i.TemplateID,
|
||||||
Quantity: i.Quantity,
|
Quantity: i.Quantity,
|
||||||
Favorite: i.Favorite,
|
Favorite: i.Favorite,
|
||||||
HasSeen: i.HasSeen,
|
HasSeen: i.HasSeen,
|
||||||
Variants: variants,
|
Variants: variants,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Item) Save() {
|
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 {
|
func (i *Item) ToLootDatabase(giftId string) *storage.DB_Loot {
|
||||||
return &storage.DB_Loot{
|
return &storage.DB_Loot{
|
||||||
GiftID: giftId,
|
GiftID: giftId,
|
||||||
ProfileType: i.ProfileType,
|
ProfileType: i.ProfileType,
|
||||||
ID: i.ID,
|
ID: i.ID,
|
||||||
TemplateID: i.TemplateID,
|
TemplateID: i.TemplateID,
|
||||||
Quantity: i.Quantity,
|
Quantity: i.Quantity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,12 +201,12 @@ func (i *Item) Snapshot() ItemSnapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ItemSnapshot{
|
return ItemSnapshot{
|
||||||
ID: i.ID,
|
ID: i.ID,
|
||||||
TemplateID: i.TemplateID,
|
TemplateID: i.TemplateID,
|
||||||
Quantity: i.Quantity,
|
Quantity: i.Quantity,
|
||||||
Favorite: i.Favorite,
|
Favorite: i.Favorite,
|
||||||
HasSeen: i.HasSeen,
|
HasSeen: i.HasSeen,
|
||||||
Variants: variants,
|
Variants: variants,
|
||||||
ProfileType: i.ProfileType,
|
ProfileType: i.ProfileType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,21 +221,21 @@ type VariantChannel struct {
|
||||||
|
|
||||||
func FromDatabaseVariant(variant *storage.DB_VariantChannel) *VariantChannel {
|
func FromDatabaseVariant(variant *storage.DB_VariantChannel) *VariantChannel {
|
||||||
return &VariantChannel{
|
return &VariantChannel{
|
||||||
ID: variant.ID,
|
ID: variant.ID,
|
||||||
ItemID: variant.ItemID,
|
ItemID: variant.ItemID,
|
||||||
Channel: variant.Channel,
|
Channel: variant.Channel,
|
||||||
Owned: variant.Owned,
|
Owned: variant.Owned,
|
||||||
Active: variant.Active,
|
Active: variant.Active,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VariantChannel) ToDatabase() *storage.DB_VariantChannel {
|
func (v *VariantChannel) ToDatabase() *storage.DB_VariantChannel {
|
||||||
return &storage.DB_VariantChannel{
|
return &storage.DB_VariantChannel{
|
||||||
ID: v.ID,
|
ID: v.ID,
|
||||||
ItemID: v.ItemID,
|
ItemID: v.ItemID,
|
||||||
Channel: v.Channel,
|
Channel: v.Channel,
|
||||||
Owned: v.Owned,
|
Owned: v.Owned,
|
||||||
Active: v.Active,
|
Active: v.Active,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
103
person/person.go
103
person/person.go
|
@ -1,19 +1,20 @@
|
||||||
package person
|
package person
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ectrc/snow/storage"
|
"github.com/ectrc/snow/storage"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
ID string
|
ID string
|
||||||
DisplayName string
|
DisplayName string
|
||||||
AccessKey string
|
AccessKey string
|
||||||
AthenaProfile *Profile
|
AthenaProfile *Profile
|
||||||
CommonCoreProfile *Profile
|
CommonCoreProfile *Profile
|
||||||
CommonPublicProfile *Profile
|
CommonPublicProfile *Profile
|
||||||
Profile0 *Profile
|
Profile0 *Profile
|
||||||
Loadout *Loadout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
|
@ -30,69 +31,52 @@ func NewPerson() *Person {
|
||||||
CommonCoreProfile: NewProfile("common_core"),
|
CommonCoreProfile: NewProfile("common_core"),
|
||||||
CommonPublicProfile: NewProfile("common_public"),
|
CommonPublicProfile: NewProfile("common_public"),
|
||||||
Profile0: NewProfile("profile0"),
|
Profile0: NewProfile("profile0"),
|
||||||
Loadout: NewLoadout(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Find(personId string) *Person {
|
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 {
|
if person == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
loadout := FromDatabaseLoadout(&person.Loadout)
|
return findHelper(person)
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindByDisplay(displayName string) *Person {
|
func FindByDisplay(displayName string) *Person {
|
||||||
person := storage.Repo.GetPersonByDisplay(displayName)
|
if cache == nil {
|
||||||
|
cache = NewPersonsCacheMutex()
|
||||||
|
}
|
||||||
|
|
||||||
|
person := storage.Repo.GetPersonByDisplayFromDB(displayName)
|
||||||
if person == nil {
|
if person == nil {
|
||||||
return 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")
|
athenaProfile := NewProfile("athena")
|
||||||
commonCoreProfile := NewProfile("common_core")
|
commonCoreProfile := NewProfile("common_core")
|
||||||
commonPublicProfile := NewProfile("common_public")
|
commonPublicProfile := NewProfile("common_public")
|
||||||
profile0 := NewProfile("profile0")
|
profile0 := NewProfile("profile0")
|
||||||
|
|
||||||
for _, profile := range person.Profiles {
|
for _, profile := range databasePerson.Profiles {
|
||||||
if profile.Type == "athena" {
|
if profile.Type == "athena" {
|
||||||
athenaProfile.ID = profile.ID
|
athenaProfile.ID = profile.ID
|
||||||
athenaProfile = FromDatabaseProfile(&profile)
|
athenaProfile = FromDatabaseProfile(&profile)
|
||||||
|
@ -113,17 +97,23 @@ func FindByDisplay(displayName string) *Person {
|
||||||
profile0 = FromDatabaseProfile(&profile)
|
profile0 = FromDatabaseProfile(&profile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Person{
|
person := &Person{
|
||||||
ID: person.ID,
|
ID: databasePerson.ID,
|
||||||
DisplayName: person.DisplayName,
|
DisplayName: databasePerson.DisplayName,
|
||||||
AccessKey: person.AccessKey,
|
AccessKey: databasePerson.AccessKey,
|
||||||
AthenaProfile: athenaProfile,
|
AthenaProfile: athenaProfile,
|
||||||
CommonCoreProfile: commonCoreProfile,
|
CommonCoreProfile: commonCoreProfile,
|
||||||
CommonPublicProfile: commonPublicProfile,
|
CommonPublicProfile: commonPublicProfile,
|
||||||
Profile0: profile0,
|
Profile0: profile0,
|
||||||
Loadout: loadout,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache.Store(person.ID, &CacheEntry{
|
||||||
|
Entry: person,
|
||||||
|
LastAccessed: time.Now(),
|
||||||
|
})
|
||||||
|
|
||||||
|
return person
|
||||||
}
|
}
|
||||||
|
|
||||||
func AllFromDatabase() []*Person {
|
func AllFromDatabase() []*Person {
|
||||||
|
@ -152,7 +142,8 @@ func (p *Person) GetProfileFromType(profileType string) *Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Person) Save() {
|
func (p *Person) Save() {
|
||||||
storage.Repo.SavePerson(p.ToDatabase())
|
dbPerson := p.ToDatabase()
|
||||||
|
storage.Repo.SavePerson(dbPerson)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Person) ToDatabase() *storage.DB_Person {
|
func (p *Person) ToDatabase() *storage.DB_Person {
|
||||||
|
@ -160,7 +151,6 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
||||||
ID: p.ID,
|
ID: p.ID,
|
||||||
DisplayName: p.DisplayName,
|
DisplayName: p.DisplayName,
|
||||||
Profiles: []storage.DB_Profile{},
|
Profiles: []storage.DB_Profile{},
|
||||||
Loadout: *p.Loadout.ToDatabase(),
|
|
||||||
AccessKey: p.AccessKey,
|
AccessKey: p.AccessKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +168,9 @@ func (p *Person) ToDatabase() *storage.DB_Person {
|
||||||
Type: profileType,
|
Type: profileType,
|
||||||
Items: []storage.DB_Item{},
|
Items: []storage.DB_Item{},
|
||||||
Gifts: []storage.DB_Gift{},
|
Gifts: []storage.DB_Gift{},
|
||||||
|
Quests: []storage.DB_Quest{},
|
||||||
Attributes: []storage.DB_PAttribute{},
|
Attributes: []storage.DB_PAttribute{},
|
||||||
|
Revision: profile.Revision,
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.Items.RangeItems(func(id string, item *Item) bool {
|
profile.Items.RangeItems(func(id string, item *Item) bool {
|
||||||
|
@ -225,7 +217,6 @@ func (p *Person) Snapshot() *PersonSnapshot {
|
||||||
ID: p.ID,
|
ID: p.ID,
|
||||||
DisplayName: p.DisplayName,
|
DisplayName: p.DisplayName,
|
||||||
AthenaProfile: *p.AthenaProfile.Snapshot(),
|
AthenaProfile: *p.AthenaProfile.Snapshot(),
|
||||||
CommonCoreProfile:* p.CommonCoreProfile.Snapshot(),
|
CommonCoreProfile: *p.CommonCoreProfile.Snapshot(),
|
||||||
Loadout: *p.Loadout,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,10 +10,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Profile struct {
|
type Profile struct {
|
||||||
ID string
|
ID string
|
||||||
PersonID string
|
PersonID string
|
||||||
Items *ItemMutex
|
Items *ItemMutex
|
||||||
Gifts *GiftMutex
|
Gifts *GiftMutex
|
||||||
Quests *QuestMutex
|
Quests *QuestMutex
|
||||||
Attributes *AttributeMutex
|
Attributes *AttributeMutex
|
||||||
Type string
|
Type string
|
||||||
|
@ -22,27 +22,28 @@ type Profile struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProfile(profile string) *Profile {
|
func NewProfile(profile string) *Profile {
|
||||||
|
id := uuid.New().String()
|
||||||
return &Profile{
|
return &Profile{
|
||||||
ID: uuid.New().String(),
|
ID: id,
|
||||||
PersonID: "",
|
PersonID: "",
|
||||||
Items: NewItemMutex(profile),
|
Items: NewItemMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||||
Gifts: NewGiftMutex(),
|
Gifts: NewGiftMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||||
Quests: NewQuestMutex(),
|
Quests: NewQuestMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||||
Attributes: NewAttributeMutex(),
|
Attributes: NewAttributeMutex(&storage.DB_Profile{ID: id, Type: profile}),
|
||||||
Type: profile,
|
Type: profile,
|
||||||
Revision: 0,
|
Revision: 0,
|
||||||
Changes: []interface{}{},
|
Changes: []interface{}{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
||||||
items := NewItemMutex(profile.Type)
|
items := NewItemMutex(profile)
|
||||||
gifts := NewGiftMutex()
|
gifts := NewGiftMutex(profile)
|
||||||
quests := NewQuestMutex()
|
quests := NewQuestMutex(profile)
|
||||||
attributes := NewAttributeMutex()
|
attributes := NewAttributeMutex(profile)
|
||||||
|
|
||||||
for _, item := range profile.Items {
|
for _, item := range profile.Items {
|
||||||
items.AddItem(FromDatabaseItem(&item, &profile.Type))
|
items.AddItem(FromDatabaseItem(&item))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, gift := range profile.Gifts {
|
for _, gift := range profile.Gifts {
|
||||||
|
@ -50,7 +51,7 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, quest := range profile.Quests {
|
for _, quest := range profile.Quests {
|
||||||
quests.AddQuest(FromDatabaseQuest(&quest, &profile.Type))
|
quests.AddQuest(FromDatabaseQuest(&quest))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, attribute := range profile.Attributes {
|
for _, attribute := range profile.Attributes {
|
||||||
|
@ -64,14 +65,15 @@ func FromDatabaseProfile(profile *storage.DB_Profile) *Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Profile{
|
return &Profile{
|
||||||
ID: profile.ID,
|
ID: profile.ID,
|
||||||
PersonID: profile.PersonID,
|
PersonID: profile.PersonID,
|
||||||
Items: items,
|
Items: items,
|
||||||
Gifts: gifts,
|
Gifts: gifts,
|
||||||
Quests: quests,
|
Quests: quests,
|
||||||
Attributes: attributes,
|
Attributes: attributes,
|
||||||
Type: profile.Type,
|
Type: profile.Type,
|
||||||
Revision: profile.Revision,
|
Revision: profile.Revision,
|
||||||
|
Changes: []interface{}{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +97,7 @@ func (p *Profile) GenerateFortniteProfileEntry() aid.JSON {
|
||||||
})
|
})
|
||||||
|
|
||||||
p.Attributes.RangeAttributes(func(id string, attribute *Attribute) bool {
|
p.Attributes.RangeAttributes(func(id string, attribute *Attribute) bool {
|
||||||
attributes[attribute.Key] = attribute.Value
|
attributes[attribute.Key] = aid.JSONParse(attribute.ValueJSON)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -114,7 +116,7 @@ func (p *Profile) GenerateFortniteProfileEntry() aid.JSON {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Profile) Save() {
|
func (p *Profile) Save() {
|
||||||
//storage.Repo.SaveProfile(p.ToDatabase())
|
// storage.Repo.SaveProfile(p.ToDatabase())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Profile) Snapshot() *ProfileSnapshot {
|
func (p *Profile) Snapshot() *ProfileSnapshot {
|
||||||
|
@ -144,18 +146,18 @@ func (p *Profile) Snapshot() *ProfileSnapshot {
|
||||||
})
|
})
|
||||||
|
|
||||||
return &ProfileSnapshot{
|
return &ProfileSnapshot{
|
||||||
ID: p.ID,
|
ID: p.ID,
|
||||||
Items: items,
|
Items: items,
|
||||||
Gifts: gifts,
|
Gifts: gifts,
|
||||||
Quests: quests,
|
Quests: quests,
|
||||||
Attributes: attributes,
|
Attributes: attributes,
|
||||||
Type: p.Type,
|
Type: p.Type,
|
||||||
Revision: p.Revision,
|
Revision: p.Revision,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
func (p *Profile) Diff(b *ProfileSnapshot) []diff.Change {
|
||||||
changes, err := diff.Diff(snapshot, p.Snapshot())
|
changes, err := diff.Diff(*b, *p.Snapshot())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error diffing profile: %v\n", err)
|
fmt.Printf("error diffing profile: %v\n", err)
|
||||||
return nil
|
return nil
|
||||||
|
@ -200,7 +202,7 @@ func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
||||||
p.CreateStatModifiedChange(p.Attributes.GetAttribute(change.Path[1]))
|
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]))
|
p.CreateStatModifiedChange(p.Attributes.GetAttribute(change.Path[1]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,6 +211,11 @@ func (p *Profile) Diff(snapshot *ProfileSnapshot) []diff.Change {
|
||||||
return changes
|
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) {
|
func (p *Profile) CreateStatModifiedChange(attribute *Attribute) {
|
||||||
if attribute == nil {
|
if attribute == nil {
|
||||||
fmt.Println("error getting attribute from profile", attribute.ID)
|
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{
|
p.Changes = append(p.Changes, StatModified{
|
||||||
ChangeType: "statModified",
|
ChangeType: "statModified",
|
||||||
Name: attribute.Key,
|
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() {
|
func (p *Profile) CreateFullProfileUpdateChange() {
|
||||||
p.Changes = append(p.Changes, FullProfileUpdate{
|
p.Changes = []interface{}{FullProfileUpdate{
|
||||||
ChangeType: "fullProfileUpdate",
|
ChangeType: "fullProfileUpdate",
|
||||||
Profile: p.GenerateFortniteProfileEntry(),
|
Profile: p.GenerateFortniteProfileEntry(),
|
||||||
})
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Loadout struct {
|
func (p *Profile) ClearProfileChanges() {
|
||||||
ID string
|
p.Changes = []interface{}{}
|
||||||
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())
|
|
||||||
}
|
}
|
|
@ -7,46 +7,48 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Quest struct {
|
type Quest struct {
|
||||||
ID string
|
ID string
|
||||||
TemplateID string
|
ProfileID string
|
||||||
State string
|
TemplateID string
|
||||||
Objectives []string
|
State string
|
||||||
|
Objectives []string
|
||||||
ObjectiveCounts []int64
|
ObjectiveCounts []int64
|
||||||
BundleID string
|
BundleID string
|
||||||
ScheduleID string
|
ScheduleID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQuest(templateID string, bundleID string, scheduleID string) *Quest {
|
func NewQuest(templateID string, bundleID string, scheduleID string) *Quest {
|
||||||
return &Quest{
|
return &Quest{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
TemplateID: templateID,
|
TemplateID: templateID,
|
||||||
State: "Active",
|
State: "Active",
|
||||||
Objectives: []string{},
|
Objectives: []string{},
|
||||||
ObjectiveCounts: []int64{},
|
ObjectiveCounts: []int64{},
|
||||||
BundleID: bundleID,
|
BundleID: bundleID,
|
||||||
ScheduleID: scheduleID,
|
ScheduleID: scheduleID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDailyQuest(templateID string) *Quest {
|
func NewDailyQuest(templateID string) *Quest {
|
||||||
return &Quest{
|
return &Quest{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
TemplateID: templateID,
|
TemplateID: templateID,
|
||||||
State: "Active",
|
State: "Active",
|
||||||
Objectives: []string{},
|
Objectives: []string{},
|
||||||
ObjectiveCounts: []int64{},
|
ObjectiveCounts: []int64{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromDatabaseQuest(quest *storage.DB_Quest, profileType *string) *Quest {
|
func FromDatabaseQuest(quest *storage.DB_Quest) *Quest {
|
||||||
return &Quest{
|
return &Quest{
|
||||||
ID: quest.ID,
|
ID: quest.ID,
|
||||||
TemplateID: quest.TemplateID,
|
ProfileID: quest.ProfileID,
|
||||||
State: quest.State,
|
TemplateID: quest.TemplateID,
|
||||||
Objectives: quest.Objectives,
|
State: quest.State,
|
||||||
|
Objectives: quest.Objectives,
|
||||||
ObjectiveCounts: quest.ObjectiveCounts,
|
ObjectiveCounts: quest.ObjectiveCounts,
|
||||||
BundleID: quest.BundleID,
|
BundleID: quest.BundleID,
|
||||||
ScheduleID: quest.ScheduleID,
|
ScheduleID: quest.ScheduleID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,17 +128,17 @@ func (q *Quest) RemoveObjective(objective string) {
|
||||||
|
|
||||||
func (q *Quest) ToDatabase(profileId string) *storage.DB_Quest {
|
func (q *Quest) ToDatabase(profileId string) *storage.DB_Quest {
|
||||||
return &storage.DB_Quest{
|
return &storage.DB_Quest{
|
||||||
ProfileID: profileId,
|
ID: q.ID,
|
||||||
ID: q.ID,
|
ProfileID: profileId,
|
||||||
TemplateID: q.TemplateID,
|
TemplateID: q.TemplateID,
|
||||||
State: q.State,
|
State: q.State,
|
||||||
Objectives: q.Objectives,
|
Objectives: q.Objectives,
|
||||||
ObjectiveCounts: q.ObjectiveCounts,
|
ObjectiveCounts: q.ObjectiveCounts,
|
||||||
BundleID: q.BundleID,
|
BundleID: q.BundleID,
|
||||||
ScheduleID: q.ScheduleID,
|
ScheduleID: q.ScheduleID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Quest) Save() {
|
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
|
DisplayName string
|
||||||
AthenaProfile ProfileSnapshot
|
AthenaProfile ProfileSnapshot
|
||||||
CommonCoreProfile ProfileSnapshot
|
CommonCoreProfile ProfileSnapshot
|
||||||
Loadout Loadout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProfileSnapshot struct {
|
type ProfileSnapshot struct {
|
||||||
|
|
|
@ -2,23 +2,28 @@ package person
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ectrc/snow/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ItemMutex struct {
|
type ItemMutex struct {
|
||||||
sync.Map
|
sync.Map
|
||||||
ProfileType string
|
ProfileType string
|
||||||
|
ProfileID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewItemMutex(profile string) *ItemMutex {
|
func NewItemMutex(profile *storage.DB_Profile) *ItemMutex {
|
||||||
return &ItemMutex{
|
return &ItemMutex{
|
||||||
ProfileType: profile,
|
ProfileType: profile.Type,
|
||||||
|
ProfileID: profile.ID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ItemMutex) AddItem(item *Item) {
|
func (m *ItemMutex) AddItem(item *Item) {
|
||||||
item.ProfileType = m.ProfileType
|
item.ProfileType = m.ProfileType
|
||||||
|
item.ProfileID = m.ProfileID
|
||||||
m.Store(item.ID, item)
|
m.Store(item.ID, item)
|
||||||
// storage.Repo.SaveItem(item)
|
storage.Repo.SaveItem(item.ToDatabase(m.ProfileID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ItemMutex) DeleteItem(id string) {
|
func (m *ItemMutex) DeleteItem(id string) {
|
||||||
|
@ -29,7 +34,7 @@ func (m *ItemMutex) DeleteItem(id string) {
|
||||||
|
|
||||||
item.Delete()
|
item.Delete()
|
||||||
m.Delete(id)
|
m.Delete(id)
|
||||||
// storage.Repo.DeleteItem(id)
|
storage.Repo.DeleteItem(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ItemMutex) GetItem(id string) *Item {
|
func (m *ItemMutex) GetItem(id string) *Item {
|
||||||
|
@ -74,20 +79,25 @@ func (m *ItemMutex) Count() int {
|
||||||
type GiftMutex struct {
|
type GiftMutex struct {
|
||||||
sync.Map
|
sync.Map
|
||||||
ProfileType string
|
ProfileType string
|
||||||
|
ProfileID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGiftMutex() *GiftMutex {
|
func NewGiftMutex(profile *storage.DB_Profile) *GiftMutex {
|
||||||
return &GiftMutex{}
|
return &GiftMutex{
|
||||||
|
ProfileType: profile.Type,
|
||||||
|
ProfileID: profile.ID,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GiftMutex) AddGift(gift *Gift) {
|
func (m *GiftMutex) AddGift(gift *Gift) {
|
||||||
|
gift.ProfileID = m.ProfileID
|
||||||
m.Store(gift.ID, gift)
|
m.Store(gift.ID, gift)
|
||||||
// storage.Repo.SaveGift(gift)
|
storage.Repo.SaveGift(gift.ToDatabase(m.ProfileID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GiftMutex) DeleteGift(id string) {
|
func (m *GiftMutex) DeleteGift(id string) {
|
||||||
m.Delete(id)
|
m.Delete(id)
|
||||||
// storage.Repo.DeleteGift(id)
|
storage.Repo.DeleteGift(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GiftMutex) GetGift(id string) *Gift {
|
func (m *GiftMutex) GetGift(id string) *Gift {
|
||||||
|
@ -116,20 +126,26 @@ func (m *GiftMutex) Count() int {
|
||||||
|
|
||||||
type QuestMutex struct {
|
type QuestMutex struct {
|
||||||
sync.Map
|
sync.Map
|
||||||
|
ProfileType string
|
||||||
|
ProfileID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQuestMutex() *QuestMutex {
|
func NewQuestMutex(profile *storage.DB_Profile) *QuestMutex {
|
||||||
return &QuestMutex{}
|
return &QuestMutex{
|
||||||
|
ProfileType: profile.Type,
|
||||||
|
ProfileID: profile.ID,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *QuestMutex) AddQuest(quest *Quest) {
|
func (m *QuestMutex) AddQuest(quest *Quest) {
|
||||||
|
quest.ProfileID = m.ProfileID
|
||||||
m.Store(quest.ID, quest)
|
m.Store(quest.ID, quest)
|
||||||
// storage.Repo.SaveQuest(quest)
|
storage.Repo.SaveQuest(quest.ToDatabase(m.ProfileID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *QuestMutex) DeleteQuest(id string) {
|
func (m *QuestMutex) DeleteQuest(id string) {
|
||||||
m.Delete(id)
|
m.Delete(id)
|
||||||
// storage.Repo.DeleteQuest(id)
|
storage.Repo.DeleteQuest(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *QuestMutex) GetQuest(id string) *Quest {
|
func (m *QuestMutex) GetQuest(id string) *Quest {
|
||||||
|
@ -158,20 +174,25 @@ func (m *QuestMutex) Count() int {
|
||||||
|
|
||||||
type AttributeMutex struct {
|
type AttributeMutex struct {
|
||||||
sync.Map
|
sync.Map
|
||||||
|
ProfileType string
|
||||||
|
ProfileID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAttributeMutex() *AttributeMutex {
|
func NewAttributeMutex(profile *storage.DB_Profile) *AttributeMutex {
|
||||||
return &AttributeMutex{}
|
return &AttributeMutex{
|
||||||
|
ProfileID: profile.ID,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AttributeMutex) AddAttribute(attribute *Attribute) {
|
func (m *AttributeMutex) AddAttribute(attribute *Attribute) {
|
||||||
|
attribute.ProfileID = m.ProfileID
|
||||||
m.Store(attribute.ID, attribute)
|
m.Store(attribute.ID, attribute)
|
||||||
// storage.Repo.SaveAttribute(key, value)
|
storage.Repo.SaveAttribute(attribute.ToDatabase(m.ProfileID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AttributeMutex) DeleteAttribute(id string) {
|
func (m *AttributeMutex) DeleteAttribute(id string) {
|
||||||
m.Delete(id)
|
m.Delete(id)
|
||||||
// storage.Repo.DeleteAttribute(key)
|
storage.Repo.DeleteAttribute(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AttributeMutex) GetAttribute(id string) *Attribute {
|
func (m *AttributeMutex) GetAttribute(id string) *Attribute {
|
||||||
|
|
|
@ -88,26 +88,63 @@ func (s *PostgresStorage) SavePerson(person *DB_Person) {
|
||||||
s.Postgres.Save(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) {
|
func (s *PostgresStorage) DeleteItem(itemId string) {
|
||||||
s.Postgres.Delete(&DB_Item{}, "id = ?", itemId)
|
s.Postgres.Delete(&DB_Item{}, "id = ?", itemId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) SaveVariant(variant *DB_VariantChannel) {
|
||||||
|
s.Postgres.Save(variant)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) DeleteVariant(variantId string) {
|
func (s *PostgresStorage) DeleteVariant(variantId string) {
|
||||||
s.Postgres.Delete(&DB_VariantChannel{}, "id = ?", variantId)
|
s.Postgres.Delete(&DB_VariantChannel{}, "id = ?", variantId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) SaveQuest(quest *DB_Quest) {
|
||||||
|
s.Postgres.Save(quest)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) DeleteQuest(questId string) {
|
func (s *PostgresStorage) DeleteQuest(questId string) {
|
||||||
s.Postgres.Delete(&DB_Quest{}, "id = ?", questId)
|
s.Postgres.Delete(&DB_Quest{}, "id = ?", questId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) SaveLoot(loot *DB_Loot) {
|
||||||
|
s.Postgres.Save(loot)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) DeleteLoot(lootId string) {
|
func (s *PostgresStorage) DeleteLoot(lootId string) {
|
||||||
s.Postgres.Delete(&DB_Loot{}, "id = ?", lootId)
|
s.Postgres.Delete(&DB_Loot{}, "id = ?", lootId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PostgresStorage) SaveGift(gift *DB_Gift) {
|
||||||
|
s.Postgres.Save(gift)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) DeleteGift(giftId string) {
|
func (s *PostgresStorage) DeleteGift(giftId string) {
|
||||||
s.Postgres.Delete(&DB_Gift{}, "id = ?", giftId)
|
s.Postgres.Delete(&DB_Gift{}, "id = ?", giftId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PostgresStorage) DeleteAttribute(attributeId string) {
|
func (s *PostgresStorage) DeleteAttribute(attributeId string) {
|
||||||
s.Postgres.Delete(&DB_PAttribute{}, "id = ?", attributeId)
|
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)
|
||||||
}
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Repo *Repository
|
Repo *Repository
|
||||||
Cache *PersonsCache
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
|
@ -13,11 +12,25 @@ type Storage interface {
|
||||||
GetAllPersons() []*DB_Person
|
GetAllPersons() []*DB_Person
|
||||||
SavePerson(person *DB_Person)
|
SavePerson(person *DB_Person)
|
||||||
|
|
||||||
|
SaveProfile(profile *DB_Profile)
|
||||||
|
DeleteProfile(profileId string)
|
||||||
|
|
||||||
|
SaveItem(item *DB_Item)
|
||||||
DeleteItem(itemId string)
|
DeleteItem(itemId string)
|
||||||
|
|
||||||
|
SaveVariant(variant *DB_VariantChannel)
|
||||||
DeleteVariant(variantId string)
|
DeleteVariant(variantId string)
|
||||||
|
|
||||||
|
SaveQuest(quest *DB_Quest)
|
||||||
DeleteQuest(questId string)
|
DeleteQuest(questId string)
|
||||||
|
|
||||||
|
SaveLoot(loot *DB_Loot)
|
||||||
DeleteLoot(lootId string)
|
DeleteLoot(lootId string)
|
||||||
|
|
||||||
|
SaveGift(gift *DB_Gift)
|
||||||
DeleteGift(giftId string)
|
DeleteGift(giftId string)
|
||||||
|
|
||||||
|
SaveAttribute(attribute *DB_PAttribute)
|
||||||
DeleteAttribute(attributeId string)
|
DeleteAttribute(attributeId string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,30 +44,18 @@ func NewStorage(s Storage) *Repository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) GetPerson(personId string) *DB_Person {
|
func (r *Repository) GetPersonFromDB(personId string) *DB_Person {
|
||||||
cachePerson := Cache.GetPerson(personId)
|
|
||||||
if cachePerson != nil {
|
|
||||||
return cachePerson
|
|
||||||
}
|
|
||||||
|
|
||||||
storagePerson := r.Storage.GetPerson(personId)
|
storagePerson := r.Storage.GetPerson(personId)
|
||||||
if storagePerson != nil {
|
if storagePerson != nil {
|
||||||
Cache.SavePerson(storagePerson)
|
|
||||||
return storagePerson
|
return storagePerson
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) GetPersonByDisplay(displayName string) *DB_Person {
|
func (r *Repository) GetPersonByDisplayFromDB(displayName string) *DB_Person {
|
||||||
cachePerson := Cache.GetPersonByDisplay(displayName)
|
|
||||||
if cachePerson != nil {
|
|
||||||
return cachePerson
|
|
||||||
}
|
|
||||||
|
|
||||||
storagePerson := r.Storage.GetPersonByDisplay(displayName)
|
storagePerson := r.Storage.GetPersonByDisplay(displayName)
|
||||||
if storagePerson != nil {
|
if storagePerson != nil {
|
||||||
Cache.SavePerson(storagePerson)
|
|
||||||
return storagePerson
|
return storagePerson
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,30 +67,61 @@ func (r *Repository) GetAllPersons() []*DB_Person {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) SavePerson(person *DB_Person) {
|
func (r *Repository) SavePerson(person *DB_Person) {
|
||||||
Cache.SavePerson(person)
|
|
||||||
r.Storage.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) {
|
func (r *Repository) DeleteItem(itemId string) {
|
||||||
r.Storage.DeleteItem(itemId)
|
r.Storage.DeleteItem(itemId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveVariant(variant *DB_VariantChannel) {
|
||||||
|
r.Storage.SaveVariant(variant)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) DeleteVariant(variantId string) {
|
func (r *Repository) DeleteVariant(variantId string) {
|
||||||
r.Storage.DeleteVariant(variantId)
|
r.Storage.DeleteVariant(variantId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveQuest(quest *DB_Quest) {
|
||||||
|
r.Storage.SaveQuest(quest)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) DeleteQuest(questId string) {
|
func (r *Repository) DeleteQuest(questId string) {
|
||||||
r.Storage.DeleteQuest(questId)
|
r.Storage.DeleteQuest(questId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveLoot(loot *DB_Loot) {
|
||||||
|
r.Storage.SaveLoot(loot)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) DeleteLoot(lootId string) {
|
func (r *Repository) DeleteLoot(lootId string) {
|
||||||
r.Storage.DeleteLoot(lootId)
|
r.Storage.DeleteLoot(lootId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveGift(gift *DB_Gift) {
|
||||||
|
r.Storage.SaveGift(gift)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) DeleteGift(giftId string) {
|
func (r *Repository) DeleteGift(giftId string) {
|
||||||
r.Storage.DeleteGift(giftId)
|
r.Storage.DeleteGift(giftId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Repository) SaveAttribute(attribute *DB_PAttribute) {
|
||||||
|
r.Storage.SaveAttribute(attribute)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Repository) DeleteAttribute(attributeId string) {
|
func (r *Repository) DeleteAttribute(attributeId string) {
|
||||||
r.Storage.DeleteAttribute(attributeId)
|
r.Storage.DeleteAttribute(attributeId)
|
||||||
}
|
}
|
|
@ -7,45 +7,24 @@ type Tabler interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_Person struct {
|
type DB_Person struct {
|
||||||
ID string
|
ID string
|
||||||
DisplayName string
|
DisplayName string
|
||||||
AccessKey string
|
AccessKey string
|
||||||
Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
|
Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
|
||||||
Loadout DB_Loadout `gorm:"foreignkey:PersonID"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_Person) TableName() string {
|
func (DB_Person) TableName() string {
|
||||||
return "Persons"
|
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 {
|
type DB_Profile struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
PersonID string
|
PersonID string
|
||||||
Items []DB_Item `gorm:"foreignkey:ProfileID"`
|
Items []DB_Item `gorm:"foreignkey:ProfileID"`
|
||||||
Gifts []DB_Gift `gorm:"foreignkey:ProfileID"`
|
Gifts []DB_Gift `gorm:"foreignkey:ProfileID"`
|
||||||
Quests []DB_Quest `gorm:"foreignkey:ProfileID"`
|
Quests []DB_Quest `gorm:"foreignkey:ProfileID"`
|
||||||
Attributes []DB_PAttribute `gorm:"foreignkey:ProfileID"`
|
Attributes []DB_PAttribute `gorm:"foreignkey:ProfileID"`
|
||||||
Type string
|
Type string
|
||||||
Revision int
|
Revision int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,11 +33,11 @@ func (DB_Profile) TableName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_PAttribute struct {
|
type DB_PAttribute struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
ProfileID string
|
ProfileID string
|
||||||
Key string
|
Key string
|
||||||
ValueJSON string
|
ValueJSON string
|
||||||
Type string
|
Type string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_PAttribute) TableName() string {
|
func (DB_PAttribute) TableName() string {
|
||||||
|
@ -66,13 +45,13 @@ func (DB_PAttribute) TableName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_Item struct {
|
type DB_Item struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
ProfileID string
|
ProfileID string
|
||||||
TemplateID string
|
TemplateID string
|
||||||
Quantity int
|
Quantity int
|
||||||
Favorite bool
|
Favorite bool
|
||||||
HasSeen bool
|
HasSeen bool
|
||||||
Variants []DB_VariantChannel `gorm:"foreignkey:ItemID"`
|
Variants []DB_VariantChannel `gorm:"foreignkey:ItemID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_Item) TableName() string {
|
func (DB_Item) TableName() string {
|
||||||
|
@ -80,11 +59,11 @@ func (DB_Item) TableName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_VariantChannel struct {
|
type DB_VariantChannel struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
ItemID string
|
ItemID string
|
||||||
Channel string
|
Channel string
|
||||||
Owned pq.StringArray `gorm:"type:text[]"`
|
Owned pq.StringArray `gorm:"type:text[]"`
|
||||||
Active string
|
Active string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_VariantChannel) TableName() string {
|
func (DB_VariantChannel) TableName() string {
|
||||||
|
@ -92,13 +71,13 @@ func (DB_VariantChannel) TableName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_Quest struct {
|
type DB_Quest struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
ProfileID string
|
ProfileID string
|
||||||
TemplateID string
|
TemplateID string
|
||||||
State string
|
State string
|
||||||
Objectives pq.StringArray `gorm:"type:text[]"`
|
Objectives pq.StringArray `gorm:"type:text[]"`
|
||||||
ObjectiveCounts pq.Int64Array `gorm:"type:bigint[]"`
|
ObjectiveCounts pq.Int64Array `gorm:"type:bigint[]"`
|
||||||
BundleID string
|
BundleID string
|
||||||
ScheduleID string
|
ScheduleID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,14 +86,14 @@ func (DB_Quest) TableName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_Gift struct {
|
type DB_Gift struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
ProfileID string
|
ProfileID string
|
||||||
TemplateID string
|
TemplateID string
|
||||||
Quantity int
|
Quantity int
|
||||||
FromID string
|
FromID string
|
||||||
GiftedAt int64
|
GiftedAt int64
|
||||||
Message string
|
Message string
|
||||||
Loot []DB_Loot `gorm:"foreignkey:GiftID"`
|
Loot []DB_Loot `gorm:"foreignkey:GiftID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_Gift) TableName() string {
|
func (DB_Gift) TableName() string {
|
||||||
|
@ -122,11 +101,11 @@ func (DB_Gift) TableName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB_Loot struct {
|
type DB_Loot struct {
|
||||||
ID string `gorm:"primary_key"`
|
ID string `gorm:"primary_key"`
|
||||||
GiftID string
|
GiftID string
|
||||||
TemplateID string
|
TemplateID string
|
||||||
Quantity int
|
Quantity int
|
||||||
ProfileType string
|
ProfileType string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (DB_Loot) TableName() string {
|
func (DB_Loot) TableName() string {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user