Pārlūkot izejas kodu

fix #1531

AWAY status should be tracked per-session:

1. With auto-away enabled, away status is aggregated across sessions
   (if any session is not away, the client is not away, else use
   the away status that was set most recently)
2. With auto-away disabled, we get the legacy behavior where AWAY
   applies directly to the client
tags/v2.6.0-rc1
Shivaram Lingamneni 3 gadus atpakaļ
vecāks
revīzija
70b20750aa
4 mainītis faili ar 59 papildinājumiem un 36 dzēšanām
  1. 0
    4
      docs/MANUAL.md
  2. 11
    14
      irc/client.go
  3. 46
    16
      irc/getters.go
  4. 2
    2
      irc/handlers.go

+ 0
- 4
docs/MANUAL.md Parādīt failu

@@ -621,10 +621,6 @@ In this section, we give an overview of the modes Oragono supports.
621 621
 
622 622
 These are the modes which can be set on you when you're connected.
623 623
 
624
-### +a - Away
625
-
626
-If this mode is set, you're marked as being away. This mode is set with the /AWAY command.
627
-
628 624
 ### +i - Invisible
629 625
 
630 626
 If this mode is set, you're marked as 'invisible'. This means that your channels won't be shown when users `/WHOIS` you (except for IRC operators, they can see all the channels you're in).

+ 11
- 14
irc/client.go Parādīt failu

@@ -78,8 +78,6 @@ type Client struct {
78 78
 	accountName        string // display name of the account: uncasefolded, '*' if not logged in
79 79
 	accountRegDate     time.Time
80 80
 	accountSettings    AccountSettings
81
-	away               bool
82
-	autoAway           bool
83 81
 	awayMessage        string
84 82
 	brbTimer           BrbTimer
85 83
 	channels           ChannelSet
@@ -177,6 +175,9 @@ type Session struct {
177 175
 
178 176
 	quitMessage string
179 177
 
178
+	awayMessage string
179
+	awayAt      time.Time
180
+
180 181
 	capabilities caps.Set
181 182
 	capState     caps.State
182 183
 	capVersion   caps.Version
@@ -486,8 +487,6 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, channelToStatus m
486 487
 	}
487 488
 
488 489
 	if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
489
-		client.autoAway = true
490
-		client.away = true
491 490
 		client.awayMessage = client.t("User is currently disconnected")
492 491
 	}
493 492
 }
@@ -675,7 +674,7 @@ func (client *Client) run(session *Session) {
675 674
 			session.playResume()
676 675
 			session.resumeDetails = nil
677 676
 			client.brbTimer.Disable()
678
-			client.SetAway(false, "") // clear BRB message if any
677
+			session.SetAway("") // clear BRB message if any
679 678
 		} else {
680 679
 			client.playReattachMessages(session)
681 680
 		}
@@ -1458,15 +1457,13 @@ func (client *Client) destroy(session *Session) {
1458 1457
 		client.dirtyBits |= IncludeLastSeen
1459 1458
 	}
1460 1459
 
1461
-	autoAway := false
1460
+	becameAutoAway := false
1462 1461
 	var awayMessage string
1463
-	if alwaysOn && !client.away && remainingSessions == 0 &&
1464
-		persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
1465
-		autoAway = true
1466
-		client.autoAway = true
1467
-		client.away = true
1468
-		awayMessage = config.languageManager.Translate(client.languages, `User is currently disconnected`)
1469
-		client.awayMessage = awayMessage
1462
+	if alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
1463
+		wasAway := client.awayMessage != ""
1464
+		client.setAutoAwayNoMutex(config)
1465
+		awayMessage = client.awayMessage
1466
+		becameAutoAway = !wasAway && awayMessage != ""
1470 1467
 	}
1471 1468
 
1472 1469
 	if client.registrationTimer != nil {
@@ -1523,7 +1520,7 @@ func (client *Client) destroy(session *Session) {
1523 1520
 		client.server.stats.Remove(registered, invisible, operator)
1524 1521
 	}
1525 1522
 
1526
-	if autoAway {
1523
+	if becameAutoAway {
1527 1524
 		dispatchAwayNotify(client, true, awayMessage)
1528 1525
 	}
1529 1526
 

+ 46
- 16
irc/getters.go Parādīt failu

@@ -107,6 +107,7 @@ func (client *Client) AllSessionData(currentSession *Session, hasPrivs bool) (da
107 107
 }
108 108
 
109 109
 func (client *Client) AddSession(session *Session) (success bool, numSessions int, lastSeen time.Time, back bool) {
110
+	config := client.server.Config()
110 111
 	client.stateMutex.Lock()
111 112
 	defer client.stateMutex.Unlock()
112 113
 
@@ -126,11 +127,12 @@ func (client *Client) AddSession(session *Session) (success bool, numSessions in
126 127
 		client.setLastSeen(time.Now().UTC(), session.deviceID)
127 128
 	}
128 129
 	client.sessions = newSessions
129
-	if client.autoAway {
130
-		back = true
131
-		client.autoAway = false
132
-		client.away = false
130
+	// TODO(#1551) there should be a cap to opt out of this behavior on a session
131
+	if persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway) {
133 132
 		client.awayMessage = ""
133
+		if len(client.sessions) == 1 {
134
+			back = true
135
+		}
134 136
 	}
135 137
 	return true, len(client.sessions), lastSeen, back
136 138
 }
@@ -196,20 +198,54 @@ func (client *Client) Hostname() string {
196 198
 
197 199
 func (client *Client) Away() (result bool, message string) {
198 200
 	client.stateMutex.Lock()
199
-	result, message = client.away, client.awayMessage
201
+	message = client.awayMessage
200 202
 	client.stateMutex.Unlock()
203
+	result = client.awayMessage != ""
201 204
 	return
202 205
 }
203 206
 
204
-func (client *Client) SetAway(away bool, awayMessage string) (changed bool) {
207
+func (session *Session) SetAway(awayMessage string) {
208
+	client := session.client
209
+	config := client.server.Config()
210
+
205 211
 	client.stateMutex.Lock()
206
-	changed = away != client.away
207
-	client.away = away
208
-	client.awayMessage = awayMessage
209
-	client.stateMutex.Unlock()
212
+	defer client.stateMutex.Unlock()
213
+
214
+	session.awayMessage = awayMessage
215
+	session.awayAt = time.Now().UTC()
216
+
217
+	autoAway := client.registered && client.alwaysOn && persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
218
+	if autoAway {
219
+		client.setAutoAwayNoMutex(config)
220
+	} else {
221
+		client.awayMessage = awayMessage
222
+	}
210 223
 	return
211 224
 }
212 225
 
226
+func (client *Client) setAutoAwayNoMutex(config *Config) {
227
+	// aggregate the away statuses of the individual sessions:
228
+	var globalAwayState string
229
+	var awaySetAt time.Time
230
+	for _, cSession := range client.sessions {
231
+		if cSession.awayMessage == "" {
232
+			// a session is active, we are not auto-away
233
+			client.awayMessage = ""
234
+			return
235
+		} else if cSession.awayAt.After(awaySetAt) {
236
+			// choose the latest available away message from any session
237
+			globalAwayState = cSession.awayMessage
238
+			awaySetAt = cSession.awayAt
239
+		}
240
+	}
241
+	if awaySetAt.IsZero() {
242
+		// no sessions, enable auto-away
243
+		client.awayMessage = config.languageManager.Translate(client.languages, `User is currently disconnected`)
244
+	} else {
245
+		client.awayMessage = globalAwayState
246
+	}
247
+}
248
+
213 249
 func (client *Client) AlwaysOn() (alwaysOn bool) {
214 250
 	client.stateMutex.RLock()
215 251
 	alwaysOn = client.registered && client.alwaysOn
@@ -269,12 +305,6 @@ func (client *Client) AwayMessage() (result string) {
269 305
 	return
270 306
 }
271 307
 
272
-func (client *Client) SetAwayMessage(message string) {
273
-	client.stateMutex.Lock()
274
-	client.awayMessage = message
275
-	client.stateMutex.Unlock()
276
-}
277
-
278 308
 func (client *Client) Account() string {
279 309
 	client.stateMutex.RLock()
280 310
 	defer client.stateMutex.RUnlock()

+ 2
- 2
irc/handlers.go Parādīt failu

@@ -352,7 +352,7 @@ func awayHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
352 352
 		}
353 353
 	}
354 354
 
355
-	client.SetAway(isAway, awayMessage)
355
+	rb.session.SetAway(awayMessage)
356 356
 
357 357
 	if isAway {
358 358
 		rb.Add(nil, server.name, RPL_NOWAWAY, client.nick, client.t("You have been marked as being away"))
@@ -439,7 +439,7 @@ func brbHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
439 439
 
440 440
 	if len(client.Sessions()) == 1 {
441 441
 		// true BRB
442
-		client.SetAway(true, message)
442
+		rb.session.SetAway(message)
443 443
 	}
444 444
 
445 445
 	return true

Notiek ielāde…
Atcelt
Saglabāt