Kaynağa Gözat

fix #526

tags/v1.2.0-rc1
Shivaram Lingamneni 5 yıl önce
ebeveyn
işleme
5a554ab4b0
6 değiştirilmiş dosya ile 108 ekleme ve 66 silme
  1. 12
    25
      irc/client.go
  2. 2
    9
      irc/handlers.go
  3. 5
    0
      irc/languages/languages.go
  4. 2
    0
      irc/numerics.go
  5. 31
    7
      irc/server.go
  6. 56
    25
      irc/stats.go

+ 12
- 25
irc/client.go Dosyayı Görüntüle

275
 	client.rawHostname = session.rawHostname
275
 	client.rawHostname = session.rawHostname
276
 	client.proxiedIP = session.proxiedIP
276
 	client.proxiedIP = session.proxiedIP
277
 
277
 
278
+	server.stats.Add()
278
 	client.run(session)
279
 	client.run(session)
279
 }
280
 }
280
 
281
 
359
 	return ip
360
 	return ip
360
 }
361
 }
361
 
362
 
363
+// t returns the translated version of the given string, based on the languages configured by the client.
364
+func (client *Client) t(originalString string) string {
365
+	languageManager := client.server.Config().languageManager
366
+	if !languageManager.Enabled() {
367
+		return originalString
368
+	}
369
+	return languageManager.Translate(client.Languages(), originalString)
370
+}
371
+
362
 //
372
 //
363
 // command goroutine
373
 // command goroutine
364
 //
374
 //
921
 	return client.Account() != ""
931
 	return client.Account() != ""
922
 }
932
 }
923
 
933
 
924
-// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses.
925
-func (client *Client) RplISupport(rb *ResponseBuffer) {
926
-	translatedISupport := client.t("are supported by this server")
927
-	nick := client.Nick()
928
-	config := client.server.Config()
929
-	for _, cachedTokenLine := range config.Server.isupport.CachedReply {
930
-		length := len(cachedTokenLine) + 2
931
-		tokenline := make([]string, length)
932
-		tokenline[0] = nick
933
-		copy(tokenline[1:], cachedTokenLine)
934
-		tokenline[length-1] = translatedISupport
935
-		rb.Add(nil, client.server.name, RPL_ISUPPORT, tokenline...)
936
-	}
937
-}
938
-
939
 // Quit sets the given quit message for the client.
934
 // Quit sets the given quit message for the client.
940
 // (You must ensure separately that destroy() is called, e.g., by returning `true` from
935
 // (You must ensure separately that destroy() is called, e.g., by returning `true` from
941
 // the command handler or calling it yourself.)
936
 // the command handler or calling it yourself.)
1094
 
1089
 
1095
 	client.server.accounts.Logout(client)
1090
 	client.server.accounts.Logout(client)
1096
 
1091
 
1097
-	// send quit messages to friends
1098
-	if registered {
1099
-		client.server.stats.ChangeTotal(-1)
1100
-	}
1101
-	if client.HasMode(modes.Invisible) {
1102
-		client.server.stats.ChangeInvisible(-1)
1103
-	}
1104
-	if client.HasMode(modes.Operator) || client.HasMode(modes.LocalOperator) {
1105
-		client.server.stats.ChangeOperators(-1)
1106
-	}
1092
+	client.server.stats.Remove(registered, client.HasMode(modes.Invisible),
1093
+		client.HasMode(modes.Operator) || client.HasMode(modes.LocalOperator))
1107
 
1094
 
1108
 	// this happens under failure to return from BRB
1095
 	// this happens under failure to return from BRB
1109
 	if quitMessage == "" {
1096
 	if quitMessage == "" {

+ 2
- 9
irc/handlers.go Dosyayı Görüntüle

1638
 
1638
 
1639
 // LUSERS [<mask> [<server>]]
1639
 // LUSERS [<mask> [<server>]]
1640
 func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1640
 func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1641
-	//TODO(vegax87) Fix network statistics and additional parameters
1642
-	totalCount, invisibleCount, operCount := server.stats.GetStats()
1643
-
1644
-	rb.Add(nil, server.name, RPL_LUSERCLIENT, client.nick, fmt.Sprintf(client.t("There are %[1]d users and %[2]d invisible on %[3]d server(s)"), totalCount-invisibleCount, invisibleCount, 1))
1645
-	rb.Add(nil, server.name, RPL_LUSEROP, client.nick, strconv.Itoa(operCount), client.t("IRC Operators online"))
1646
-	rb.Add(nil, server.name, RPL_LUSERCHANNELS, client.nick, strconv.Itoa(server.channels.Len()), client.t("channels formed"))
1647
-	rb.Add(nil, server.name, RPL_LUSERME, client.nick, fmt.Sprintf(client.t("I have %[1]d clients and %[2]d servers"), totalCount, 1))
1648
-
1641
+	server.Lusers(client, rb)
1649
 	return false
1642
 	return false
1650
 }
1643
 }
1651
 
1644
 
2582
 // VERSION
2575
 // VERSION
2583
 func versionHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2576
 func versionHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2584
 	rb.Add(nil, server.name, RPL_VERSION, client.nick, Ver, server.name)
2577
 	rb.Add(nil, server.name, RPL_VERSION, client.nick, Ver, server.name)
2585
-	client.RplISupport(rb)
2578
+	server.RplISupport(client, rb)
2586
 	return false
2579
 	return false
2587
 }
2580
 }
2588
 
2581
 

+ 5
- 0
irc/languages/languages.go Dosyayı Görüntüle

164
 	return len(lm.Languages)
164
 	return len(lm.Languages)
165
 }
165
 }
166
 
166
 
167
+// Enabled returns whether translation is enabled.
168
+func (lm *Manager) Enabled() bool {
169
+	return len(lm.translations) != 0
170
+}
171
+
167
 // Translators returns the languages we have and the translators.
172
 // Translators returns the languages we have and the translators.
168
 func (lm *Manager) Translators() []string {
173
 func (lm *Manager) Translators() []string {
169
 	var tlist sort.StringSlice
174
 	var tlist sort.StringSlice

+ 2
- 0
irc/numerics.go Dosyayı Görüntüle

50
 	RPL_TRACELOG                  = "261"
50
 	RPL_TRACELOG                  = "261"
51
 	RPL_TRACEEND                  = "262"
51
 	RPL_TRACEEND                  = "262"
52
 	RPL_TRYAGAIN                  = "263"
52
 	RPL_TRYAGAIN                  = "263"
53
+	RPL_LOCALUSERS                = "265"
54
+	RPL_GLOBALUSERS               = "266"
53
 	RPL_WHOISCERTFP               = "276"
55
 	RPL_WHOISCERTFP               = "276"
54
 	RPL_AWAY                      = "301"
56
 	RPL_AWAY                      = "301"
55
 	RPL_USERHOST                  = "302"
57
 	RPL_USERHOST                  = "302"

+ 31
- 7
irc/server.go Dosyayı Görüntüle

386
 	c.SetRegistered()
386
 	c.SetRegistered()
387
 
387
 
388
 	// count new user in statistics
388
 	// count new user in statistics
389
-	server.stats.ChangeTotal(1)
389
+	server.stats.Register()
390
 	server.monitorManager.AlertAbout(c, true)
390
 	server.monitorManager.AlertAbout(c, true)
391
 
391
 
392
 	server.playRegistrationBurst(session)
392
 	server.playRegistrationBurst(session)
410
 	session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
410
 	session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
411
 
411
 
412
 	rb := NewResponseBuffer(session)
412
 	rb := NewResponseBuffer(session)
413
-	c.RplISupport(rb)
413
+	server.RplISupport(c, rb)
414
+	server.Lusers(c, rb)
414
 	server.MOTD(c, rb)
415
 	server.MOTD(c, rb)
415
 	rb.Send(true)
416
 	rb.Send(true)
416
 
417
 
423
 	}
424
 	}
424
 }
425
 }
425
 
426
 
426
-// t returns the translated version of the given string, based on the languages configured by the client.
427
-func (client *Client) t(originalString string) string {
428
-	// TODO(slingamn) investigate a fast path for this, using an atomic load to see if translation is disabled
429
-	languages := client.Languages()
430
-	return client.server.Languages().Translate(languages, originalString)
427
+// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses.
428
+func (server *Server) RplISupport(client *Client, rb *ResponseBuffer) {
429
+	translatedISupport := client.t("are supported by this server")
430
+	nick := client.Nick()
431
+	config := server.Config()
432
+	for _, cachedTokenLine := range config.Server.isupport.CachedReply {
433
+		length := len(cachedTokenLine) + 2
434
+		tokenline := make([]string, length)
435
+		tokenline[0] = nick
436
+		copy(tokenline[1:], cachedTokenLine)
437
+		tokenline[length-1] = translatedISupport
438
+		rb.Add(nil, server.name, RPL_ISUPPORT, tokenline...)
439
+	}
440
+}
441
+
442
+func (server *Server) Lusers(client *Client, rb *ResponseBuffer) {
443
+	nick := client.Nick()
444
+	stats := server.stats.GetValues()
445
+
446
+	rb.Add(nil, server.name, RPL_LUSERCLIENT, nick, fmt.Sprintf(client.t("There are %[1]d users and %[2]d invisible on %[3]d server(s)"), stats.Total-stats.Invisible, stats.Invisible, 1))
447
+	rb.Add(nil, server.name, RPL_LUSEROP, nick, strconv.Itoa(stats.Operators), client.t("IRC Operators online"))
448
+	rb.Add(nil, server.name, RPL_LUSERUNKNOWN, nick, strconv.Itoa(stats.Unknown), client.t("unregistered connections"))
449
+	rb.Add(nil, server.name, RPL_LUSERCHANNELS, nick, strconv.Itoa(server.channels.Len()), client.t("channels formed"))
450
+	rb.Add(nil, server.name, RPL_LUSERME, nick, fmt.Sprintf(client.t("I have %[1]d clients and %[2]d servers"), stats.Total, 1))
451
+	total := strconv.Itoa(stats.Total)
452
+	max := strconv.Itoa(stats.Max)
453
+	rb.Add(nil, server.name, RPL_LOCALUSERS, nick, total, max, fmt.Sprintf(client.t("Current local users %[1]s, max %[2]s"), total, max))
454
+	rb.Add(nil, server.name, RPL_GLOBALUSERS, nick, total, max, fmt.Sprintf(client.t("Current global users %[1]s, max %[2]s"), total, max))
431
 }
455
 }
432
 
456
 
433
 // MOTD serves the Message of the Day.
457
 // MOTD serves the Message of the Day.

+ 56
- 25
irc/stats.go Dosyayı Görüntüle

4
 	"sync"
4
 	"sync"
5
 )
5
 )
6
 
6
 
7
-// Stats contains the numbers of total, invisible and operators on the server
8
-type Stats struct {
9
-	sync.RWMutex
10
-
11
-	Total     int
7
+type StatsValues struct {
8
+	Unknown   int // unregistered clients
9
+	Total     int // registered clients, including invisible
10
+	Max       int // high-water mark of registered clients
12
 	Invisible int
11
 	Invisible int
13
 	Operators int
12
 	Operators int
14
 }
13
 }
15
 
14
 
16
-// ChangeTotal increments the total user count on server
17
-func (s *Stats) ChangeTotal(i int) {
18
-	s.Lock()
19
-	defer s.Unlock()
15
+// Stats tracks statistics for a running server
16
+type Stats struct {
17
+	StatsValues
18
+
19
+	mutex sync.Mutex
20
+}
20
 
21
 
21
-	s.Total += i
22
+// Adds an unregistered client
23
+func (s *Stats) Add() {
24
+	s.mutex.Lock()
25
+	s.Unknown += 1
26
+	s.mutex.Unlock()
22
 }
27
 }
23
 
28
 
24
-// ChangeInvisible increments the invisible count
25
-func (s *Stats) ChangeInvisible(i int) {
26
-	s.Lock()
27
-	defer s.Unlock()
29
+// Transition a client from unregistered to registered
30
+func (s *Stats) Register() {
31
+	s.mutex.Lock()
32
+	s.Unknown -= 1
33
+	s.Total += 1
34
+	if s.Max < s.Total {
35
+		s.Max = s.Total
36
+	}
37
+	s.mutex.Unlock()
38
+}
28
 
39
 
29
-	s.Invisible += i
40
+// Modify the Invisible count
41
+func (s *Stats) ChangeInvisible(increment int) {
42
+	s.mutex.Lock()
43
+	s.Invisible += increment
44
+	s.mutex.Unlock()
30
 }
45
 }
31
 
46
 
32
-// ChangeOperators increases the operator count
33
-func (s *Stats) ChangeOperators(i int) {
34
-	s.Lock()
35
-	defer s.Unlock()
47
+// Modify the Operator count
48
+func (s *Stats) ChangeOperators(increment int) {
49
+	s.mutex.Lock()
50
+	s.Operators += increment
51
+	s.mutex.Unlock()
52
+}
36
 
53
 
37
-	s.Operators += i
54
+// Remove a user from the server
55
+func (s *Stats) Remove(registered, invisible, operator bool) {
56
+	s.mutex.Lock()
57
+	if registered {
58
+		s.Total -= 1
59
+	} else {
60
+		s.Unknown -= 1
61
+	}
62
+	if invisible {
63
+		s.Invisible -= 1
64
+	}
65
+	if operator {
66
+		s.Operators -= 1
67
+	}
68
+	s.mutex.Unlock()
38
 }
69
 }
39
 
70
 
40
 // GetStats retrives total, invisible and oper count
71
 // GetStats retrives total, invisible and oper count
41
-func (s *Stats) GetStats() (int, int, int) {
42
-	s.Lock()
43
-	defer s.Unlock()
44
-
45
-	return s.Total, s.Invisible, s.Operators
72
+func (s *Stats) GetValues() (result StatsValues) {
73
+	s.mutex.Lock()
74
+	result = s.StatsValues
75
+	s.mutex.Unlock()
76
+	return
46
 }
77
 }

Loading…
İptal
Kaydet