Friends rereimplemented + add mutex to stop concurrent writes to webscoket
This commit is contained in:
parent
9275e8fcd4
commit
1ebe963b2d
|
@ -43,4 +43,16 @@ func (s *GenericSyncMap[T]) Range(f func(key string, value *T) bool) {
|
||||||
func (s *GenericSyncMap[T]) Has(key string) bool {
|
func (s *GenericSyncMap[T]) Has(key string) bool {
|
||||||
_, ok := s.Get(key)
|
_, ok := s.Get(key)
|
||||||
return ok
|
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)
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
p "github.com/ectrc/snow/person"
|
p "github.com/ectrc/snow/person"
|
||||||
"github.com/ectrc/snow/storage"
|
"github.com/ectrc/snow/storage"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -24,7 +25,35 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewFortnitePerson(displayName string, everything bool) *p.Person {
|
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
|
person.DisplayName = displayName
|
||||||
|
|
||||||
for _, item := range defaultAthenaItems {
|
for _, item := range defaultAthenaItems {
|
||||||
|
@ -122,28 +151,4 @@ func NewFortnitePerson(displayName string, everything bool) *p.Person {
|
||||||
person.Save()
|
person.Save()
|
||||||
|
|
||||||
return person
|
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()
|
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Rarities = map[string]map[string]int{
|
Rarities = map[string]map[string]int{
|
||||||
"EFortRarity::Legendary": map[string]int{
|
"EFortRarity::Legendary": {
|
||||||
"AthenaCharacter": 2000,
|
"AthenaCharacter": 2000,
|
||||||
"AthenaBackpack": 1500,
|
"AthenaBackpack": 1500,
|
||||||
"AthenaPickaxe": 1500,
|
"AthenaPickaxe": 1500,
|
||||||
|
@ -18,7 +18,7 @@ var (
|
||||||
"AthenaDance": 500,
|
"AthenaDance": 500,
|
||||||
"AthenaItemWrap": 800,
|
"AthenaItemWrap": 800,
|
||||||
},
|
},
|
||||||
"EFortRarity::Epic": map[string]int{
|
"EFortRarity::Epic": {
|
||||||
"AthenaCharacter": 1500,
|
"AthenaCharacter": 1500,
|
||||||
"AthenaBackpack": 1200,
|
"AthenaBackpack": 1200,
|
||||||
"AthenaPickaxe": 1200,
|
"AthenaPickaxe": 1200,
|
||||||
|
@ -26,7 +26,7 @@ var (
|
||||||
"AthenaDance": 800,
|
"AthenaDance": 800,
|
||||||
"AthenaItemWrap": 800,
|
"AthenaItemWrap": 800,
|
||||||
},
|
},
|
||||||
"EFortRarity::Rare": map[string]int{
|
"EFortRarity::Rare": {
|
||||||
"AthenaCharacter": 1200,
|
"AthenaCharacter": 1200,
|
||||||
"AthenaBackpack": 800,
|
"AthenaBackpack": 800,
|
||||||
"AthenaPickaxe": 800,
|
"AthenaPickaxe": 800,
|
||||||
|
@ -34,7 +34,7 @@ var (
|
||||||
"AthenaDance": 500,
|
"AthenaDance": 500,
|
||||||
"AthenaItemWrap": 600,
|
"AthenaItemWrap": 600,
|
||||||
},
|
},
|
||||||
"EFortRarity::Uncommon": map[string]int{
|
"EFortRarity::Uncommon": {
|
||||||
"AthenaCharacter": 800,
|
"AthenaCharacter": 800,
|
||||||
"AthenaBackpack": 200,
|
"AthenaBackpack": 200,
|
||||||
"AthenaPickaxe": 500,
|
"AthenaPickaxe": 500,
|
||||||
|
@ -42,7 +42,7 @@ var (
|
||||||
"AthenaDance": 200,
|
"AthenaDance": 200,
|
||||||
"AthenaItemWrap": 300,
|
"AthenaItemWrap": 300,
|
||||||
},
|
},
|
||||||
"EFortRarity::Common": map[string]int{
|
"EFortRarity::Common": {
|
||||||
"AthenaCharacter": 500,
|
"AthenaCharacter": 500,
|
||||||
"AthenaBackpack": 200,
|
"AthenaBackpack": 200,
|
||||||
"AthenaPickaxe": 500,
|
"AthenaPickaxe": 500,
|
||||||
|
|
|
@ -34,22 +34,24 @@ func PostCreateFriend(c *fiber.Ctx) error {
|
||||||
return c.Status(400).JSON(aid.ErrorBadRequest(err.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 {
|
if found {
|
||||||
from.JabberSendMessageToPerson(aid.JSON{
|
from.JabberSendMessageToPerson(aid.JSON{
|
||||||
"type": "com.epicgames.friends.core.apiobjects.Friend",
|
"type": "com.epicgames.friends.core.apiobjects.Friend",
|
||||||
"timestamp": time.Now().Format(time.RFC3339),
|
"timestamp": time.Now().Format(time.RFC3339),
|
||||||
"payload": relationship.GenerateFortniteFriendEntry(p.GenerateTypeFromPerson),
|
"payload": relationship.GenerateFortniteFriendEntry(p.GenerateTypeFromPerson),
|
||||||
})
|
})
|
||||||
|
from.JabberNotifyFriends()
|
||||||
}
|
}
|
||||||
|
|
||||||
towards, found := socket.GetJabberSocketByPersonID(relationship.Towards.ID)
|
towards, found := socket.JabberSockets.Get(relationship.Towards.ID)
|
||||||
if found {
|
if found {
|
||||||
towards.JabberSendMessageToPerson(aid.JSON{
|
towards.JabberSendMessageToPerson(aid.JSON{
|
||||||
"type": "com.epicgames.friends.core.apiobjects.Friend",
|
"type": "com.epicgames.friends.core.apiobjects.Friend",
|
||||||
"timestamp": time.Now().Format(time.RFC3339),
|
"timestamp": time.Now().Format(time.RFC3339),
|
||||||
"payload": relationship.GenerateFortniteFriendEntry(p.GenerateTypeTowardsPerson),
|
"payload": relationship.GenerateFortniteFriendEntry(p.GenerateTypeTowardsPerson),
|
||||||
})
|
})
|
||||||
|
towards.JabberNotifyFriends()
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SendStatus(204)
|
return c.SendStatus(204)
|
||||||
|
|
|
@ -44,9 +44,9 @@ func WebsocketConnection(c *websocket.Conn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConnectedSockets(c *fiber.Ctx) error {
|
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 {
|
socket.JabberSockets.Range(func(key string, value *socket.Socket[socket.JabberData]) bool {
|
||||||
jabber = append(jabber, *value)
|
jabber[key] = *value
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
7
main.go
7
main.go
|
@ -46,9 +46,13 @@ func init() {
|
||||||
fortnite.GeneratePlaylistImages()
|
fortnite.GeneratePlaylistImages()
|
||||||
|
|
||||||
if found := person.FindByDisplay("god"); found == nil {
|
if found := person.FindByDisplay("god"); found == nil {
|
||||||
god := fortnite.NewFortnitePerson("god", true)
|
god := fortnite.NewFortnitePersonWithId("god", "god", true)
|
||||||
god.AddPermission("all")
|
god.AddPermission("all")
|
||||||
|
|
||||||
|
angel := fortnite.NewFortnitePersonWithId("angel", "angel", true)
|
||||||
|
angel.AddPermission("all")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
func main() {
|
func main() {
|
||||||
r := fiber.New(fiber.Config{
|
r := fiber.New(fiber.Config{
|
||||||
|
@ -57,6 +61,7 @@ func main() {
|
||||||
JSONDecoder: json.Unmarshal,
|
JSONDecoder: json.Unmarshal,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
r.Use(aid.FiberLogger())
|
r.Use(aid.FiberLogger())
|
||||||
r.Use(aid.FiberLimiter())
|
r.Use(aid.FiberLimiter())
|
||||||
r.Use(aid.FiberCors())
|
r.Use(aid.FiberCors())
|
||||||
|
|
|
@ -84,7 +84,7 @@ func FindShallow(personId string) *Person {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return findHelper(person, true, true)
|
return findHelper(person, true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindByDisplay(displayName string) *Person {
|
func FindByDisplay(displayName string) *Person {
|
||||||
|
@ -120,7 +120,7 @@ func FindByDisplayShallow(displayName string) *Person {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return findHelper(person, true, true)
|
return findHelper(person, true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindByDiscord(discordId string) *Person {
|
func FindByDiscord(discordId string) *Person {
|
||||||
|
|
|
@ -39,13 +39,15 @@ func (r *Relationship) GenerateFortniteFriendEntry(t RelationshipGenerateType) a
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
case GenerateTypeFromPerson:
|
case GenerateTypeFromPerson:
|
||||||
result["direction"] = "OUTBOUND"
|
result["direction"] = RelationshipOutboundDirection
|
||||||
result["accountId"] = r.Towards.ID
|
result["accountId"] = r.Towards.ID
|
||||||
case GenerateTypeTowardsPerson:
|
case GenerateTypeTowardsPerson:
|
||||||
result["direction"] = "INBOUND"
|
result["direction"] = RelationshipInboundDirection
|
||||||
result["accountId"] = r.From.ID
|
result["accountId"] = r.From.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aid.PrintJSON(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +67,7 @@ func (p *Person) LoadRelationships() {
|
||||||
incoming := storage.Repo.Storage.GetIncomingRelationships(p.ID)
|
incoming := storage.Repo.Storage.GetIncomingRelationships(p.ID)
|
||||||
for _, entry := range incoming {
|
for _, entry := range incoming {
|
||||||
relationship := &Relationship{
|
relationship := &Relationship{
|
||||||
From: Find(entry.FromPersonID),
|
From: FindShallow(entry.FromPersonID),
|
||||||
Towards: p,
|
Towards: p,
|
||||||
Status: entry.Status,
|
Status: entry.Status,
|
||||||
Direction: RelationshipInboundDirection,
|
Direction: RelationshipInboundDirection,
|
||||||
|
@ -73,6 +75,18 @@ func (p *Person) LoadRelationships() {
|
||||||
|
|
||||||
p.Relationships.Set(entry.FromPersonID, relationship)
|
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) {
|
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) {
|
func (p *Person) createOutboundRelationship(towards string) (*Relationship, error) {
|
||||||
relationship := &Relationship{
|
relationship := &Relationship{
|
||||||
From: p,
|
From: p,
|
||||||
Towards: Find(towards),
|
Towards: FindShallow(towards),
|
||||||
Status: "PENDING",
|
Status: "PENDING",
|
||||||
Direction: RelationshipOutboundDirection,
|
Direction: RelationshipOutboundDirection,
|
||||||
}
|
}
|
||||||
|
@ -104,7 +118,7 @@ func (p *Person) createOutboundRelationship(towards string) (*Relationship, erro
|
||||||
|
|
||||||
func (p *Person) createAcceptInboundRelationship(towards string) (*Relationship, error) {
|
func (p *Person) createAcceptInboundRelationship(towards string) (*Relationship, error) {
|
||||||
relationship := &Relationship{
|
relationship := &Relationship{
|
||||||
From: Find(towards),
|
From: FindShallow(towards),
|
||||||
Towards: p,
|
Towards: p,
|
||||||
Status: "ACCEPTED",
|
Status: "ACCEPTED",
|
||||||
Direction: RelationshipInboundDirection,
|
Direction: RelationshipInboundDirection,
|
||||||
|
|
|
@ -12,11 +12,14 @@ import (
|
||||||
|
|
||||||
type JabberData struct {
|
type JabberData struct {
|
||||||
JabberID string
|
JabberID string
|
||||||
|
LastPresence string
|
||||||
}
|
}
|
||||||
|
|
||||||
var jabberHandlers = map[string]func(*Socket[JabberData], *etree.Document) error {
|
var jabberHandlers = map[string]func(*Socket[JabberData], *etree.Document) error {
|
||||||
"open": jabberOpenHandler,
|
"open": jabberOpenHandler,
|
||||||
"iq": jabberIqRootHandler,
|
"iq": jabberIqRootHandler,
|
||||||
|
"presence": jabberPresenceHandler,
|
||||||
|
"message": jabberMessageHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleNewJabberSocket(identifier string) {
|
func HandleNewJabberSocket(identifier string) {
|
||||||
|
@ -24,7 +27,7 @@ func HandleNewJabberSocket(identifier string) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer JabberSockets.Delete(identifier)
|
defer JabberSockets.Delete(socket.ID)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, message, failed := socket.Connection.ReadMessage()
|
_, message, failed := socket.Connection.ReadMessage()
|
||||||
|
@ -49,8 +52,8 @@ func HandleNewJabberSocket(identifier string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func jabberOpenHandler(socket *Socket[JabberData], parsed *etree.Document) error {
|
func jabberOpenHandler(socket *Socket[JabberData], parsed *etree.Document) error {
|
||||||
socket.Connection.WriteMessage(websocket.TextMessage, []byte(`<open xmlns="urn:ietf:params:xml:ns:xmpp-framing" from="prod.ol.epicgames.com" version="1.0" id="`+ socket.ID +`" />`))
|
socket.Write([]byte(`<open xmlns="urn:ietf:params:xml:ns:xmpp-framing" from="prod.ol.epicgames.com" version="1.0" id="`+ socket.ID +`" />`))
|
||||||
socket.Connection.WriteMessage(websocket.TextMessage, []byte(`<stream:features xmlns:stream="http://etherx.jabber.org/streams" />`))
|
socket.Write([]byte(`<stream:features xmlns:stream="http://etherx.jabber.org/streams" />`))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -81,32 +84,30 @@ func jabberIqSetHandler(socket *Socket[JabberData], parsed *etree.Document) erro
|
||||||
return fmt.Errorf("person not found")
|
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.Person = person
|
||||||
|
socket.Data.JabberID = snowId + "@prod.ol.epicgames.com/" + parsed.FindElement("/iq/query/resource").Text()
|
||||||
|
|
||||||
socket.Connection.WriteMessage(websocket.TextMessage, []byte(`<iq xmlns="jabber:client" type="result" id="_xmpp_auth1" from="prod.ol.epicgames.com" to="`+ socket.Data.JabberID +`" />`))
|
socket.Write([]byte(`<iq xmlns="jabber:client" type="result" id="_xmpp_auth1" from="prod.ol.epicgames.com" to="`+ socket.Data.JabberID +`" />`))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func jabberIqGetHandler(socket *Socket[JabberData], parsed *etree.Document) error {
|
func jabberIqGetHandler(socket *Socket[JabberData], parsed *etree.Document) error {
|
||||||
socket.Connection.WriteMessage(websocket.TextMessage, []byte(`<iq xmlns="jabber:client" type="result" id="`+ parsed.Root().SelectAttr("id").Value +`" from="prod.ol.epicgames.com" to="`+ socket.Data.JabberID +`" />`))
|
socket.Write([]byte(`<iq xmlns="jabber:client" type="result" id="`+ parsed.Root().SelectAttr("id").Value +`" from="prod.ol.epicgames.com" to="`+ socket.Data.JabberID +`" />`))
|
||||||
|
socket.JabberNotifyFriends()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetJabberSocketByPersonID(id string) (*Socket[JabberData], bool) {
|
func jabberPresenceHandler(socket *Socket[JabberData], parsed *etree.Document) error {
|
||||||
var found *Socket[JabberData]
|
socket.Data.LastPresence = parsed.FindElement("/presence/status").Text()
|
||||||
|
socket.JabberNotifyFriends()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
JabberSockets.Range(func(key string, socket *Socket[JabberData]) bool {
|
func jabberMessageHandler(socket *Socket[JabberData], parsed *etree.Document) error {
|
||||||
if socket.Person.ID == id {
|
|
||||||
found = socket
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
return nil
|
||||||
})
|
|
||||||
|
|
||||||
return found, found != nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Socket[T]) JabberSendMessageToPerson(data aid.JSON) {
|
func (s *Socket[T]) JabberSendMessageToPerson(data aid.JSON) {
|
||||||
|
@ -120,11 +121,39 @@ func (s *Socket[T]) JabberSendMessageToPerson(data aid.JSON) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
aid.Print(`<message xmlns="jabber:client" from="xmpp-admin@prod.ol.epicgames.com" to="`+ jabberSocket.Data.JabberID +`">
|
s.Write([]byte(`<message xmlns="jabber:client" from="xmpp-admin@prod.ol.epicgames.com" to="`+ jabberSocket.Data.JabberID +`">
|
||||||
<body>`+ string(data.ToBytes()) +`</body>
|
|
||||||
</message>`)
|
|
||||||
|
|
||||||
s.Connection.WriteMessage(1, []byte(`<message xmlns="jabber:client" from="xmpp-admin@prod.ol.epicgames.com" to="`+ jabberSocket.Data.JabberID +`">
|
|
||||||
<body>`+ string(data.ToBytes()) +`</body>
|
<body>`+ string(data.ToBytes()) +`</body>
|
||||||
</message>`))
|
</message>`))
|
||||||
|
}
|
||||||
|
|
||||||
|
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(`<presence xmlns="jabber:client" type="available" from="`+ jabberSocket.Data.JabberID +`" to="`+ friendSocket.Data.JabberID +`">
|
||||||
|
<status>`+ jabberSocket.Data.LastPresence +`</status>
|
||||||
|
</presence>`))
|
||||||
|
|
||||||
|
jabberSocket.Write([]byte(`<presence xmlns="jabber:client" type="available" from="`+ friendSocket.Data.JabberID +`" to="`+ jabberSocket.Data.JabberID +`">
|
||||||
|
<status>`+ friendSocket.Data.LastPresence +`</status>
|
||||||
|
</presence>`))
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
}
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package socket
|
package socket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/ectrc/snow/aid"
|
"github.com/ectrc/snow/aid"
|
||||||
"github.com/ectrc/snow/person"
|
"github.com/ectrc/snow/person"
|
||||||
"github.com/gofiber/contrib/websocket"
|
"github.com/gofiber/contrib/websocket"
|
||||||
|
@ -17,6 +19,14 @@ type Socket[T JabberData | MatchmakerData] struct {
|
||||||
Connection *websocket.Conn
|
Connection *websocket.Conn
|
||||||
Data *T
|
Data *T
|
||||||
Person *person.Person
|
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] {
|
func newSocket[T JabberData | MatchmakerData](conn *websocket.Conn, data ...T) *Socket[T] {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user