Skip to content

Commit

Permalink
set status bitmask on session from SetUserInfoFields
Browse files Browse the repository at this point in the history
  • Loading branch information
mk6i committed Aug 3, 2024
1 parent 71984cf commit f77e293
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 59 deletions.
2 changes: 1 addition & 1 deletion foodgroup/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ func TestAuthService_RegisterBOSSession(t *testing.T) {
},
wantSess: func(sess *state.Session) bool {
uinMatches := fmt.Sprintf("%d", sess.UIN()) == uin.String()
flagsMatch := sess.UserInfoFlags()&wire.OServiceUserFlagICQ == wire.OServiceUserFlagICQ
flagsMatch := sess.UserInfoBitmask()&wire.OServiceUserFlagICQ == wire.OServiceUserFlagICQ
return uinMatches && flagsMatch
},
},
Expand Down
19 changes: 6 additions & 13 deletions foodgroup/oservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,23 +419,16 @@ func (s OServiceService) UserInfoQuery(_ context.Context, sess *state.Session, i
// It returns SNAC wire.OServiceUserInfoUpdate containing the user's info.
func (s OServiceService) SetUserInfoFields(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x01_0x1E_OServiceSetUserInfoFields) (wire.SNACMessage, error) {
if status, hasStatus := inBody.Uint32(wire.OServiceUserInfoStatus); hasStatus {
if status == wire.OServiceUserStatusAvailable {
sess.SetInvisible(false)
if err := s.buddyUpdateBroadcaster.BroadcastBuddyArrived(ctx, sess); err != nil {
sess.SetUserStatusBitmask(status)
if sess.Invisible() {
if err := s.buddyUpdateBroadcaster.BroadcastBuddyDeparted(ctx, sess); err != nil {
return wire.SNACMessage{}, err
}
}
if status&wire.OServiceUserStatusInvisible == wire.OServiceUserStatusInvisible {
sess.SetInvisible(true)
if err := s.buddyUpdateBroadcaster.BroadcastBuddyDeparted(ctx, sess); err != nil {
} else {
if err := s.buddyUpdateBroadcaster.BroadcastBuddyArrived(ctx, sess); err != nil {
return wire.SNACMessage{}, err
}
}
if status&wire.OServiceUserStatusDirectRequireAuth == wire.OServiceUserStatusDirectRequireAuth {
s.logger.DebugContext(ctx, "got unsupported status", "status", status)
}
if status&wire.OServiceUserStatusHideIP == wire.OServiceUserStatusHideIP {
s.logger.DebugContext(ctx, "got unsupported status", "status", status)

}
}
return wire.SNACMessage{
Expand Down
2 changes: 1 addition & 1 deletion foodgroup/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ func sessOptChatRoomCookie(cookie string) func(session *state.Session) {
// sessOptInvisible sets the invisible flag to true on the session
// object
func sessOptInvisible(session *state.Session) {
session.SetInvisible(true)
session.SetUserStatusBitmask(wire.OServiceUserStatusInvisible)
}

// sessOptIdle sets the idle flag to dur on the session object
Expand Down
75 changes: 35 additions & 40 deletions state/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,65 +40,67 @@ type Session struct {
stopCh chan struct{}
uin uint32
warning uint16
userInfoFlags uint16
userInfoBitmask uint16
userStatusBitmask uint32
}

// NewSession returns a new instance of Session. By default, the user may have
// up to 1000 pending messages before blocking.
func NewSession() *Session {
return &Session{
msgCh: make(chan wire.SNACMessage, 1000),
nowFn: time.Now,
stopCh: make(chan struct{}),
signonTime: time.Now(),
caps: make([][16]byte, 0),
userInfoFlags: wire.OServiceUserFlagOSCARFree,
msgCh: make(chan wire.SNACMessage, 1000),
nowFn: time.Now,
stopCh: make(chan struct{}),
signonTime: time.Now(),
caps: make([][16]byte, 0),
userInfoBitmask: wire.OServiceUserFlagOSCARFree,
userStatusBitmask: wire.OServiceUserStatusAvailable,
}
}

// SetUserInfoFlag sets a flag to and returns UserInfoFlags
// SetUserInfoFlag sets a flag to and returns UserInfoBitmask
func (s *Session) SetUserInfoFlag(flag uint16) (flags uint16) {
s.mutex.Lock()
defer s.mutex.Unlock()
s.userInfoFlags |= flag
return s.userInfoFlags
s.userInfoBitmask |= flag
return s.userInfoBitmask
}

// ClearUserInfoFlag clear a flag from and returns UserInfoFlags
// ClearUserInfoFlag clear a flag from and returns UserInfoBitmask
func (s *Session) ClearUserInfoFlag(flag uint16) (flags uint16) {
s.mutex.Lock()
defer s.mutex.Unlock()
s.userInfoFlags &^= flag
return s.userInfoFlags
s.userInfoBitmask &^= flag
return s.userInfoBitmask
}

// UserInfoFlags returns UserInfoFlags
func (s *Session) UserInfoFlags() (flags uint16) {
// UserInfoBitmask returns UserInfoBitmask
func (s *Session) UserInfoBitmask() (flags uint16) {
s.mutex.RLock()
defer s.mutex.RUnlock()
return s.userInfoFlags
return s.userInfoBitmask
}

// IncrementWarning increments the user's warning level. To decrease, pass a
// negative increment value.
func (s *Session) IncrementWarning(incr uint16) {
// SetUserStatusBitmask sets the user status bitmask from the client.
func (s *Session) SetUserStatusBitmask(bitmask uint32) {
s.mutex.Lock()
defer s.mutex.Unlock()
s.warning += incr
s.userStatusBitmask = bitmask
}

// SetInvisible toggles the user's invisibility status.
func (s *Session) SetInvisible(invisible bool) {
// IncrementWarning increments the user's warning level. To decrease, pass a
// negative increment value.
func (s *Session) IncrementWarning(incr uint16) {
s.mutex.Lock()
defer s.mutex.Unlock()
s.invisible = invisible
s.warning += incr
}

// Invisible returns true if the user is idle.
func (s *Session) Invisible() bool {
s.mutex.RLock()
defer s.mutex.RUnlock()
return s.invisible
return s.userStatusBitmask&wire.OServiceUserStatusInvisible == wire.OServiceUserStatusInvisible
}

// SetIdentScreenName sets the user's screen name.
Expand Down Expand Up @@ -152,17 +154,10 @@ func (s *Session) UnsetIdle() {
s.idle = false
}

// SetAwayMessage sets the user's away message, and
// sets or clears the OServiceUserFlagUnavailable flag
// SetAwayMessage sets the user's away message.
func (s *Session) SetAwayMessage(awayMessage string) {
s.mutex.Lock()
defer s.mutex.Unlock()
if awayMessage != "" {
s.userInfoFlags |= wire.OServiceUserFlagUnavailable
} else {
s.userInfoFlags &^= wire.OServiceUserFlagUnavailable
}

s.awayMessage = awayMessage
}

Expand Down Expand Up @@ -236,14 +231,14 @@ func (s *Session) userInfo() wire.TLVList {
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoSignonTOD, uint32(s.signonTime.Unix())))

// user info flags
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoUserFlags, s.UserInfoFlags()))

// reflects invisibility toggle status back to toggling client
if s.invisible {
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoStatus, wire.OServiceUserStatusInvisible))
} else {
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoStatus, uint32(0)))
uFlags := s.userInfoBitmask
if s.awayMessage != "" {
uFlags |= wire.OServiceUserFlagUnavailable
}
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoUserFlags, uFlags))

// user status flags
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoStatus, s.userStatusBitmask))

// idle status
if s.idle {
Expand All @@ -252,7 +247,7 @@ func (s *Session) userInfo() wire.TLVList {

// ICQ direct-connect info. The TLV is required for buddy arrival events to
// work in ICQ, even if the values are set to default.
if s.userInfoFlags&wire.OServiceUserFlagICQ == wire.OServiceUserFlagICQ {
if s.userInfoBitmask&wire.OServiceUserFlagICQ == wire.OServiceUserFlagICQ {
tlvs.Append(wire.NewTLV(wire.OServiceUserInfoICQDC, wire.ICQDCInfo{}))
}

Expand Down
6 changes: 2 additions & 4 deletions state/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ func TestSession_IncrementAndGetWarning(t *testing.T) {
func TestSession_SetAndGetInvisible(t *testing.T) {
s := NewSession()
assert.False(t, s.Invisible())
s.SetInvisible(true)
s.SetUserStatusBitmask(wire.OServiceUserStatusInvisible)
assert.True(t, s.Invisible())
s.SetInvisible(false)
assert.False(t, s.Invisible())
}

func TestSession_SetAndGetScreenName(t *testing.T) {
Expand Down Expand Up @@ -135,7 +133,7 @@ func TestSession_TLVUserInfo(t *testing.T) {
givenSessionFn: func() *Session {
s := NewSession()
s.SetSignonTime(time.Unix(1, 0))
s.SetInvisible(true)
s.SetUserStatusBitmask(wire.OServiceUserStatusInvisible)
return s
},
want: wire.TLVUserInfo{
Expand Down

0 comments on commit f77e293

Please sign in to comment.