mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-11-21 12:09:48 -05:00
track user active state
This commit is contained in:
parent
06d3b84017
commit
ed375e315c
4 changed files with 52 additions and 19 deletions
|
@ -78,14 +78,19 @@ func (g *GenericServiceControls) HandleSNAC(ctx context.Context, db *bun.DB, sna
|
|||
onlineSnac.Data.WriteString(uin)
|
||||
onlineSnac.Data.WriteUint16(0) // warning level
|
||||
|
||||
user.Status = "active"
|
||||
if err := user.Update(ctx, db); err != nil {
|
||||
return ctx, errors.Wrap(err, "could not set user as active")
|
||||
}
|
||||
|
||||
tlvs := []*oscar.TLV{
|
||||
oscar.NewTLV(0x01, util.Dword(0x80)), // User Class
|
||||
oscar.NewTLV(0x06, util.Dword(0x0001|0x0100)), // User Status (TODO: update status in DB)
|
||||
oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(SRV_HOST)))), // External IP
|
||||
oscar.NewTLV(0x0f, util.Dword(0x0)), // Idle Time (TODO: track idle time)
|
||||
oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // Client Signon Time
|
||||
oscar.NewTLV(0x01e, util.Dword(0x0)), // Unknown value
|
||||
oscar.NewTLV(0x05, util.Dword(uint32(time.Now().Unix()))), // Member since
|
||||
oscar.NewTLV(0x01, util.Dword(0x80)), // User Class
|
||||
oscar.NewTLV(0x06, util.Dword(0x0001|0x0100)), // User Status
|
||||
oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(SRV_HOST)))), // External IP
|
||||
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(0x01e, util.Dword(0x0)), // Unknown value
|
||||
oscar.NewTLV(0x05, util.Dword(uint32(user.CreatedAt.Unix()))), // Member since
|
||||
}
|
||||
|
||||
onlineSnac.Data.WriteUint16(uint16(len(tlvs)))
|
||||
|
|
22
main.go
22
main.go
|
@ -15,6 +15,7 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
"github.com/uptrace/bun/dbfixture"
|
||||
"github.com/uptrace/bun/dialect/sqlitedialect"
|
||||
|
@ -68,7 +69,19 @@ func main() {
|
|||
}
|
||||
defer listener.Close()
|
||||
|
||||
handler := oscar.NewHandler(func(ctx context.Context, flap *oscar.FLAP) context.Context {
|
||||
handleCloseFn := func(ctx context.Context, session *oscar.Session) {
|
||||
log.Printf("%v disconnected", session.RemoteAddr())
|
||||
|
||||
user := models.UserFromContext(ctx)
|
||||
if user != nil {
|
||||
user.Status = "offline"
|
||||
if err := user.Update(ctx, db); err != nil {
|
||||
log.Print(errors.Wrap(err, "could not set user as active"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleFn := func(ctx context.Context, flap *oscar.FLAP) context.Context {
|
||||
session, err := oscar.SessionFromContext(ctx)
|
||||
if err != nil {
|
||||
util.PanicIfError(err)
|
||||
|
@ -76,6 +89,8 @@ func main() {
|
|||
|
||||
if user := models.UserFromContext(ctx); user != nil {
|
||||
fmt.Printf("%s (%v) ->\n%+v\n", user.Username, session.RemoteAddr(), flap)
|
||||
user.LastActivityAt = time.Now()
|
||||
ctx = models.NewContextWithUser(ctx, user)
|
||||
} else {
|
||||
fmt.Printf("%v ->\n%+v\n", session.RemoteAddr(), flap)
|
||||
}
|
||||
|
@ -123,10 +138,13 @@ func main() {
|
|||
}
|
||||
} else if flap.Header.Channel == 4 {
|
||||
session.Disconnect()
|
||||
handleCloseFn(ctx, session)
|
||||
}
|
||||
|
||||
return ctx
|
||||
})
|
||||
}
|
||||
|
||||
handler := oscar.NewHandler(handleFn, handleCloseFn)
|
||||
|
||||
RegisterService(0x17, &AuthorizationRegistrationService{})
|
||||
RegisterService(0x01, &GenericServiceControls{})
|
||||
|
|
|
@ -3,18 +3,23 @@ package models
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
UIN int `bun:",pk,autoincrement"`
|
||||
Email string `bun:",unique"`
|
||||
Username string `bun:",unique"`
|
||||
Password string
|
||||
Cipher string
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
UIN int `bun:",pk,autoincrement"`
|
||||
Email string `bun:",unique"`
|
||||
Username string `bun:",unique"`
|
||||
Password string
|
||||
Cipher string
|
||||
CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"`
|
||||
UpdatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"`
|
||||
Status string
|
||||
LastActivityAt time.Time `bin:"-"`
|
||||
}
|
||||
|
||||
type userKey string
|
||||
|
|
|
@ -13,12 +13,17 @@ import (
|
|||
)
|
||||
|
||||
type HandlerFunc func(context.Context, *FLAP) context.Context
|
||||
type HandleCloseFn func(context.Context, *Session)
|
||||
|
||||
type Handler struct{ handle HandlerFunc }
|
||||
type Handler struct {
|
||||
handle HandlerFunc
|
||||
handleClose HandleCloseFn
|
||||
}
|
||||
|
||||
func NewHandler(fn HandlerFunc) *Handler {
|
||||
func NewHandler(fn HandlerFunc, handleClose HandleCloseFn) *Handler {
|
||||
return &Handler{
|
||||
handle: fn,
|
||||
handle: fn,
|
||||
handleClose: handleClose,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,8 +45,8 @@ func (h *Handler) Handle(conn net.Conn) {
|
|||
n, err := conn.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
if strings.Contains(err.Error(), "use of closed network connection") {
|
||||
log.Printf("%v disconnected", conn.RemoteAddr())
|
||||
session.Disconnect()
|
||||
h.handleClose(ctx, session)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue