mirror of
https://github.com/amigan/aim-oscar-server.git
synced 2024-11-21 20:19:47 -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.WriteString(uin)
|
||||||
onlineSnac.Data.WriteUint16(0) // warning level
|
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{
|
tlvs := []*oscar.TLV{
|
||||||
oscar.NewTLV(0x01, util.Dword(0x80)), // User Class
|
oscar.NewTLV(0x01, util.Dword(0x80)), // User Class
|
||||||
oscar.NewTLV(0x06, util.Dword(0x0001|0x0100)), // User Status (TODO: update status in DB)
|
oscar.NewTLV(0x06, util.Dword(0x0001|0x0100)), // User Status
|
||||||
oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(SRV_HOST)))), // External IP
|
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(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(0x01e, util.Dword(0x0)), // Unknown value
|
oscar.NewTLV(0x01e, util.Dword(0x0)), // Unknown value
|
||||||
oscar.NewTLV(0x05, util.Dword(uint32(time.Now().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)))
|
||||||
|
|
22
main.go
22
main.go
|
@ -15,6 +15,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/uptrace/bun"
|
"github.com/uptrace/bun"
|
||||||
"github.com/uptrace/bun/dbfixture"
|
"github.com/uptrace/bun/dbfixture"
|
||||||
"github.com/uptrace/bun/dialect/sqlitedialect"
|
"github.com/uptrace/bun/dialect/sqlitedialect"
|
||||||
|
@ -68,7 +69,19 @@ func main() {
|
||||||
}
|
}
|
||||||
defer listener.Close()
|
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)
|
session, err := oscar.SessionFromContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.PanicIfError(err)
|
util.PanicIfError(err)
|
||||||
|
@ -76,6 +89,8 @@ func main() {
|
||||||
|
|
||||||
if user := models.UserFromContext(ctx); user != nil {
|
if user := models.UserFromContext(ctx); user != nil {
|
||||||
fmt.Printf("%s (%v) ->\n%+v\n", user.Username, session.RemoteAddr(), flap)
|
fmt.Printf("%s (%v) ->\n%+v\n", user.Username, session.RemoteAddr(), flap)
|
||||||
|
user.LastActivityAt = time.Now()
|
||||||
|
ctx = models.NewContextWithUser(ctx, user)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%v ->\n%+v\n", session.RemoteAddr(), flap)
|
fmt.Printf("%v ->\n%+v\n", session.RemoteAddr(), flap)
|
||||||
}
|
}
|
||||||
|
@ -123,10 +138,13 @@ func main() {
|
||||||
}
|
}
|
||||||
} else if flap.Header.Channel == 4 {
|
} else if flap.Header.Channel == 4 {
|
||||||
session.Disconnect()
|
session.Disconnect()
|
||||||
|
handleCloseFn(ctx, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
})
|
}
|
||||||
|
|
||||||
|
handler := oscar.NewHandler(handleFn, handleCloseFn)
|
||||||
|
|
||||||
RegisterService(0x17, &AuthorizationRegistrationService{})
|
RegisterService(0x17, &AuthorizationRegistrationService{})
|
||||||
RegisterService(0x01, &GenericServiceControls{})
|
RegisterService(0x01, &GenericServiceControls{})
|
||||||
|
|
|
@ -3,18 +3,23 @@ package models
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/uptrace/bun"
|
"github.com/uptrace/bun"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
bun.BaseModel `bun:"table:users"`
|
bun.BaseModel `bun:"table:users"`
|
||||||
UIN int `bun:",pk,autoincrement"`
|
UIN int `bun:",pk,autoincrement"`
|
||||||
Email string `bun:",unique"`
|
Email string `bun:",unique"`
|
||||||
Username string `bun:",unique"`
|
Username string `bun:",unique"`
|
||||||
Password string
|
Password string
|
||||||
Cipher 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
|
type userKey string
|
||||||
|
|
|
@ -13,12 +13,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type HandlerFunc func(context.Context, *FLAP) context.Context
|
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{
|
return &Handler{
|
||||||
handle: fn,
|
handle: fn,
|
||||||
|
handleClose: handleClose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +45,8 @@ func (h *Handler) Handle(conn net.Conn) {
|
||||||
n, err := conn.Read(buf)
|
n, err := conn.Read(buf)
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
if strings.Contains(err.Error(), "use of closed network connection") {
|
if strings.Contains(err.Error(), "use of closed network connection") {
|
||||||
log.Printf("%v disconnected", conn.RemoteAddr())
|
|
||||||
session.Disconnect()
|
session.Disconnect()
|
||||||
|
h.handleClose(ctx, session)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue