mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-11-21 12:09:48 -05:00
fix offline status and adding buddies
This commit is contained in:
parent
0f8e600469
commit
060650a7aa
4 changed files with 60 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@ aim-oscar
|
||||||
aim.db
|
aim.db
|
||||||
vendor
|
vendor
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
env/dev.env
|
||||||
|
|
|
@ -44,31 +44,50 @@ func OnlineNotification(sm *SessionManager) (chan *models.User, routineFn) {
|
||||||
if buddy.Source.Status == models.UserStatusAway || buddy.Source.Status == models.UserStatusDnd {
|
if buddy.Source.Status == models.UserStatusAway || buddy.Source.Status == models.UserStatusDnd {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Printf("telling %s that %s has a new status: %d!", buddy.Source.ScreenName, user.ScreenName, user.Status)
|
log.Printf("telling %s that %s has a new status: %d", buddy.Source.ScreenName, user.ScreenName, user.Status)
|
||||||
|
|
||||||
if s := sm.GetSession(buddy.Source.ScreenName); s != nil {
|
if s := sm.GetSession(buddy.Source.ScreenName); s != nil {
|
||||||
onlineSnac := oscar.NewSNAC(3, 0xb)
|
if user.Status == models.UserStatusOnline {
|
||||||
onlineSnac.Data.WriteLPString(user.ScreenName)
|
onlineSnac := oscar.NewSNAC(3, 0xb)
|
||||||
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
onlineSnac.Data.WriteLPString(user.ScreenName)
|
||||||
|
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
||||||
|
|
||||||
tlvs := []*oscar.TLV{
|
tlvs := []*oscar.TLV{
|
||||||
oscar.NewTLV(1, util.Word(0)), // TODO: user class
|
oscar.NewTLV(1, util.Word(0)), // TODO: user class
|
||||||
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))), // TODO: User Status
|
oscar.NewTLV(0x06, util.Dword(uint32(user.Status))),
|
||||||
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(OSCAR_HOST)))), // TODO: External IP of the client?
|
// oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(OSCAR_HOST)))), // TODO: External IP of the client?
|
||||||
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
|
||||||
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
||||||
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
||||||
}
|
}
|
||||||
|
|
||||||
onlineSnac.Data.WriteUint16(uint16(len(tlvs)))
|
onlineSnac.Data.WriteUint16(uint16(len(tlvs)))
|
||||||
for _, tlv := range tlvs {
|
for _, tlv := range tlvs {
|
||||||
onlineSnac.Data.WriteBinary(tlv)
|
onlineSnac.Data.WriteBinary(tlv)
|
||||||
}
|
}
|
||||||
|
|
||||||
onlineFlap := oscar.NewFLAP(2)
|
onlineFlap := oscar.NewFLAP(2)
|
||||||
onlineFlap.Data.WriteBinary(onlineSnac)
|
onlineFlap.Data.WriteBinary(onlineSnac)
|
||||||
if err := s.Send(onlineFlap); err != nil {
|
if err := s.Send(onlineFlap); err != nil {
|
||||||
log.Printf("could not tell %s that %s is online", buddy.Source.ScreenName, user.ScreenName)
|
log.Printf("could not tell %s that %s is online", buddy.Source.ScreenName, user.ScreenName)
|
||||||
|
}
|
||||||
|
} else if user.Status == models.UserStatusAway {
|
||||||
|
offlineSnac := oscar.NewSNAC(3, 0xc)
|
||||||
|
offlineSnac.Data.WriteLPString(user.ScreenName)
|
||||||
|
offlineSnac.Data.WriteUint16(0) // TODO: user warning level
|
||||||
|
tlvs := []*oscar.TLV{
|
||||||
|
oscar.NewTLV(1, util.Word(0)),
|
||||||
|
}
|
||||||
|
offlineSnac.Data.WriteUint16(uint16(len(tlvs)))
|
||||||
|
for _, tlv := range tlvs {
|
||||||
|
offlineSnac.Data.WriteBinary(tlv)
|
||||||
|
}
|
||||||
|
|
||||||
|
offlineFlap := oscar.NewFLAP(2)
|
||||||
|
offlineFlap.Data.WriteBinary(offlineSnac)
|
||||||
|
if err := s.Send(offlineFlap); err != nil {
|
||||||
|
log.Printf("could not tell %s that %s is offline", buddy.Source.ScreenName, user.ScreenName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HandlerFunc func(context.Context, *FLAP) context.Context
|
type HandlerFunc func(context.Context, *FLAP) context.Context
|
||||||
|
@ -41,6 +42,9 @@ func (h *Handler) Handle(conn net.Conn) {
|
||||||
session.GreetedClient = true
|
session.GreetedClient = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Never timeout
|
||||||
|
conn.SetReadDeadline(time.Time{})
|
||||||
|
|
||||||
incoming := make([]byte, 512)
|
incoming := make([]byte, 512)
|
||||||
n, err := conn.Read(incoming)
|
n, err := conn.Read(incoming)
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
|
|
|
@ -6,13 +6,16 @@ import (
|
||||||
"aim-oscar/oscar"
|
"aim-oscar/oscar"
|
||||||
"aim-oscar/util"
|
"aim-oscar/util"
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/uptrace/bun"
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BuddyListManagement struct{}
|
type BuddyListManagement struct {
|
||||||
|
OnlineCh chan *models.User
|
||||||
|
}
|
||||||
|
|
||||||
func (b *BuddyListManagement) HandleSNAC(ctx context.Context, db *bun.DB, snac *oscar.SNAC) (context.Context, error) {
|
func (b *BuddyListManagement) HandleSNAC(ctx context.Context, db *bun.DB, snac *oscar.SNAC) (context.Context, error) {
|
||||||
session, _ := oscar.SessionFromContext(ctx)
|
session, _ := oscar.SessionFromContext(ctx)
|
||||||
|
@ -61,11 +64,23 @@ func (b *BuddyListManagement) HandleSNAC(ctx context.Context, db *bun.DB, snac *
|
||||||
WithUIN: buddy.UIN,
|
WithUIN: buddy.UIN,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count, err := db.NewSelect().Model((*models.Buddy)(nil)).Where("source_uin = ?", user.UIN).Where("with_uin = ?", buddy.UIN).Count(ctx)
|
||||||
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||||
|
return ctx, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already buddies
|
||||||
|
if count > 0 {
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
_, err = db.NewInsert().Model(rel).Exec(ctx)
|
_, err = db.NewInsert().Model(rel).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, err
|
return ctx, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.OnlineCh <- buddy
|
||||||
|
|
||||||
log.Printf("%s added buddy %s to buddy list", user.ScreenName, buddyScreename)
|
log.Printf("%s added buddy %s to buddy list", user.ScreenName, buddyScreename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue