Просмотр исходного кода

set status bitmask on session from SetUserInfoFields

Mike 1 год назад
Родитель
Сommit
f77e29392f
5 измененных файлов с 45 добавлено и 59 удалено
  1. 1 1
      foodgroup/auth_test.go
  2. 6 13
      foodgroup/oservice.go
  3. 1 1
      foodgroup/test_helpers.go
  4. 35 40
      state/session.go
  5. 2 4
      state/session_test.go

+ 1 - 1
foodgroup/auth_test.go

@@ -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
 			},
 		},

+ 6 - 13
foodgroup/oservice.go

@@ -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{

+ 1 - 1
foodgroup/test_helpers.go

@@ -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

+ 35 - 40
state/session.go

@@ -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.
@@ -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
 }
 
@@ -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 {
@@ -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{}))
 	}
 

+ 2 - 4
state/session_test.go

@@ -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) {
@@ -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{