fix offline status and adding buddies

This commit is contained in:
Artem Titoulenko 2022-02-11 13:28:20 -05:00
parent 0f8e600469
commit 060650a7aa
4 changed files with 60 additions and 21 deletions

1
.gitignore vendored
View file

@ -5,3 +5,4 @@ aim-oscar
aim.db
vendor
.DS_Store
env/dev.env

View file

@ -44,16 +44,17 @@ func OnlineNotification(sm *SessionManager) (chan *models.User, routineFn) {
if buddy.Source.Status == models.UserStatusAway || buddy.Source.Status == models.UserStatusDnd {
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 user.Status == models.UserStatusOnline {
onlineSnac := oscar.NewSNAC(3, 0xb)
onlineSnac.Data.WriteLPString(user.ScreenName)
onlineSnac.Data.WriteUint16(0) // TODO: user warning level
tlvs := []*oscar.TLV{
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(0x0f, util.Dword(uint32(time.Since(user.LastActivityAt).Seconds()))), // Idle Time
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
@ -70,6 +71,24 @@ func OnlineNotification(sm *SessionManager) (chan *models.User, routineFn) {
if err := s.Send(onlineFlap); err != nil {
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)
}
}
}
}
}

View file

@ -10,6 +10,7 @@ import (
"log"
"net"
"strings"
"time"
)
type HandlerFunc func(context.Context, *FLAP) context.Context
@ -41,6 +42,9 @@ func (h *Handler) Handle(conn net.Conn) {
session.GreetedClient = true
}
// Never timeout
conn.SetReadDeadline(time.Time{})
incoming := make([]byte, 512)
n, err := conn.Read(incoming)
if err != nil && err != io.EOF {

View file

@ -6,13 +6,16 @@ import (
"aim-oscar/oscar"
"aim-oscar/util"
"context"
"database/sql"
"log"
"github.com/pkg/errors"
"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) {
session, _ := oscar.SessionFromContext(ctx)
@ -61,11 +64,23 @@ func (b *BuddyListManagement) HandleSNAC(ctx context.Context, db *bun.DB, snac *
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)
if err != nil {
return ctx, err
}
b.OnlineCh <- buddy
log.Printf("%s added buddy %s to buddy list", user.ScreenName, buddyScreename)
}