diff --git a/aid/syncer.go b/aid/syncer.go
index f5cae4f..913fc1a 100644
--- a/aid/syncer.go
+++ b/aid/syncer.go
@@ -43,4 +43,16 @@ func (s *GenericSyncMap[T]) Range(f func(key string, value *T) bool) {
func (s *GenericSyncMap[T]) Has(key string) bool {
_, ok := s.Get(key)
return ok
+}
+
+// change the key of a value in the map
+
+func (s *GenericSyncMap[T]) ChangeKey(oldKey, newKey string) {
+ v, ok := s.Get(oldKey)
+ if !ok {
+ return
+ }
+
+ s.Set(newKey, v)
+ s.Delete(oldKey)
}
\ No newline at end of file
diff --git a/fortnite/person.go b/fortnite/person.go
index f2822b3..414ff61 100644
--- a/fortnite/person.go
+++ b/fortnite/person.go
@@ -7,6 +7,7 @@ import (
"github.com/ectrc/snow/aid"
p "github.com/ectrc/snow/person"
"github.com/ectrc/snow/storage"
+ "github.com/google/uuid"
)
var (
@@ -24,7 +25,35 @@ var (
)
func NewFortnitePerson(displayName string, everything bool) *p.Person {
- person := p.NewPerson()
+ return NewFortnitePersonWithId(uuid.New().String(), displayName, everything)
+}
+
+func GiveEverything(person *p.Person) {
+ items := make([]storage.DB_Item, 0)
+
+ for _, item := range Cosmetics.Items {
+ if strings.Contains(strings.ToLower(item.ID), "random") {
+ continue
+ }
+
+ has := person.AthenaProfile.Items.GetItemByTemplateID(item.ID)
+ if has != nil {
+ continue
+ }
+
+ item := p.NewItem(item.Type.BackendValue + ":" + item.ID, 1)
+ item.HasSeen = true
+ person.AthenaProfile.Items.AddItem(item)
+
+ items = append(items, *item.ToDatabase(person.AthenaProfile.ID))
+ }
+
+ storage.Repo.BulkCreateItems(&items)
+ person.Save()
+}
+
+func NewFortnitePersonWithId(id string, displayName string, everything bool) *p.Person {
+ person := p.NewPersonWithCustomID(id)
person.DisplayName = displayName
for _, item := range defaultAthenaItems {
@@ -122,28 +151,4 @@ func NewFortnitePerson(displayName string, everything bool) *p.Person {
person.Save()
return person
-}
-
-func GiveEverything(person *p.Person) {
- items := make([]storage.DB_Item, 0)
-
- for _, item := range Cosmetics.Items {
- if strings.Contains(strings.ToLower(item.ID), "random") {
- continue
- }
-
- has := person.AthenaProfile.Items.GetItemByTemplateID(item.ID)
- if has != nil {
- continue
- }
-
- item := p.NewItem(item.Type.BackendValue + ":" + item.ID, 1)
- item.HasSeen = true
- person.AthenaProfile.Items.AddItem(item)
-
- items = append(items, *item.ToDatabase(person.AthenaProfile.ID))
- }
-
- storage.Repo.BulkCreateItems(&items)
- person.Save()
}
\ No newline at end of file
diff --git a/fortnite/shop.go b/fortnite/shop.go
index b74e16d..a9aced5 100644
--- a/fortnite/shop.go
+++ b/fortnite/shop.go
@@ -10,7 +10,7 @@ import (
var (
Rarities = map[string]map[string]int{
- "EFortRarity::Legendary": map[string]int{
+ "EFortRarity::Legendary": {
"AthenaCharacter": 2000,
"AthenaBackpack": 1500,
"AthenaPickaxe": 1500,
@@ -18,7 +18,7 @@ var (
"AthenaDance": 500,
"AthenaItemWrap": 800,
},
- "EFortRarity::Epic": map[string]int{
+ "EFortRarity::Epic": {
"AthenaCharacter": 1500,
"AthenaBackpack": 1200,
"AthenaPickaxe": 1200,
@@ -26,7 +26,7 @@ var (
"AthenaDance": 800,
"AthenaItemWrap": 800,
},
- "EFortRarity::Rare": map[string]int{
+ "EFortRarity::Rare": {
"AthenaCharacter": 1200,
"AthenaBackpack": 800,
"AthenaPickaxe": 800,
@@ -34,7 +34,7 @@ var (
"AthenaDance": 500,
"AthenaItemWrap": 600,
},
- "EFortRarity::Uncommon": map[string]int{
+ "EFortRarity::Uncommon": {
"AthenaCharacter": 800,
"AthenaBackpack": 200,
"AthenaPickaxe": 500,
@@ -42,7 +42,7 @@ var (
"AthenaDance": 200,
"AthenaItemWrap": 300,
},
- "EFortRarity::Common": map[string]int{
+ "EFortRarity::Common": {
"AthenaCharacter": 500,
"AthenaBackpack": 200,
"AthenaPickaxe": 500,
diff --git a/handlers/friends.go b/handlers/friends.go
index 82def37..e439f1d 100644
--- a/handlers/friends.go
+++ b/handlers/friends.go
@@ -34,22 +34,24 @@ func PostCreateFriend(c *fiber.Ctx) error {
return c.Status(400).JSON(aid.ErrorBadRequest(err.Error()))
}
- from, found := socket.GetJabberSocketByPersonID(relationship.From.ID)
+ from, found := socket.JabberSockets.Get(relationship.From.ID)
if found {
from.JabberSendMessageToPerson(aid.JSON{
"type": "com.epicgames.friends.core.apiobjects.Friend",
"timestamp": time.Now().Format(time.RFC3339),
"payload": relationship.GenerateFortniteFriendEntry(p.GenerateTypeFromPerson),
})
+ from.JabberNotifyFriends()
}
- towards, found := socket.GetJabberSocketByPersonID(relationship.Towards.ID)
+ towards, found := socket.JabberSockets.Get(relationship.Towards.ID)
if found {
towards.JabberSendMessageToPerson(aid.JSON{
"type": "com.epicgames.friends.core.apiobjects.Friend",
"timestamp": time.Now().Format(time.RFC3339),
"payload": relationship.GenerateFortniteFriendEntry(p.GenerateTypeTowardsPerson),
})
+ towards.JabberNotifyFriends()
}
return c.SendStatus(204)
diff --git a/handlers/socket.go b/handlers/socket.go
index 8efda12..8ff3330 100644
--- a/handlers/socket.go
+++ b/handlers/socket.go
@@ -44,9 +44,9 @@ func WebsocketConnection(c *websocket.Conn) {
}
func GetConnectedSockets(c *fiber.Ctx) error {
- jabber := []socket.Socket[socket.JabberData]{}
+ jabber := map[string]socket.Socket[socket.JabberData]{}
socket.JabberSockets.Range(func(key string, value *socket.Socket[socket.JabberData]) bool {
- jabber = append(jabber, *value)
+ jabber[key] = *value
return true
})
diff --git a/main.go b/main.go
index 05bb62c..e8b087a 100644
--- a/main.go
+++ b/main.go
@@ -46,9 +46,13 @@ func init() {
fortnite.GeneratePlaylistImages()
if found := person.FindByDisplay("god"); found == nil {
- god := fortnite.NewFortnitePerson("god", true)
+ god := fortnite.NewFortnitePersonWithId("god", "god", true)
god.AddPermission("all")
+
+ angel := fortnite.NewFortnitePersonWithId("angel", "angel", true)
+ angel.AddPermission("all")
}
+
}
func main() {
r := fiber.New(fiber.Config{
@@ -57,6 +61,7 @@ func main() {
JSONDecoder: json.Unmarshal,
})
+
r.Use(aid.FiberLogger())
r.Use(aid.FiberLimiter())
r.Use(aid.FiberCors())
diff --git a/person/person.go b/person/person.go
index b4e4534..10b2591 100644
--- a/person/person.go
+++ b/person/person.go
@@ -84,7 +84,7 @@ func FindShallow(personId string) *Person {
return nil
}
- return findHelper(person, true, true)
+ return findHelper(person, true, false)
}
func FindByDisplay(displayName string) *Person {
@@ -120,7 +120,7 @@ func FindByDisplayShallow(displayName string) *Person {
return nil
}
- return findHelper(person, true, true)
+ return findHelper(person, true, false)
}
func FindByDiscord(discordId string) *Person {
diff --git a/person/relationships.go b/person/relationships.go
index 84fb3d4..2d2e171 100644
--- a/person/relationships.go
+++ b/person/relationships.go
@@ -39,13 +39,15 @@ func (r *Relationship) GenerateFortniteFriendEntry(t RelationshipGenerateType) a
switch t {
case GenerateTypeFromPerson:
- result["direction"] = "OUTBOUND"
+ result["direction"] = RelationshipOutboundDirection
result["accountId"] = r.Towards.ID
case GenerateTypeTowardsPerson:
- result["direction"] = "INBOUND"
+ result["direction"] = RelationshipInboundDirection
result["accountId"] = r.From.ID
}
+ aid.PrintJSON(result)
+
return result
}
@@ -65,7 +67,7 @@ func (p *Person) LoadRelationships() {
incoming := storage.Repo.Storage.GetIncomingRelationships(p.ID)
for _, entry := range incoming {
relationship := &Relationship{
- From: Find(entry.FromPersonID),
+ From: FindShallow(entry.FromPersonID),
Towards: p,
Status: entry.Status,
Direction: RelationshipInboundDirection,
@@ -73,6 +75,18 @@ func (p *Person) LoadRelationships() {
p.Relationships.Set(entry.FromPersonID, relationship)
}
+
+ outgoing := storage.Repo.Storage.GetOutgoingRelationships(p.ID)
+ for _, entry := range outgoing {
+ relationship := &Relationship{
+ From: p,
+ Towards: FindShallow(entry.TowardsPersonID),
+ Status: entry.Status,
+ Direction: RelationshipOutboundDirection,
+ }
+
+ p.Relationships.Set(entry.FromPersonID, relationship)
+ }
}
func (p *Person) CreateRelationship(personId string) (*Relationship, error) {
@@ -95,7 +109,7 @@ func (p *Person) CreateRelationship(personId string) (*Relationship, error) {
func (p *Person) createOutboundRelationship(towards string) (*Relationship, error) {
relationship := &Relationship{
From: p,
- Towards: Find(towards),
+ Towards: FindShallow(towards),
Status: "PENDING",
Direction: RelationshipOutboundDirection,
}
@@ -104,7 +118,7 @@ func (p *Person) createOutboundRelationship(towards string) (*Relationship, erro
func (p *Person) createAcceptInboundRelationship(towards string) (*Relationship, error) {
relationship := &Relationship{
- From: Find(towards),
+ From: FindShallow(towards),
Towards: p,
Status: "ACCEPTED",
Direction: RelationshipInboundDirection,
diff --git a/socket/jabber.go b/socket/jabber.go
index c8f1759..0f7fb6e 100644
--- a/socket/jabber.go
+++ b/socket/jabber.go
@@ -12,11 +12,14 @@ import (
type JabberData struct {
JabberID string
+ LastPresence string
}
var jabberHandlers = map[string]func(*Socket[JabberData], *etree.Document) error {
"open": jabberOpenHandler,
"iq": jabberIqRootHandler,
+ "presence": jabberPresenceHandler,
+ "message": jabberMessageHandler,
}
func HandleNewJabberSocket(identifier string) {
@@ -24,7 +27,7 @@ func HandleNewJabberSocket(identifier string) {
if !ok {
return
}
- defer JabberSockets.Delete(identifier)
+ defer JabberSockets.Delete(socket.ID)
for {
_, message, failed := socket.Connection.ReadMessage()
@@ -49,8 +52,8 @@ func HandleNewJabberSocket(identifier string) {
}
func jabberOpenHandler(socket *Socket[JabberData], parsed *etree.Document) error {
- socket.Connection.WriteMessage(websocket.TextMessage, []byte(``))
- socket.Connection.WriteMessage(websocket.TextMessage, []byte(``))
+ socket.Write([]byte(``))
+ socket.Write([]byte(``))
return nil
}
@@ -81,32 +84,30 @@ func jabberIqSetHandler(socket *Socket[JabberData], parsed *etree.Document) erro
return fmt.Errorf("person not found")
}
- socket.Data.JabberID = snowId + "@prod.ol.epicgames.com/" + parsed.FindElement("/iq/query/resource").Text()
+ JabberSockets.ChangeKey(socket.ID, person.ID)
+ socket.ID = person.ID
socket.Person = person
+ socket.Data.JabberID = snowId + "@prod.ol.epicgames.com/" + parsed.FindElement("/iq/query/resource").Text()
- socket.Connection.WriteMessage(websocket.TextMessage, []byte(``))
+ socket.Write([]byte(``))
return nil
}
-
func jabberIqGetHandler(socket *Socket[JabberData], parsed *etree.Document) error {
- socket.Connection.WriteMessage(websocket.TextMessage, []byte(``))
+ socket.Write([]byte(``))
+ socket.JabberNotifyFriends()
return nil
}
-func GetJabberSocketByPersonID(id string) (*Socket[JabberData], bool) {
- var found *Socket[JabberData]
+func jabberPresenceHandler(socket *Socket[JabberData], parsed *etree.Document) error {
+ socket.Data.LastPresence = parsed.FindElement("/presence/status").Text()
+ socket.JabberNotifyFriends()
+ return nil
+}
- JabberSockets.Range(func(key string, socket *Socket[JabberData]) bool {
- if socket.Person.ID == id {
- found = socket
- return false
- }
+func jabberMessageHandler(socket *Socket[JabberData], parsed *etree.Document) error {
- return true
- })
-
- return found, found != nil
+ return nil
}
func (s *Socket[T]) JabberSendMessageToPerson(data aid.JSON) {
@@ -120,11 +121,39 @@ func (s *Socket[T]) JabberSendMessageToPerson(data aid.JSON) {
return
}
- aid.Print(`
- `+ string(data.ToBytes()) +`
- `)
-
- s.Connection.WriteMessage(1, []byte(`
+ s.Write([]byte(`
`+ string(data.ToBytes()) +`
`))
+}
+
+func (s *Socket[T]) JabberNotifyFriends() {
+ if reflect.TypeOf(s.Data) != reflect.TypeOf(&JabberData{}) {
+ return
+ }
+
+ jabberSocket, ok := JabberSockets.Get(s.ID)
+ if !ok {
+ aid.Print("jabber socket not found even though it should be")
+ return
+ }
+
+ s.Person.Relationships.Range(func(key string, value *person.Relationship) bool {
+ friendSocket, found := JabberSockets.Get(value.From.ID)
+ if value.Direction == person.RelationshipOutboundDirection {
+ friendSocket, found = JabberSockets.Get(value.Towards.ID)
+ }
+ if !found {
+ return true
+ }
+
+ friendSocket.Write([]byte(`
+ `+ jabberSocket.Data.LastPresence +`
+ `))
+
+ jabberSocket.Write([]byte(`
+ `+ friendSocket.Data.LastPresence +`
+ `))
+
+ return true
+ })
}
\ No newline at end of file
diff --git a/socket/socket.go b/socket/socket.go
index 989149f..99e6628 100644
--- a/socket/socket.go
+++ b/socket/socket.go
@@ -1,6 +1,8 @@
package socket
import (
+ "sync"
+
"github.com/ectrc/snow/aid"
"github.com/ectrc/snow/person"
"github.com/gofiber/contrib/websocket"
@@ -17,6 +19,14 @@ type Socket[T JabberData | MatchmakerData] struct {
Connection *websocket.Conn
Data *T
Person *person.Person
+ mutex sync.Mutex
+}
+
+func (s *Socket[T]) Write(payload []byte) {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ s.Connection.WriteMessage(websocket.TextMessage, payload)
}
func newSocket[T JabberData | MatchmakerData](conn *websocket.Conn, data ...T) *Socket[T] {