|
@@ -237,7 +237,7 @@ func (s *Session) EndMultilineBatch(label string) (batch MultilineBatch, err err
|
237
|
237
|
}
|
238
|
238
|
|
239
|
239
|
// sets the session quit message, if there isn't one already
|
240
|
|
-func (sd *Session) SetQuitMessage(message string) (set bool) {
|
|
240
|
+func (sd *Session) setQuitMessage(message string) (set bool) {
|
241
|
241
|
if message == "" {
|
242
|
242
|
message = "Connection closed"
|
243
|
243
|
}
|
|
@@ -443,6 +443,11 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, channelToModes ma
|
443
|
443
|
nextSessionID: 1,
|
444
|
444
|
}
|
445
|
445
|
|
|
446
|
+ if client.checkAlwaysOnExpirationNoMutex(config) {
|
|
447
|
+ server.logger.Debug("accounts", "always-on client not created due to expiration", account.Name)
|
|
448
|
+ return
|
|
449
|
+ }
|
|
450
|
+
|
446
|
451
|
client.SetMode(modes.TLS, true)
|
447
|
452
|
for _, m := range uModes {
|
448
|
453
|
client.SetMode(m, true)
|
|
@@ -789,14 +794,16 @@ func (client *Client) Touch(session *Session) {
|
789
|
794
|
var markDirty bool
|
790
|
795
|
now := time.Now().UTC()
|
791
|
796
|
client.stateMutex.Lock()
|
792
|
|
- if client.accountSettings.AutoreplayMissed || session.deviceID != "" {
|
793
|
|
- client.setLastSeen(now, session.deviceID)
|
794
|
|
- if now.Sub(client.lastSeenLastWrite) > lastSeenWriteInterval {
|
795
|
|
- markDirty = true
|
796
|
|
- client.lastSeenLastWrite = now
|
|
797
|
+ if client.registered {
|
|
798
|
+ client.updateIdleTimer(session, now)
|
|
799
|
+ if client.alwaysOn {
|
|
800
|
+ client.setLastSeen(now, session.deviceID)
|
|
801
|
+ if now.Sub(client.lastSeenLastWrite) > lastSeenWriteInterval {
|
|
802
|
+ markDirty = true
|
|
803
|
+ client.lastSeenLastWrite = now
|
|
804
|
+ }
|
797
|
805
|
}
|
798
|
806
|
}
|
799
|
|
- client.updateIdleTimer(session, now)
|
800
|
807
|
client.stateMutex.Unlock()
|
801
|
808
|
if markDirty {
|
802
|
809
|
client.markDirty(IncludeLastSeen)
|
|
@@ -1364,7 +1371,7 @@ func (client *Client) Quit(message string, session *Session) {
|
1364
|
1371
|
}
|
1365
|
1372
|
|
1366
|
1373
|
for _, session := range sessions {
|
1367
|
|
- if session.SetQuitMessage(message) {
|
|
1374
|
+ if session.setQuitMessage(message) {
|
1368
|
1375
|
setFinalData(session)
|
1369
|
1376
|
}
|
1370
|
1377
|
}
|
|
@@ -1378,6 +1385,7 @@ func (client *Client) destroy(session *Session) {
|
1378
|
1385
|
config := client.server.Config()
|
1379
|
1386
|
var sessionsToDestroy []*Session
|
1380
|
1387
|
var saveLastSeen bool
|
|
1388
|
+ var quitMessage string
|
1381
|
1389
|
|
1382
|
1390
|
client.stateMutex.Lock()
|
1383
|
1391
|
|
|
@@ -1390,6 +1398,13 @@ func (client *Client) destroy(session *Session) {
|
1390
|
1398
|
// XXX a temporary (reattaching) client can be marked alwaysOn when it logs in,
|
1391
|
1399
|
// but then the session attaches to another client and we need to clean it up here
|
1392
|
1400
|
alwaysOn := registered && client.alwaysOn
|
|
1401
|
+ // if we hit always-on-expiration, confirm the expiration and then proceed as though
|
|
1402
|
+ // always-on is disabled:
|
|
1403
|
+ if alwaysOn && session == nil && client.checkAlwaysOnExpirationNoMutex(config) {
|
|
1404
|
+ quitMessage = "Timed out due to inactivity"
|
|
1405
|
+ alwaysOn = false
|
|
1406
|
+ client.alwaysOn = false
|
|
1407
|
+ }
|
1393
|
1408
|
|
1394
|
1409
|
var remainingSessions int
|
1395
|
1410
|
if session == nil {
|
|
@@ -1459,7 +1474,6 @@ func (client *Client) destroy(session *Session) {
|
1459
|
1474
|
}
|
1460
|
1475
|
|
1461
|
1476
|
// destroy all applicable sessions:
|
1462
|
|
- var quitMessage string
|
1463
|
1477
|
for _, session := range sessionsToDestroy {
|
1464
|
1478
|
if session.client != client {
|
1465
|
1479
|
// session has been attached to a new client; do not destroy it
|
|
@@ -1468,7 +1482,7 @@ func (client *Client) destroy(session *Session) {
|
1468
|
1482
|
session.stopIdleTimer()
|
1469
|
1483
|
// send quit/error message to client if they haven't been sent already
|
1470
|
1484
|
client.Quit("", session)
|
1471
|
|
- quitMessage = session.quitMessage
|
|
1485
|
+ quitMessage = session.quitMessage // doesn't need synch, we already detached
|
1472
|
1486
|
session.SetDestroyed()
|
1473
|
1487
|
session.socket.Close()
|
1474
|
1488
|
|
|
@@ -1506,13 +1520,7 @@ func (client *Client) destroy(session *Session) {
|
1506
|
1520
|
return
|
1507
|
1521
|
}
|
1508
|
1522
|
|
1509
|
|
- splitQuitMessage := utils.MakeMessage(quitMessage)
|
1510
|
|
- quitItem := history.Item{
|
1511
|
|
- Type: history.Quit,
|
1512
|
|
- Nick: details.nickMask,
|
1513
|
|
- AccountName: details.accountName,
|
1514
|
|
- Message: splitQuitMessage,
|
1515
|
|
- }
|
|
1523
|
+ var quitItem history.Item
|
1516
|
1524
|
var channels []*Channel
|
1517
|
1525
|
// use a defer here to avoid writing to mysql while holding the destroy semaphore:
|
1518
|
1526
|
defer func() {
|
|
@@ -1574,6 +1582,13 @@ func (client *Client) destroy(session *Session) {
|
1574
|
1582
|
if quitMessage == "" {
|
1575
|
1583
|
quitMessage = "Exited"
|
1576
|
1584
|
}
|
|
1585
|
+ splitQuitMessage := utils.MakeMessage(quitMessage)
|
|
1586
|
+ quitItem = history.Item{
|
|
1587
|
+ Type: history.Quit,
|
|
1588
|
+ Nick: details.nickMask,
|
|
1589
|
+ AccountName: details.accountName,
|
|
1590
|
+ Message: splitQuitMessage,
|
|
1591
|
+ }
|
1577
|
1592
|
var cache MessageCache
|
1578
|
1593
|
cache.Initialize(client.server, splitQuitMessage.Time, splitQuitMessage.Msgid, details.nickMask, details.accountName, nil, "QUIT", quitMessage)
|
1579
|
1594
|
for friend := range friends {
|