|
@@ -92,7 +92,7 @@ func (client *Client) AllSessionData(currentSession *Session, hasPrivs bool) (da
|
92
|
92
|
return
|
93
|
93
|
}
|
94
|
94
|
|
95
|
|
-func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, back bool) {
|
|
95
|
+func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, wasAway, nowAway string) {
|
96
|
96
|
config := client.server.Config()
|
97
|
97
|
client.stateMutex.Lock()
|
98
|
98
|
defer client.stateMutex.Unlock()
|
|
@@ -113,14 +113,22 @@ func (client *Client) AddSession(session *Session) (success bool, numSessions in
|
113
|
113
|
client.setLastSeen(time.Now().UTC(), session.deviceID)
|
114
|
114
|
}
|
115
|
115
|
client.sessions = newSessions
|
116
|
|
- // TODO(#1551) there should be a cap to opt out of this behavior on a session
|
117
|
|
- if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
|
118
|
|
- client.awayMessage = ""
|
119
|
|
- if len(client.sessions) == 1 {
|
120
|
|
- back = true
|
|
116
|
+ wasAway = client.awayMessage
|
|
117
|
+ if client.autoAwayEnabledNoMutex(config) {
|
|
118
|
+ client.setAutoAwayNoMutex(config)
|
|
119
|
+ } else {
|
|
120
|
+ if session.awayMessage != "" && session.awayMessage != "*" {
|
|
121
|
+ // set the away message
|
|
122
|
+ client.awayMessage = session.awayMessage
|
|
123
|
+ } else if session.awayMessage == "" && !session.awayAt.IsZero() {
|
|
124
|
+ // weird edge case: explicit `AWAY` or `AWAY :` during pre-registration makes the client back
|
|
125
|
+ client.awayMessage = ""
|
121
|
126
|
}
|
|
127
|
+ // else: the client sent no AWAY command at all, no-op
|
|
128
|
+ // or: the client sent `AWAY *`, which should not modify the publicly visible away state
|
122
|
129
|
}
|
123
|
|
- return true, len(client.sessions), lastSeen, back
|
|
130
|
+ nowAway = client.awayMessage
|
|
131
|
+ return true, len(client.sessions), lastSeen, wasAway, nowAway
|
124
|
132
|
}
|
125
|
133
|
|
126
|
134
|
func (client *Client) removeSession(session *Session) (success bool, length int) {
|
|
@@ -195,7 +203,7 @@ func (client *Client) Away() (result bool, message string) {
|
195
|
203
|
return
|
196
|
204
|
}
|
197
|
205
|
|
198
|
|
-func (session *Session) SetAway(awayMessage string) {
|
|
206
|
+func (session *Session) SetAway(awayMessage string) (wasAway, nowAway string) {
|
199
|
207
|
client := session.client
|
200
|
208
|
config := client.server.Config()
|
201
|
209
|
|
|
@@ -205,15 +213,21 @@ func (session *Session) SetAway(awayMessage string) {
|
205
|
213
|
session.awayMessage = awayMessage
|
206
|
214
|
session.awayAt = time.Now().UTC()
|
207
|
215
|
|
208
|
|
- autoAway := client.registered && client.alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
|
209
|
|
- if autoAway {
|
|
216
|
+ wasAway = client.awayMessage
|
|
217
|
+ if client.autoAwayEnabledNoMutex(config) {
|
210
|
218
|
client.setAutoAwayNoMutex(config)
|
211
|
|
- } else {
|
|
219
|
+ } else if awayMessage != "*" {
|
212
|
220
|
client.awayMessage = awayMessage
|
213
|
|
- }
|
|
221
|
+ } // else: `AWAY *`, should not modify publicly visible away state
|
|
222
|
+ nowAway = client.awayMessage
|
214
|
223
|
return
|
215
|
224
|
}
|
216
|
225
|
|
|
226
|
+func (client *Client) autoAwayEnabledNoMutex(config *Config) bool {
|
|
227
|
+ return client.registered && client.alwaysOn &&
|
|
228
|
+ persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
|
|
229
|
+}
|
|
230
|
+
|
217
|
231
|
func (client *Client) setAutoAwayNoMutex(config *Config) {
|
218
|
232
|
// aggregate the away statuses of the individual sessions:
|
219
|
233
|
var globalAwayState string
|
|
@@ -223,8 +237,8 @@ func (client *Client) setAutoAwayNoMutex(config *Config) {
|
223
|
237
|
// a session is active, we are not auto-away
|
224
|
238
|
client.awayMessage = ""
|
225
|
239
|
return
|
226
|
|
- } else if cSession.awayAt.After(awaySetAt) {
|
227
|
|
- // choose the latest available away message from any session
|
|
240
|
+ } else if cSession.awayAt.After(awaySetAt) && cSession.awayMessage != "*" {
|
|
241
|
+ // choose the latest valid away message from any session
|
228
|
242
|
globalAwayState = cSession.awayMessage
|
229
|
243
|
awaySetAt = cSession.awayAt
|
230
|
244
|
}
|