snow/socket/jabber.go

178 lines
5.0 KiB
Go
Raw Normal View History

2024-01-28 22:04:40 +00:00
package socket
2024-01-29 21:08:05 +00:00
import (
"fmt"
2024-01-29 23:46:22 +00:00
"reflect"
2024-01-31 00:36:47 +00:00
"strings"
2024-01-29 21:08:05 +00:00
"github.com/beevik/etree"
"github.com/ectrc/snow/aid"
"github.com/ectrc/snow/person"
"github.com/gofiber/contrib/websocket"
)
type JabberData struct {
JabberID string
LastPresence string
2024-01-29 21:08:05 +00:00
}
var jabberHandlers = map[string]func(*Socket[JabberData], *etree.Document) error {
"open": jabberOpenHandler,
"iq": jabberIqRootHandler,
"presence": jabberPresenceHandler,
"message": jabberMessageHandler,
2024-01-29 21:08:05 +00:00
}
2024-01-28 22:04:40 +00:00
func HandleNewJabberSocket(identifier string) {
2024-01-29 21:08:05 +00:00
socket, ok := JabberSockets.Get(identifier)
2024-01-28 22:04:40 +00:00
if !ok {
return
}
defer JabberSockets.Delete(socket.ID)
2024-01-29 21:08:05 +00:00
for {
_, message, failed := socket.Connection.ReadMessage()
if failed != nil {
break
}
parsed := etree.NewDocument()
if err := parsed.ReadFromBytes(message); err != nil {
return
}
if handler, ok := jabberHandlers[parsed.Root().Tag]; ok {
if err := handler(socket, parsed); err != nil {
socket.Connection.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, err.Error()))
return
}
}
}
}
func jabberOpenHandler(socket *Socket[JabberData], parsed *etree.Document) error {
socket.Write([]byte(`<open xmlns="urn:ietf:params:xml:ns:xmpp-framing" from="prod.ol.epicgames.com" version="1.0" id="`+ socket.ID +`" />`))
socket.Write([]byte(`<stream:features xmlns:stream="http://etherx.jabber.org/streams" />`))
2024-01-29 21:08:05 +00:00
return nil
}
func jabberIqRootHandler(socket *Socket[JabberData], parsed *etree.Document) error {
redirect := map[string]func(*Socket[JabberData], *etree.Document) error {
"set": jabberIqSetHandler,
"get": jabberIqGetHandler,
}
if handler, ok := redirect[parsed.Root().SelectAttr("type").Value]; ok {
if err := handler(socket, parsed); err != nil {
return err
}
}
return nil
}
func jabberIqSetHandler(socket *Socket[JabberData], parsed *etree.Document) error {
snowId, err := aid.GetSnowFromToken(parsed.FindElement("/iq/query/password").Text())
if err != nil {
return err
}
person := person.Find(snowId)
if person == nil {
return fmt.Errorf("person not found")
}
JabberSockets.ChangeKey(socket.ID, person.ID)
socket.ID = person.ID
2024-01-29 21:08:05 +00:00
socket.Person = person
socket.Data.JabberID = snowId + "@prod.ol.epicgames.com/" + parsed.FindElement("/iq/query/resource").Text()
2024-01-29 21:08:05 +00:00
socket.Write([]byte(`<iq xmlns="jabber:client" type="result" id="_xmpp_auth1" from="prod.ol.epicgames.com" to="`+ socket.Data.JabberID +`" />`))
2024-01-29 21:08:05 +00:00
return nil
}
func jabberIqGetHandler(socket *Socket[JabberData], parsed *etree.Document) error {
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()
2024-01-29 21:08:05 +00:00
return nil
2024-01-29 23:46:22 +00:00
}
func jabberPresenceHandler(socket *Socket[JabberData], parsed *etree.Document) error {
2024-01-31 00:36:47 +00:00
status := parsed.FindElement("/presence/status")
if status == nil {
return nil
}
socket.Data.LastPresence = status.Text()
socket.JabberNotifyFriends()
return nil
}
2024-01-29 23:46:22 +00:00
func jabberMessageHandler(socket *Socket[JabberData], parsed *etree.Document) error {
2024-01-31 00:36:47 +00:00
if parsed.FindElement("/message/body") == nil {
return nil
}
message := parsed.FindElement("/message")
target := message.SelectAttr("to").Value
parts := strings.Split(target, "@")
2024-01-29 23:46:22 +00:00
2024-01-31 00:36:47 +00:00
if len(parts) != 2 {
return nil
}
if reciever, ok := JabberSockets.Get(parts[0]); ok {
reciever.Write([]byte(`<message xmlns="jabber:client" from="`+ socket.Data.JabberID +`" to="`+ target +`" id="`+ message.SelectAttr("id").Value +`">
<body>`+ message.FindElement("/message/body").Text() +`</body>
</message>`))
}
return nil
2024-01-29 23:46:22 +00:00
}
func (s *Socket[T]) JabberSendMessageToPerson(data aid.JSON) {
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.Write([]byte(`<message xmlns="jabber:client" from="xmpp-admin@prod.ol.epicgames.com" to="`+ jabberSocket.Data.JabberID +`">
2024-01-29 23:46:22 +00:00
<body>`+ string(data.ToBytes()) +`</body>
</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
})
2024-01-28 22:04:40 +00:00
}