浏览代码

Persist realname for always-on clients

tags/v2.2.0-rc1
Conrad Lukawski 3 年前
父节点
当前提交
6f8711da3b
共有 5 个文件被更改,包括 51 次插入10 次删除
  1. 36
    2
      irc/accounts.go
  2. 6
    1
      irc/client.go
  3. 0
    7
      irc/client_lookup_set.go
  4. 4
    0
      irc/getters.go
  5. 5
    0
      irc/handlers.go

+ 36
- 2
irc/accounts.go 查看文件

@@ -39,7 +39,8 @@ const (
39 39
 	keyAccountChannels         = "account.channels %s" // channels registered to the account
40 40
 	keyAccountJoinedChannels   = "account.joinedto %s" // channels a persistent client has joined
41 41
 	keyAccountLastSeen         = "account.lastseen %s"
42
-	keyAccountModes            = "account.modes %s" // user modes for the always-on client as a string
42
+	keyAccountModes            = "account.modes %s"    // user modes for the always-on client as a string
43
+	keyAccountRealname         = "account.realname %s" // client realname stored as string
43 44
 
44 45
 	keyVHostQueueAcctToId = "vhostQueue %s"
45 46
 	vhostRequestIdx       = "vhostQueue"
@@ -127,7 +128,13 @@ func (am *AccountManager) createAlwaysOnClients(config *Config) {
127 128
 		account, err := am.LoadAccount(accountName)
128 129
 		if err == nil && account.Verified &&
129 130
 			persistenceEnabled(config.Accounts.Multiclient.AlwaysOn, account.Settings.AlwaysOn) {
130
-			am.server.AddAlwaysOnClient(account, am.loadChannels(accountName), am.loadLastSeen(accountName), am.loadModes(accountName))
131
+			am.server.AddAlwaysOnClient(
132
+				account,
133
+				am.loadChannels(accountName),
134
+				am.loadLastSeen(accountName),
135
+				am.loadModes(accountName),
136
+				am.loadRealname(accountName),
137
+			)
131 138
 		}
132 139
 	}
133 140
 }
@@ -650,6 +657,30 @@ func (am *AccountManager) loadLastSeen(account string) (lastSeen map[string]time
650 657
 	return
651 658
 }
652 659
 
660
+func (am *AccountManager) saveRealname(account string, realname string) {
661
+	key := fmt.Sprintf(keyAccountRealname, account)
662
+	am.server.store.Update(func(tx *buntdb.Tx) error {
663
+		if realname != "" {
664
+			tx.Set(key, realname, nil)
665
+		} else {
666
+			tx.Delete(key)
667
+		}
668
+		return nil
669
+	})
670
+}
671
+
672
+func (am *AccountManager) loadRealname(account string) (realname string) {
673
+	key := fmt.Sprintf(keyAccountRealname, account)
674
+	am.server.store.Update(func(tx *buntdb.Tx) error {
675
+		realname, _ = tx.Get(key)
676
+		return nil
677
+	})
678
+	if realname == "" {
679
+		return ""
680
+	}
681
+	return
682
+}
683
+
653 684
 func (am *AccountManager) addRemoveCertfp(account, certfp string, add bool, hasPrivs bool) (err error) {
654 685
 	certfp, err = utils.NormalizeCertfp(certfp)
655 686
 	if err != nil {
@@ -874,6 +905,9 @@ func (am *AccountManager) Verify(client *Client, account string, code string) er
874 905
 			am.server.RandomlyRename(currentClient)
875 906
 		}
876 907
 	}
908
+	if client.AlwaysOn() {
909
+		client.markDirty(IncludeRealname)
910
+	}
877 911
 	return nil
878 912
 }
879 913
 

+ 6
- 1
irc/client.go 查看文件

@@ -365,7 +365,7 @@ func (server *Server) RunClient(conn IRCConn) {
365 365
 	client.run(session)
366 366
 }
367 367
 
368
-func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen map[string]time.Time, uModes modes.Modes) {
368
+func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string, lastSeen map[string]time.Time, uModes modes.Modes, realname string) {
369 369
 	now := time.Now().UTC()
370 370
 	config := server.Config()
371 371
 	if lastSeen == nil && account.Settings.AutoreplayMissed {
@@ -386,6 +386,7 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, chnames []string,
386 386
 		realIP:      utils.IPv4LoopbackAddress,
387 387
 
388 388
 		alwaysOn: true,
389
+		realname: realname,
389 390
 	}
390 391
 
391 392
 	client.SetMode(modes.TLS, true)
@@ -1707,6 +1708,7 @@ const (
1707 1708
 	IncludeChannels uint = 1 << iota
1708 1709
 	IncludeLastSeen
1709 1710
 	IncludeUserModes
1711
+	IncludeRealname
1710 1712
 )
1711 1713
 
1712 1714
 func (client *Client) markDirty(dirtyBits uint) {
@@ -1778,6 +1780,9 @@ func (client *Client) performWrite(additionalDirtyBits uint) {
1778 1780
 		}
1779 1781
 		client.server.accounts.saveModes(account, uModes)
1780 1782
 	}
1783
+	if (dirtyBits & IncludeRealname) != 0 {
1784
+		client.server.accounts.saveRealname(account, client.realname)
1785
+	}
1781 1786
 }
1782 1787
 
1783 1788
 // Blocking store; see Channel.Store and Socket.BlockingWrite

+ 0
- 7
irc/client_lookup_set.go 查看文件

@@ -122,7 +122,6 @@ func (clients *ClientManager) SetNick(client *Client, session *Session, newNick
122 122
 	accountName := client.accountName
123 123
 	settings := client.accountSettings
124 124
 	registered := client.registered
125
-	realname := client.realname
126 125
 	client.stateMutex.RUnlock()
127 126
 
128 127
 	// recompute always-on status, because client.alwaysOn is not set for unregistered clients
@@ -225,12 +224,6 @@ func (clients *ClientManager) SetNick(client *Client, session *Session, newNick
225 224
 			client.server.stats.AddRegistered(invisible, operator)
226 225
 		}
227 226
 		session.autoreplayMissedSince = lastSeen
228
-		// XXX SetNames only changes names if they are unset, so the realname change only
229
-		// takes effect on first attach to an always-on client (good), but the user/ident
230
-		// change is always a no-op (bad). we could make user/ident act the same way as
231
-		// realname, but then we'd have to send CHGHOST and i don't want to deal with that
232
-		// for performance reasons
233
-		currentClient.SetNames("user", realname, true)
234 227
 		// successful reattach!
235 228
 		return newNick, nil, back
236 229
 	} else if currentClient == client && currentClient.Nick() == newNick {

+ 4
- 0
irc/getters.go 查看文件

@@ -373,7 +373,11 @@ func (client *Client) SetMode(mode modes.Mode, on bool) bool {
373 373
 func (client *Client) SetRealname(realname string) {
374 374
 	client.stateMutex.Lock()
375 375
 	client.realname = realname
376
+	alwaysOn := client.alwaysOn
376 377
 	client.stateMutex.Unlock()
378
+	if alwaysOn {
379
+		client.markDirty(IncludeRealname)
380
+	}
377 381
 }
378 382
 
379 383
 func (client *Client) Channels() (result []*Channel) {

+ 5
- 0
irc/handlers.go 查看文件

@@ -2514,6 +2514,11 @@ func sceneHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
2514 2514
 // SETNAME <realname>
2515 2515
 func setnameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2516 2516
 	realname := msg.Params[0]
2517
+	if realname == "" {
2518
+		rb.Add(nil, server.name, "FAIL", "SETNAME", "INVALID_REALNAME", client.t("Realname is not valid"))
2519
+		return false
2520
+	}
2521
+
2517 2522
 	client.SetRealname(realname)
2518 2523
 	details := client.Details()
2519 2524
 

正在加载...
取消
保存