mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-11-22 04:29:47 -05:00
split out message delivery routine
This commit is contained in:
parent
19cf364c78
commit
68b315345b
2 changed files with 81 additions and 60 deletions
62
main.go
62
main.go
|
@ -74,66 +74,8 @@ func main() {
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
// Goroutine that listens for messages to deliver and tries to find a user socket to push them to
|
// Goroutine that listens for messages to deliver and tries to find a user socket to push them to
|
||||||
commCh := make(chan *models.Message, 1)
|
commCh, messageRoutine := MessageDelivery()
|
||||||
go func() {
|
go messageRoutine(db)
|
||||||
for {
|
|
||||||
message, more := <-commCh
|
|
||||||
if !more {
|
|
||||||
log.Printf("message delivery routine shutting down")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("got a message: %s", message)
|
|
||||||
if s, ok := sessions[message.To]; ok {
|
|
||||||
messageSnac := oscar.NewSNAC(4, 7)
|
|
||||||
messageSnac.Data.WriteUint64(message.MessageID)
|
|
||||||
messageSnac.Data.WriteUint16(1)
|
|
||||||
messageSnac.Data.WriteLPString(message.From)
|
|
||||||
messageSnac.Data.WriteUint16(0) // TODO: sender's warning level
|
|
||||||
|
|
||||||
tlvs := []*oscar.TLV{
|
|
||||||
oscar.NewTLV(1, util.Word(0x80)), // TODO: user class
|
|
||||||
oscar.NewTLV(6, util.Dword(0x0001|0x0100)), // TODO: user status
|
|
||||||
oscar.NewTLV(0xf, util.Dword(0)), // TODO: user idle time
|
|
||||||
oscar.NewTLV(3, util.Dword(0)), // TODO: user creation time
|
|
||||||
// oscar.NewTLV(4, []byte{}), // TODO: this TLV appears in automated responses like away messages
|
|
||||||
}
|
|
||||||
|
|
||||||
// Length of TLVs in fixed part
|
|
||||||
messageSnac.Data.WriteUint16(uint16(len(tlvs)))
|
|
||||||
|
|
||||||
// Write all of the TLVs to the SNAC
|
|
||||||
for _, tlv := range tlvs {
|
|
||||||
messageSnac.Data.WriteBinary(tlv)
|
|
||||||
}
|
|
||||||
|
|
||||||
frag := oscar.Buffer{}
|
|
||||||
frag.Write([]byte{5, 1, 0, 4, 1, 1, 1, 1}) // TODO: first fragment [id, version, len, len, (cap * len)... ]
|
|
||||||
frag.Write([]byte{1, 1}) // message text fragment start (this is a busted "TLV")
|
|
||||||
frag.Write(util.Word(uint16(len(message.Contents) + 4))) // length of TLV
|
|
||||||
frag.Write([]byte{0, 0, 0, 0}) // TODO: message charset number, message charset subset
|
|
||||||
frag.WriteString(message.Contents)
|
|
||||||
|
|
||||||
// Append the fragments
|
|
||||||
messageSnac.Data.Write(frag.Bytes())
|
|
||||||
|
|
||||||
messageFlap := oscar.NewFLAP(2)
|
|
||||||
messageFlap.Data.WriteBinary(messageSnac)
|
|
||||||
if err := s.Send(messageFlap); err != nil {
|
|
||||||
log.Panicf("could not deliver message %d: %s", message.MessageID, err.Error())
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
log.Printf("sent message %d to user %s at %s", message.MessageID, message.To, s.RemoteAddr())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := message.MarkDelivered(context.Background(), db); err != nil {
|
|
||||||
log.Panicf("could not mark message %d as delivered: %s", message.MessageID, err.Error())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Printf("could not find session for user %s", message.To)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
handleCloseFn := func(ctx context.Context, session *oscar.Session) {
|
handleCloseFn := func(ctx context.Context, session *oscar.Session) {
|
||||||
log.Printf("%v disconnected", session.RemoteAddr())
|
log.Printf("%v disconnected", session.RemoteAddr())
|
||||||
|
|
79
message_delivery_routine.go
Normal file
79
message_delivery_routine.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"aim-oscar/models"
|
||||||
|
"aim-oscar/oscar"
|
||||||
|
"aim-oscar/util"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
|
type routineFn func(db *bun.DB)
|
||||||
|
|
||||||
|
func MessageDelivery() (chan *models.Message, routineFn) {
|
||||||
|
commCh := make(chan *models.Message, 1)
|
||||||
|
|
||||||
|
routine := func(db *bun.DB) {
|
||||||
|
for {
|
||||||
|
message, more := <-commCh
|
||||||
|
if !more {
|
||||||
|
log.Printf("message delivery routine shutting down")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("got a message: %s", message)
|
||||||
|
if s, ok := sessions[message.To]; ok {
|
||||||
|
messageSnac := oscar.NewSNAC(4, 7)
|
||||||
|
messageSnac.Data.WriteUint64(message.MessageID)
|
||||||
|
messageSnac.Data.WriteUint16(1)
|
||||||
|
messageSnac.Data.WriteLPString(message.From)
|
||||||
|
messageSnac.Data.WriteUint16(0) // TODO: sender's warning level
|
||||||
|
|
||||||
|
tlvs := []*oscar.TLV{
|
||||||
|
oscar.NewTLV(1, util.Word(0x80)), // TODO: user class
|
||||||
|
oscar.NewTLV(6, util.Dword(0x0001|0x0100)), // TODO: user status
|
||||||
|
oscar.NewTLV(0xf, util.Dword(0)), // TODO: user idle time
|
||||||
|
oscar.NewTLV(3, util.Dword(0)), // TODO: user creation time
|
||||||
|
// oscar.NewTLV(4, []byte{}), // TODO: this TLV appears in automated responses like away messages
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length of TLVs in fixed part
|
||||||
|
messageSnac.Data.WriteUint16(uint16(len(tlvs)))
|
||||||
|
|
||||||
|
// Write all of the TLVs to the SNAC
|
||||||
|
for _, tlv := range tlvs {
|
||||||
|
messageSnac.Data.WriteBinary(tlv)
|
||||||
|
}
|
||||||
|
|
||||||
|
frag := oscar.Buffer{}
|
||||||
|
frag.Write([]byte{5, 1, 0, 4, 1, 1, 1, 1}) // TODO: first fragment [id, version, len, len, (cap * len)... ]
|
||||||
|
frag.Write([]byte{1, 1}) // message text fragment start (this is a busted "TLV")
|
||||||
|
frag.Write(util.Word(uint16(len(message.Contents) + 4))) // length of TLV
|
||||||
|
frag.Write([]byte{0, 0, 0, 0}) // TODO: message charset number, message charset subset
|
||||||
|
frag.WriteString(message.Contents)
|
||||||
|
|
||||||
|
// Append the fragments
|
||||||
|
messageSnac.Data.Write(frag.Bytes())
|
||||||
|
|
||||||
|
messageFlap := oscar.NewFLAP(2)
|
||||||
|
messageFlap.Data.WriteBinary(messageSnac)
|
||||||
|
if err := s.Send(messageFlap); err != nil {
|
||||||
|
log.Panicf("could not deliver message %d: %s", message.MessageID, err.Error())
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
log.Printf("sent message %d to user %s at %s", message.MessageID, message.To, s.RemoteAddr())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := message.MarkDelivered(context.Background(), db); err != nil {
|
||||||
|
log.Panicf("could not mark message %d as delivered: %s", message.MessageID, err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("could not find session for user %s", message.To)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return commCh, routine
|
||||||
|
}
|
Loading…
Reference in a new issue