Remove friends and fix client credentials bug
This commit is contained in:
parent
8619cac5ca
commit
20cbc92e7f
|
@ -35,6 +35,7 @@ type CS struct {
|
|||
Build float64
|
||||
Everything bool
|
||||
Password bool
|
||||
DisableClientCredentials bool
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,4 +135,5 @@ func LoadConfig(file []byte) {
|
|||
Config.Fortnite.Season = parsedSeason
|
||||
Config.Fortnite.Everything = cfg.Section("fortnite").Key("everything").MustBool(false)
|
||||
Config.Fortnite.Password = cfg.Section("fortnite").Key("password").MustBool(false)
|
||||
Config.Fortnite.DisableClientCredentials = cfg.Section("fortnite").Key("disable_client_credentials").MustBool(false)
|
||||
}
|
|
@ -45,3 +45,9 @@ everything=true
|
|||
; if this is set to false, you can login to any account with just the username
|
||||
; if this is true you must login using an exchange code given by the bot
|
||||
password=true
|
||||
|
||||
; if you recieve lots of /account/api/oauth/token requests, set this to true
|
||||
; this will disable the client credentials grant type
|
||||
; however this will also disable a user to get the hotfixes before login
|
||||
; so xmpp and other hotfix related things will be delayed by ~1 minute
|
||||
disable_client_credentials=false
|
6
go.mod
6
go.mod
|
@ -3,10 +3,8 @@ module github.com/ectrc/snow
|
|||
go 1.21.3
|
||||
|
||||
require (
|
||||
github.com/beevik/etree v1.3.0
|
||||
github.com/bwmarrin/discordgo v0.27.1
|
||||
github.com/goccy/go-json v0.10.2
|
||||
github.com/gofiber/contrib/websocket v1.3.0
|
||||
github.com/gofiber/fiber/v2 v2.51.0
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||
github.com/google/uuid v1.4.0
|
||||
|
@ -20,7 +18,6 @@ require (
|
|||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/fasthttp/websocket v1.5.7 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
|
@ -33,7 +30,7 @@ require (
|
|||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
|
@ -41,7 +38,6 @@ require (
|
|||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
golang.org/x/crypto v0.15.0 // indirect
|
||||
golang.org/x/net v0.18.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
||||
|
|
10
go.sum
10
go.sum
|
@ -1,18 +1,12 @@
|
|||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/beevik/etree v1.3.0 h1:hQTc+pylzIKDb23yYprodCWWTt+ojFfUZyzU09a/hmU=
|
||||
github.com/beevik/etree v1.3.0/go.mod h1:aiPf89g/1k3AShMVAzriilpcE4R/Vuor90y83zVZWFc=
|
||||
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
|
||||
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fasthttp/websocket v1.5.7 h1:0a6o2OfeATvtGgoMKleURhLT6JqWPg7fYfWnH4KHau4=
|
||||
github.com/fasthttp/websocket v1.5.7/go.mod h1:bC4fxSono9czeXHQUVKxsC0sNjbm7lPJR04GDFqClfU=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gofiber/contrib/websocket v1.3.0 h1:XADFAGorer1VJ1bqC4UkCjqS37kwRTV0415+050NrMk=
|
||||
github.com/gofiber/contrib/websocket v1.3.0/go.mod h1:xguaOzn2ZZ759LavtosEP+rcxIgBEE/rdumPINhR+Xo=
|
||||
github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ=
|
||||
github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
|
@ -53,8 +47,6 @@ github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJ
|
|||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
@ -85,8 +77,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
|
@ -40,6 +40,10 @@ func PostFortniteToken(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
func PostTokenClientCredentials(c *fiber.Ctx, body *FortniteTokenBody) error {
|
||||
if aid.Config.Fortnite.DisableClientCredentials {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(aid.ErrorBadRequest("Client Credentials is disabled."))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).JSON(aid.JSON{
|
||||
"access_token": "snow",
|
||||
"token_type": "bearer",
|
||||
|
|
|
@ -1,138 +1,26 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
p "github.com/ectrc/snow/person"
|
||||
"github.com/ectrc/snow/storage"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func GetFriendList(c *fiber.Ctx) error {
|
||||
person := c.Locals("person").(*p.Person)
|
||||
result := map[string]aid.JSON{}
|
||||
|
||||
for _, partial := range storage.Repo.GetFriendsForPerson(person.ID) {
|
||||
friend := person.GetFriend(partial.ID)
|
||||
if friend == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
result[partial.ID] = friend.GenerateFriendResponse()
|
||||
}
|
||||
|
||||
response := []aid.JSON{}
|
||||
for _, friend := range result {
|
||||
response = append(response, friend)
|
||||
}
|
||||
|
||||
return c.Status(200).JSON(response)
|
||||
return c.Status(200).JSON([]aid.JSON{})
|
||||
}
|
||||
|
||||
func PostCreateFriend(c *fiber.Ctx) error {
|
||||
person := c.Locals("person").(*p.Person)
|
||||
friendId := c.Params("wanted")
|
||||
|
||||
existing := person.GetFriend(friendId)
|
||||
if existing != nil && (existing.Direction == "BOTH" || existing.Direction == "OUTGOING") {
|
||||
return c.Status(400).JSON(aid.ErrorBadRequest("already active friend request"))
|
||||
}
|
||||
|
||||
person.AddFriend(friendId)
|
||||
|
||||
socket := FindSocketForPerson(person)
|
||||
socket.PresenceWriteJSON(aid.JSON{
|
||||
"payload": person.GetFriend(friendId).GenerateFriendResponse(),
|
||||
"type": "com.epicgames.friends.core.apiobjects.Friend",
|
||||
"timestamp": time.Now().Format(time.RFC3339),
|
||||
})
|
||||
|
||||
friendSocket := FindSocketForPerson(p.Find(friendId))
|
||||
friendSocket.PresenceWriteJSON(aid.JSON{
|
||||
"payload": friendSocket.Person.GetFriend(person.ID).GenerateFriendResponse(),
|
||||
"type": "com.epicgames.friends.core.apiobjects.Friend",
|
||||
"timestamp": time.Now().Format(time.RFC3339),
|
||||
})
|
||||
|
||||
return c.SendStatus(204)
|
||||
}
|
||||
|
||||
func DeleteFriend(c *fiber.Ctx) error {
|
||||
person := c.Locals("person").(*p.Person)
|
||||
wanted := c.Params("wanted")
|
||||
|
||||
existing := person.GetFriend(wanted)
|
||||
if existing == nil {
|
||||
return c.Status(400).JSON(aid.ErrorBadRequest("not friends"))
|
||||
}
|
||||
|
||||
person.RemoveFriend(wanted)
|
||||
existing.Person.RemoveFriend(person.ID)
|
||||
|
||||
return c.SendStatus(204)
|
||||
}
|
||||
|
||||
func GetFriendListSummary(c *fiber.Ctx) error {
|
||||
person := c.Locals("person").(*p.Person)
|
||||
|
||||
all := map[string]*p.Friend{}
|
||||
for _, partial := range storage.Repo.GetFriendsForPerson(person.ID) {
|
||||
friend := person.GetFriend(partial.ID)
|
||||
if friend == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
all[partial.ID] = friend
|
||||
}
|
||||
|
||||
result := aid.JSON{
|
||||
"friends": []aid.JSON{},
|
||||
"incoming": []aid.JSON{},
|
||||
"outgoing": []aid.JSON{},
|
||||
"settings": aid.JSON{
|
||||
"acceptInvites": "public",
|
||||
},
|
||||
}
|
||||
|
||||
for _, friend := range all {
|
||||
switch friend.Status {
|
||||
case p.FriendStatusAccepted:
|
||||
result["friends"] = append(result["friends"].([]aid.JSON), friend.GenerateSummaryResponse())
|
||||
case p.FriendStatusPending:
|
||||
switch friend.Direction {
|
||||
case p.FriendDirectionIncoming:
|
||||
result["incoming"] = append(result["incoming"].([]aid.JSON), friend.GenerateSummaryResponse())
|
||||
case p.FriendDirectionOutgoing:
|
||||
result["outgoing"] = append(result["outgoing"].([]aid.JSON), friend.GenerateSummaryResponse())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c.Status(200).JSON(result)
|
||||
}
|
||||
|
||||
func GetPersonSearch(c *fiber.Ctx) error {
|
||||
query := c.Query("prefix")
|
||||
|
||||
matches := storage.Repo.GetPersonsByPartialDisplayFromDB(query)
|
||||
if matches == nil {
|
||||
return c.Status(200).JSON([]aid.JSON{})
|
||||
}
|
||||
|
||||
result := []aid.JSON{}
|
||||
for i, match := range matches {
|
||||
result = append(result, aid.JSON{
|
||||
"accountId": match.ID,
|
||||
"epicMutuals": 0,
|
||||
"sortPosition": i,
|
||||
"matchType": "prefix",
|
||||
"matches": []aid.JSON{{
|
||||
"value": match.DisplayName,
|
||||
"matchType": "prefix",
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(200).JSON(result)
|
||||
func GetPersonSearch(c *fiber.Ctx) error {
|
||||
return c.Status(200).JSON([]aid.JSON{})
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"github.com/ectrc/snow/aid"
|
||||
"github.com/ectrc/snow/person"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type SocketType string
|
||||
const SocketTypeXmpp SocketType = "xmpp"
|
||||
const SocketTypeUnknown SocketType = "unknown"
|
||||
|
||||
type Socket struct {
|
||||
ID string
|
||||
Connection *websocket.Conn
|
||||
Person *person.Person
|
||||
|
||||
Type SocketType
|
||||
PresenceState *PresenceState
|
||||
}
|
||||
|
||||
type MessageToWrite struct {
|
||||
Socket *Socket
|
||||
Message []byte
|
||||
}
|
||||
|
||||
func (s *Socket) Write(message []byte) {
|
||||
socketWriteQueue <- MessageToWrite{
|
||||
Socket: s,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
socketWriteQueue = make(chan MessageToWrite, 1000)
|
||||
socketHandlers = map[SocketType]func(string) {
|
||||
SocketTypeXmpp: presenceSocketHandle,
|
||||
}
|
||||
|
||||
sockets = aid.GenericSyncMap[Socket]{}
|
||||
)
|
||||
|
||||
func MiddlewareWebsocket(c *fiber.Ctx) error {
|
||||
if !websocket.IsWebSocketUpgrade(c) {
|
||||
return fiber.ErrUpgradeRequired
|
||||
}
|
||||
|
||||
var protocol SocketType
|
||||
switch c.Get("Sec-WebSocket-Protocol") {
|
||||
case "xmpp":
|
||||
protocol = SocketTypeXmpp
|
||||
default:
|
||||
protocol = SocketTypeUnknown
|
||||
}
|
||||
|
||||
c.Locals("uuid", uuid.New().String())
|
||||
c.Locals("protocol", protocol)
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
func WebsocketConnection(c *websocket.Conn) {
|
||||
protocol := c.Locals("protocol").(SocketType)
|
||||
uuid := c.Locals("uuid").(string)
|
||||
|
||||
sockets.Add(uuid, &Socket{
|
||||
ID: uuid,
|
||||
Type: protocol,
|
||||
Connection: c,
|
||||
})
|
||||
defer func() {
|
||||
socket, ok := sockets.Get(uuid)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
socket.Connection.Close()
|
||||
sockets.Delete(uuid)
|
||||
aid.Print("(xmpp) connection closed", uuid)
|
||||
}()
|
||||
|
||||
if handle, ok := socketHandlers[protocol]; ok {
|
||||
handle(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
func GetAllSockets(c *fiber.Ctx) error {
|
||||
result := []any{}
|
||||
|
||||
sockets.Range(func(key string, socket *Socket) bool {
|
||||
result = append(result, *socket)
|
||||
return true
|
||||
})
|
||||
|
||||
return c.Status(200).JSON(result)
|
||||
}
|
||||
|
||||
func FindSocketForPerson(person *person.Person) *Socket {
|
||||
var recieverSocket *Socket
|
||||
sockets.Range(func(key string, value *Socket) bool {
|
||||
if value.Person == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if value.Person.ID == person.ID {
|
||||
recieverSocket = value
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return recieverSocket
|
||||
}
|
||||
|
||||
func init() {
|
||||
go func() {
|
||||
for {
|
||||
if aid.Config != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
message := <-socketWriteQueue
|
||||
aid.Print("(socket) writing message to", message.Socket.ID, string(message.Message))
|
||||
message.Socket.Connection.WriteMessage(websocket.TextMessage, message.Message)
|
||||
}
|
||||
}()
|
||||
}
|
355
handlers/xmpp.go
355
handlers/xmpp.go
|
@ -1,355 +0,0 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beevik/etree"
|
||||
"github.com/ectrc/snow/aid"
|
||||
p "github.com/ectrc/snow/person"
|
||||
"github.com/ectrc/snow/storage"
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type PresenceStatus struct {
|
||||
Status string `json:"Status"`
|
||||
IsPlaying bool `json:"bIsPlaying"`
|
||||
IsJoinable bool `json:"bIsJoinable"`
|
||||
HasVoiceSupport bool `json:"bHasVoiceSupport"`
|
||||
SessionId string `json:"SessionId"`
|
||||
Properties map[string]struct {
|
||||
SourceId string `json:"sourceId"`
|
||||
SourceDisplayName string `json:"sourceDisplayName"`
|
||||
SourcePlatform string `json:"sourcePlatform"`
|
||||
PartyId string `json:"partyId"`
|
||||
PartyTypeId int `json:"partyTypeId"`
|
||||
Key string `json:"key"`
|
||||
AppId string `json:"appId"`
|
||||
BuildId string `json:"buildId"`
|
||||
PartyFlags int `json:"partyFlags"`
|
||||
NotAcceptingReason int `json:"notAcceptingReason"`
|
||||
Pc int `json:"pc"`
|
||||
} `json:"Properties"`
|
||||
}
|
||||
|
||||
type PresenceState struct {
|
||||
JID string
|
||||
Open bool
|
||||
RawStatus string
|
||||
ParsedStatus PresenceStatus
|
||||
}
|
||||
|
||||
var (
|
||||
socketXmppMessageHandlers = map[string]func(*Socket, *etree.Document) error {
|
||||
"open": presenceSocketOpenEvent,
|
||||
"iq": presenceSocketIqRootEvent,
|
||||
"message": presenceSocketMessageEvent,
|
||||
"presence": presenceSocketPresenceEvent,
|
||||
"close": presenceSocketCloseEvent,
|
||||
}
|
||||
)
|
||||
|
||||
func presenceSocketHandle(id string) {
|
||||
socket, ok := sockets.Get(id)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
socket.Type = SocketTypeXmpp
|
||||
socket.PresenceState = &PresenceState{}
|
||||
|
||||
for {
|
||||
_, message, err := socket.Connection.ReadMessage()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
parsed := etree.NewDocument()
|
||||
if err := parsed.ReadFromBytes(message); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if handler, ok := socketXmppMessageHandlers[parsed.Root().Tag]; ok {
|
||||
if err := handler(socket, parsed); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, partial := range storage.Repo.GetFriendsForPerson(socket.Person.ID) {
|
||||
friend := socket.Person.GetFriend(partial.ID)
|
||||
if friend == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
friendSocket := FindSocketForPerson(friend.Person)
|
||||
if friendSocket == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
friendDocument := etree.NewDocument()
|
||||
friendPresence := friendDocument.CreateElement("presence")
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "from", Value: socket.PresenceState.JID})
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "to", Value: friendSocket.PresenceState.JID})
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "type", Value: "available"})
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
friendPresence.CreateElement("status").SetText(aid.JSONStringify(aid.JSON{}))
|
||||
friendPresence.CreateElement("show").SetText("away")
|
||||
|
||||
friendSocket.PresenceWrite(friendDocument)
|
||||
}
|
||||
|
||||
for _, party := range socket.PresenceState.ParsedStatus.Properties {
|
||||
if party.PartyId == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
sockets.Range(func(_ string, recieverSocket *Socket) bool {
|
||||
if recieverSocket.Type != SocketTypeXmpp || recieverSocket.Person == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
document := etree.NewDocument()
|
||||
message := document.CreateElement("message")
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "id", Value: uuid.New().String()})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "from", Value: socket.PresenceState.JID})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "to", Value: recieverSocket.PresenceState.JID})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
message.CreateElement("body").SetText(aid.JSONStringify(aid.JSON{
|
||||
"type": "com.epicgames.party.memberexited",
|
||||
"timestamp": time.Now().Format(time.RFC3339),
|
||||
"payload": aid.JSON{
|
||||
"memberId": socket.Person.ID,
|
||||
"partyId": party.PartyId,
|
||||
"wasKicked": false,
|
||||
},
|
||||
}))
|
||||
|
||||
recieverSocket.PresenceWrite(document)
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func presenceSocketOpenEvent(socket *Socket, tree *etree.Document) error {
|
||||
document := etree.NewDocument()
|
||||
open := document.CreateElement("open")
|
||||
open.Attr = append(open.Attr, etree.Attr{Key: "xmlns", Value: "urn:ietf:params:xml:ns:xmpp-framing"})
|
||||
open.Attr = append(open.Attr, etree.Attr{Key: "from", Value: "prod.ol.epicgames.com"})
|
||||
open.Attr = append(open.Attr, etree.Attr{Key: "version", Value: "1.0"})
|
||||
open.Attr = append(open.Attr, etree.Attr{Key: "id", Value: socket.ID})
|
||||
|
||||
socket.PresenceWrite(document)
|
||||
return nil
|
||||
}
|
||||
|
||||
func presenceSocketCloseEvent(socket *Socket, tree *etree.Document) error {
|
||||
return fmt.Errorf("safe exit")
|
||||
}
|
||||
|
||||
func presenceSocketIqRootEvent(socket *Socket, tree *etree.Document) error {
|
||||
redirect := map[string]func(*Socket, *etree.Document) error{
|
||||
"set": presenceSocketIqSetEvent,
|
||||
"get": presenceSocketIqGetEvent,
|
||||
}
|
||||
|
||||
if handler, ok := redirect[tree.Root().SelectAttr("type").Value]; ok {
|
||||
if err := handler(socket, tree); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func presenceSocketIqSetEvent(socket *Socket, tree *etree.Document) error {
|
||||
token := tree.Root().SelectElement("query").SelectElement("password")
|
||||
if token == nil || token.Text() == "" {
|
||||
return fmt.Errorf("invalid token")
|
||||
}
|
||||
real := strings.ReplaceAll(token.Text(), "eg1~", "")
|
||||
|
||||
claims, err := aid.JWTVerify(real)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
if claims["snow_id"] == nil {
|
||||
return fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
snowId, ok := claims["snow_id"].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
person := p.Find(snowId)
|
||||
if person == nil {
|
||||
return fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
socket.Person = person
|
||||
socket.PresenceState.JID = person.ID + "@prod.ol.epicgames.com/" + tree.Root().SelectElement("query").SelectElement("resource").Text()
|
||||
|
||||
document := etree.NewDocument()
|
||||
iq := document.CreateElement("iq")
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "type", Value: "result"})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "id", Value: "_xmpp_auth1"})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "from", Value: "prod.ol.epicgames.com"})
|
||||
|
||||
socket.PresenceWrite(document)
|
||||
socket.PresenceWriteStatus()
|
||||
return nil
|
||||
}
|
||||
|
||||
func presenceSocketIqGetEvent(socket *Socket, tree *etree.Document) error {
|
||||
document := etree.NewDocument()
|
||||
iq := document.CreateElement("iq")
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "type", Value: "result"})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "id", Value: tree.Root().SelectAttr("id").Value})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "to", Value: tree.Root().SelectAttr("from").Value})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "from", Value: "prod.ol.epicgames.com"})
|
||||
ping := iq.CreateElement("ping")
|
||||
ping.Attr = append(ping.Attr, etree.Attr{Key: "xmlns", Value: "urn:xmpp:ping"})
|
||||
|
||||
socket.PresenceWrite(document)
|
||||
return nil
|
||||
}
|
||||
|
||||
func presenceSocketMessageEvent(socket *Socket, tree *etree.Document) error {
|
||||
reciever := p.Find(strings.Split(tree.Root().SelectAttr("to").Value, "@")[0])
|
||||
if reciever == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
recieverSocket := FindSocketForPerson(reciever)
|
||||
if recieverSocket == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
document := etree.NewDocument()
|
||||
message := document.CreateElement("message")
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "id", Value: tree.Root().SelectAttr("id").Value})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "from", Value: socket.PresenceState.JID})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "to", Value: recieverSocket.PresenceState.JID})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
message.CreateElement("body").SetText(tree.Root().SelectElement("body").Text())
|
||||
|
||||
recieverSocket.PresenceWrite(document)
|
||||
return nil
|
||||
}
|
||||
|
||||
func presenceSocketPresenceEvent(socket *Socket, tree *etree.Document) error {
|
||||
status := tree.Root().SelectElement("status")
|
||||
if status == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
socket.PresenceState.RawStatus = status.Text()
|
||||
json.NewDecoder(strings.NewReader(status.Text())).Decode(&socket.PresenceState.ParsedStatus)
|
||||
socket.PresenceWriteStatus()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Socket) PresenceWrite(message *etree.Document) {
|
||||
bytes, err := message.WriteToBytes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
s.Write(bytes)
|
||||
}
|
||||
|
||||
func (s *Socket) PresenceWriteStatus() {
|
||||
for _, partial := range storage.Repo.GetFriendsForPerson(s.Person.ID) {
|
||||
friend := s.Person.GetFriend(partial.ID)
|
||||
if friend == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
friendSocket := FindSocketForPerson(friend.Person)
|
||||
if friendSocket == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
friendDocument := etree.NewDocument()
|
||||
friendPresence := friendDocument.CreateElement("presence")
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "from", Value: s.PresenceState.JID})
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "to", Value: friendSocket.PresenceState.JID})
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "type", Value: "available"})
|
||||
friendPresence.Attr = append(friendPresence.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
friendPresence.CreateElement("status").SetText(s.PresenceState.RawStatus)
|
||||
friendSocket.PresenceWrite(friendDocument)
|
||||
|
||||
document := etree.NewDocument()
|
||||
presence := document.CreateElement("presence")
|
||||
presence.Attr = append(presence.Attr, etree.Attr{Key: "from", Value: friendSocket.PresenceState.JID})
|
||||
presence.Attr = append(presence.Attr, etree.Attr{Key: "to", Value: s.PresenceState.JID})
|
||||
presence.Attr = append(presence.Attr, etree.Attr{Key: "type", Value: "available"})
|
||||
presence.Attr = append(presence.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
presence.CreateElement("status").SetText(friendSocket.PresenceState.RawStatus)
|
||||
s.PresenceWrite(document)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Socket) PresenceWriteJSON(body aid.JSON) {
|
||||
aid.PrintJSON(body)
|
||||
|
||||
document := etree.NewDocument()
|
||||
message := document.CreateElement("message")
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "id", Value: uuid.New().String()})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "from", Value: "xmpp-admin@prod.ol.epicgames.com"})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "to", Value: s.PresenceState.JID})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
message.CreateElement("body").SetText(aid.JSONStringify(body))
|
||||
s.PresenceWrite(document)
|
||||
}
|
||||
|
||||
func (s *Socket) PresenceWriteGiftReceived() {
|
||||
document := etree.NewDocument()
|
||||
message := document.CreateElement("message")
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "id", Value: uuid.New().String()})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "from", Value: "prod.ol.epicgames.com"})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "to", Value: s.PresenceState.JID})
|
||||
message.Attr = append(message.Attr, etree.Attr{Key: "xmlns", Value: "jabber:client"})
|
||||
message.CreateElement("body").SetText(aid.JSONStringify(aid.JSON{
|
||||
"type": "com.epicgames.gift.received",
|
||||
"timestamp": time.Now().Format(time.RFC3339),
|
||||
"payload": aid.JSON{},
|
||||
}))
|
||||
s.PresenceWrite(document)
|
||||
}
|
||||
|
||||
func init() {
|
||||
go func() {
|
||||
for {
|
||||
if aid.Config != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
timer := time.NewTicker(30 * time.Second)
|
||||
for {
|
||||
<-timer.C
|
||||
sockets.Range(func(key string, socket *Socket) bool {
|
||||
if socket.Type != SocketTypeXmpp || socket.Person == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
document := etree.NewDocument()
|
||||
iq := document.CreateElement("iq")
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "id", Value: "_xmpp_auth1"})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "type", Value: "get"})
|
||||
iq.Attr = append(iq.Attr, etree.Attr{Key: "from", Value: "prod.ol.epicgames.com"})
|
||||
ping := iq.CreateElement("ping")
|
||||
ping.Attr = append(iq.Attr, etree.Attr{Key: "xmlns", Value: "urn:xmpp:ping"})
|
||||
|
||||
socket.PresenceWrite(document)
|
||||
return true
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
4
main.go
4
main.go
|
@ -12,7 +12,6 @@ import (
|
|||
"github.com/ectrc/snow/storage"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
|
@ -69,7 +68,7 @@ func main() {
|
|||
r.Post("/api/v1/assets/Fortnite/:versionId/:assetName", handlers.PostAssets)
|
||||
|
||||
r.Get("//", func(c *fiber.Ctx) error { return c.Redirect("/socket") })
|
||||
r.Get("/socket", handlers.MiddlewareWebsocket, websocket.New(handlers.WebsocketConnection))
|
||||
// r.Get("/socket", handlers.MiddlewareWebsocket, websocket.New(handlers.WebsocketConnection))
|
||||
|
||||
account := r.Group("/account/api")
|
||||
account.Get("/public/account", handlers.GetPublicAccounts)
|
||||
|
@ -131,7 +130,6 @@ func main() {
|
|||
snow := r.Group("/snow")
|
||||
snow.Get("/cosmetics", handlers.GetPreloadedCosmetics)
|
||||
snow.Get("/image/:playlist", handlers.GetPlaylistImage)
|
||||
snow.Get("/sockets", handlers.GetAllSockets)
|
||||
|
||||
discord := snow.Group("/discord")
|
||||
discord.Get("/", handlers.GetDiscordOAuthURL)
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
package person
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ectrc/snow/aid"
|
||||
)
|
||||
|
||||
type FriendDirection string
|
||||
var FriendDirectionBoth FriendDirection = "BOTH"
|
||||
var FriendDirectionIncoming FriendDirection = "INCOMING"
|
||||
var FriendDirectionOutgoing FriendDirection = "OUTGOING"
|
||||
|
||||
type FriendStatus string
|
||||
var FriendStatusPending FriendStatus = "PENDING"
|
||||
var FriendStatusAccepted FriendStatus = "ACCEPTED"
|
||||
var FriendStatusDeleted FriendStatus = "DELETED"
|
||||
|
||||
type Friend struct {
|
||||
Person *Person
|
||||
Status FriendStatus
|
||||
Direction FriendDirection
|
||||
}
|
||||
|
||||
func (f *Friend) GenerateSummaryResponse() aid.JSON {
|
||||
return aid.JSON{
|
||||
"accountId": f.Person.ID,
|
||||
"groups": []string{},
|
||||
"mutual": 0,
|
||||
"alias": "",
|
||||
"note": "",
|
||||
"favorite": false,
|
||||
"created": time.Now().Add(-time.Hour * 24 * 7).Format(time.RFC3339),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Friend) GenerateFriendResponse() aid.JSON {
|
||||
return aid.JSON{
|
||||
"accountId": f.Person.ID,
|
||||
"status": f.Status,
|
||||
"direction": f.Direction,
|
||||
"created": time.Now().Add(-time.Hour * 24 * 7).Format(time.RFC3339),
|
||||
"favourite": false,
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ type Person struct {
|
|||
DisplayName string
|
||||
Permissions []string
|
||||
IsBanned bool
|
||||
Friends []string
|
||||
AthenaProfile *Profile
|
||||
CommonCoreProfile *Profile
|
||||
CommonPublicProfile *Profile
|
||||
|
@ -26,7 +25,6 @@ func NewPerson() *Person {
|
|||
DisplayName: uuid.New().String(),
|
||||
Permissions: []string{},
|
||||
IsBanned: false,
|
||||
Friends: []string{},
|
||||
AthenaProfile: NewProfile("athena"),
|
||||
CommonCoreProfile: NewProfile("common_core"),
|
||||
CommonPublicProfile: NewProfile("common_public"),
|
||||
|
@ -42,7 +40,6 @@ func NewPersonWithCustomID(id string) *Person {
|
|||
DisplayName: uuid.New().String(),
|
||||
Permissions: []string{},
|
||||
IsBanned: false,
|
||||
Friends: []string{},
|
||||
AthenaProfile: NewProfile("athena"),
|
||||
CommonCoreProfile: NewProfile("common_core"),
|
||||
CommonPublicProfile: NewProfile("common_public"),
|
||||
|
@ -151,7 +148,6 @@ func findHelper(databasePerson *storage.DB_Person) *Person {
|
|||
DisplayName: databasePerson.DisplayName,
|
||||
Permissions: databasePerson.Permissions,
|
||||
IsBanned: databasePerson.IsBanned,
|
||||
Friends: databasePerson.Friends,
|
||||
AthenaProfile: athenaProfile,
|
||||
CommonCoreProfile: commonCoreProfile,
|
||||
CommonPublicProfile: commonPublicProfile,
|
||||
|
@ -251,71 +247,12 @@ func (p *Person) HasPermission(permission Permission) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (p *Person) AddFriend(friendId string) {
|
||||
p.Friends = append(p.Friends, friendId)
|
||||
p.Save()
|
||||
}
|
||||
|
||||
func (p *Person) RemoveFriend(friendId string) {
|
||||
for i, friend := range p.Friends {
|
||||
if friend == friendId {
|
||||
p.Friends = append(p.Friends[:i], p.Friends[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
p.Save()
|
||||
}
|
||||
|
||||
func (p *Person) GetFriend(friendId string) *Friend {
|
||||
friend := Find(friendId)
|
||||
if friend == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if p.IsFriendInFriendList(friendId) {
|
||||
if friend.IsFriendInFriendList(p.ID) {
|
||||
return &Friend{
|
||||
Person: friend,
|
||||
Status: FriendStatusAccepted,
|
||||
Direction: FriendDirectionBoth,
|
||||
}
|
||||
}
|
||||
|
||||
return &Friend{
|
||||
Person: friend,
|
||||
Status: FriendStatusPending,
|
||||
Direction: FriendDirectionOutgoing,
|
||||
}
|
||||
}
|
||||
|
||||
if friend.IsFriendInFriendList(p.ID) {
|
||||
return &Friend{
|
||||
Person: friend,
|
||||
Status: FriendStatusPending,
|
||||
Direction: FriendDirectionIncoming,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Person) IsFriendInFriendList(friendId string) bool {
|
||||
for _, idA := range p.Friends {
|
||||
if idA == friendId {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Person) ToDatabase() *storage.DB_Person {
|
||||
dbPerson := storage.DB_Person{
|
||||
ID: p.ID,
|
||||
DisplayName: p.DisplayName,
|
||||
Permissions: p.Permissions,
|
||||
IsBanned: p.IsBanned,
|
||||
Friends: p.Friends,
|
||||
Profiles: []storage.DB_Profile{},
|
||||
Stats: []storage.DB_SeasonStat{},
|
||||
Discord: storage.DB_DiscordPerson{},
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *PostgresStorage) GetPerson(personId string) *DB_Person {
|
|||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
// Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
|
@ -80,7 +80,7 @@ func (s *PostgresStorage) GetPersonByDisplay(displayName string) *DB_Person {
|
|||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
// Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
|
@ -103,7 +103,7 @@ func (s *PostgresStorage) GetPersonsByPartialDisplay(displayName string) []*DB_P
|
|||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
// Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
|
@ -138,7 +138,7 @@ func (s *PostgresStorage) GetAllPersons() []*DB_Person {
|
|||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
// Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
|
@ -156,42 +156,6 @@ func (s *PostgresStorage) GetPersonsCount() int {
|
|||
return int(count)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) GetFriendsForPerson(personId string) []*DB_Person {
|
||||
person := s.GetPerson(personId)
|
||||
|
||||
var mine []*DB_Person
|
||||
s.Postgres.
|
||||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
Preload("Profiles.Gifts").
|
||||
Preload("Profiles.Quests").
|
||||
Preload("Discord").
|
||||
Where("id IN (?)", person.Friends).
|
||||
Find(&mine)
|
||||
|
||||
var theirs []*DB_Person
|
||||
s.Postgres.
|
||||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
Preload("Profiles.Gifts").
|
||||
Preload("Profiles.Quests").
|
||||
Preload("Discord").
|
||||
Where("? = ?", person.ID, gorm.Expr("ANY(friends)")).
|
||||
Find(&theirs)
|
||||
|
||||
return append(mine, theirs...)
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) TotalVBucks() int {
|
||||
var total int64
|
||||
s.Postgres.Model(&DB_Item{}).Select("sum(quantity)").Where("template_id = ?", "Currency:MtxPurchased").Find(&total)
|
||||
|
@ -207,7 +171,7 @@ func (s *PostgresStorage) DeletePerson(personId string) {
|
|||
Model(&DB_Person{}).
|
||||
Preload("Profiles").
|
||||
Preload("Profiles.Loadouts").
|
||||
Preload("Profiles.Items.Variants").
|
||||
// Preload("Profiles.Items.Variants").
|
||||
Preload("Profiles.Gifts.Loot").
|
||||
Preload("Profiles.Attributes").
|
||||
Preload("Profiles.Items").
|
||||
|
|
|
@ -19,8 +19,6 @@ type Storage interface {
|
|||
SavePerson(person *DB_Person)
|
||||
DeletePerson(personId string)
|
||||
|
||||
GetFriendsForPerson(personId string) []*DB_Person
|
||||
|
||||
SaveProfile(profile *DB_Profile)
|
||||
DeleteProfile(profileId string)
|
||||
|
||||
|
@ -108,10 +106,6 @@ func (r *Repository) GetPersonsCount() int {
|
|||
return r.Storage.GetPersonsCount()
|
||||
}
|
||||
|
||||
func (r *Repository) GetFriendsForPerson(personId string) []*DB_Person {
|
||||
return r.Storage.GetFriendsForPerson(personId)
|
||||
}
|
||||
|
||||
func (r *Repository) SavePerson(person *DB_Person) {
|
||||
r.Storage.SavePerson(person)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ type DB_Person struct {
|
|||
IsBanned bool
|
||||
Profiles []DB_Profile `gorm:"foreignkey:PersonID"`
|
||||
Stats []DB_SeasonStat `gorm:"foreignkey:PersonID"`
|
||||
Friends pq.StringArray `gorm:"type:text[]"`
|
||||
Discord DB_DiscordPerson `gorm:"foreignkey:PersonID"`
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user