Преглед на файлове

Merge remote-tracking branch 'origin/master' into monoffline

tags/v2.1.0
Shivaram Lingamneni преди 4 години
родител
ревизия
aafc89feaa
променени са 12 файла, в които са добавени 81 реда и са изтрити 34 реда
  1. 0
    1
      irc/client.go
  2. 1
    1
      irc/config.go
  3. 2
    0
      irc/handlers.go
  4. 17
    14
      irc/modes.go
  5. 25
    0
      irc/modes/modes.go
  6. 7
    7
      irc/modes_test.go
  7. 3
    0
      irc/nickname.go
  8. 11
    7
      irc/server.go
  9. 4
    1
      irc/stats.go
  10. 1
    1
      irc/utils/args.go
  11. 8
    0
      irc/utils/args_test.go
  12. 2
    2
      languages/ro-RO-irc.lang.json

+ 0
- 1
irc/client.go Целия файл

337
 	session.idletimer.Initialize(session)
337
 	session.idletimer.Initialize(session)
338
 	session.resetFakelag()
338
 	session.resetFakelag()
339
 
339
 
340
-	ApplyUserModeChanges(client, config.Accounts.defaultUserModes, false, nil)
341
 	if wConn.Secure {
340
 	if wConn.Secure {
342
 		client.SetMode(modes.TLS, true)
341
 		client.SetMode(modes.TLS, true)
343
 	}
342
 	}

+ 1
- 1
irc/config.go Целия файл

256
 		exemptedNets []net.IPNet
256
 		exemptedNets []net.IPNet
257
 	} `yaml:"require-sasl"`
257
 	} `yaml:"require-sasl"`
258
 	DefaultUserModes    *string `yaml:"default-user-modes"`
258
 	DefaultUserModes    *string `yaml:"default-user-modes"`
259
-	defaultUserModes    modes.ModeChanges
259
+	defaultUserModes    modes.Modes
260
 	LDAP                ldap.ServerConfig
260
 	LDAP                ldap.ServerConfig
261
 	LoginThrottling     ThrottleConfig `yaml:"login-throttling"`
261
 	LoginThrottling     ThrottleConfig `yaml:"login-throttling"`
262
 	SkipServerPassword  bool           `yaml:"skip-server-password"`
262
 	SkipServerPassword  bool           `yaml:"skip-server-password"`

+ 2
- 0
irc/handlers.go Целия файл

2724
 		}
2724
 		}
2725
 		clientNick := client.Nick()
2725
 		clientNick := client.Nick()
2726
 		rb.Add(nil, client.server.name, RPL_WHOISUSER, clientNick, service.Name, service.Name, "localhost", "*", fmt.Sprintf(client.t("Network service, for more info /msg %s HELP"), service.Name))
2726
 		rb.Add(nil, client.server.name, RPL_WHOISUSER, clientNick, service.Name, service.Name, "localhost", "*", fmt.Sprintf(client.t("Network service, for more info /msg %s HELP"), service.Name))
2727
+		// #1080:
2728
+		rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, clientNick, service.Name, client.t("is a network service"))
2727
 		// hehe
2729
 		// hehe
2728
 		if client.HasMode(modes.TLS) {
2730
 		if client.HasMode(modes.TLS) {
2729
 			rb.Add(nil, client.server.name, RPL_WHOISSECURE, clientNick, service.Name, client.t("is using a secure connection"))
2731
 			rb.Add(nil, client.server.name, RPL_WHOISSECURE, clientNick, service.Name, client.t("is using a secure connection"))

+ 17
- 14
irc/modes.go Целия файл

23
 
23
 
24
 	// DefaultUserModes are set on all users when they login.
24
 	// DefaultUserModes are set on all users when they login.
25
 	// this can be overridden in the `accounts` config, with the `default-user-modes` key
25
 	// this can be overridden in the `accounts` config, with the `default-user-modes` key
26
-	DefaultUserModes = modes.ModeChanges{}
26
+	DefaultUserModes = modes.Modes{}
27
 )
27
 )
28
 
28
 
29
 // ApplyUserModeChanges applies the given changes, and returns the applied changes.
29
 // ApplyUserModeChanges applies the given changes, and returns the applied changes.
110
 	return applied
110
 	return applied
111
 }
111
 }
112
 
112
 
113
+// parseDefaultModes uses the provided mode change parser to parse the rawModes.
114
+func parseDefaultModes(rawModes string, parser func(params ...string) (modes.ModeChanges, map[rune]bool)) modes.Modes {
115
+	modeChangeStrings := strings.Fields(rawModes)
116
+	modeChanges, _ := parser(modeChangeStrings...)
117
+	defaultModes := make(modes.Modes, 0)
118
+	for _, modeChange := range modeChanges {
119
+		if modeChange.Op == modes.Add {
120
+			defaultModes = append(defaultModes, modeChange.Mode)
121
+		}
122
+	}
123
+	return defaultModes
124
+}
125
+
113
 // ParseDefaultChannelModes parses the `default-modes` line of the config
126
 // ParseDefaultChannelModes parses the `default-modes` line of the config
114
 func ParseDefaultChannelModes(rawModes *string) modes.Modes {
127
 func ParseDefaultChannelModes(rawModes *string) modes.Modes {
115
 	if rawModes == nil {
128
 	if rawModes == nil {
116
 		// not present in config, fall back to compile-time default
129
 		// not present in config, fall back to compile-time default
117
 		return DefaultChannelModes
130
 		return DefaultChannelModes
118
 	}
131
 	}
119
-	modeChangeStrings := strings.Fields(*rawModes)
120
-	modeChanges, _ := modes.ParseChannelModeChanges(modeChangeStrings...)
121
-	defaultChannelModes := make(modes.Modes, 0)
122
-	for _, modeChange := range modeChanges {
123
-		if modeChange.Op == modes.Add {
124
-			defaultChannelModes = append(defaultChannelModes, modeChange.Mode)
125
-		}
126
-	}
127
-	return defaultChannelModes
132
+	return parseDefaultModes(*rawModes, modes.ParseChannelModeChanges)
128
 }
133
 }
129
 
134
 
130
 // ParseDefaultUserModes parses the `default-user-modes` line of the config
135
 // ParseDefaultUserModes parses the `default-user-modes` line of the config
131
-func ParseDefaultUserModes(rawModes *string) modes.ModeChanges {
136
+func ParseDefaultUserModes(rawModes *string) modes.Modes {
132
 	if rawModes == nil {
137
 	if rawModes == nil {
133
 		// not present in config, fall back to compile-time default
138
 		// not present in config, fall back to compile-time default
134
 		return DefaultUserModes
139
 		return DefaultUserModes
135
 	}
140
 	}
136
-	modeChangeStrings := strings.Fields(*rawModes)
137
-	modeChanges, _ := modes.ParseUserModeChanges(modeChangeStrings...)
138
-	return modeChanges
141
+	return parseDefaultModes(*rawModes, modes.ParseUserModeChanges)
139
 }
142
 }
140
 
143
 
141
 // #1021: channel key must be valid as a non-final parameter
144
 // #1021: channel key must be valid as a non-final parameter

+ 25
- 0
irc/modes/modes.go Целия файл

6
 package modes
6
 package modes
7
 
7
 
8
 import (
8
 import (
9
+	"sort"
9
 	"strings"
10
 	"strings"
10
 
11
 
11
 	"github.com/oragono/oragono/irc/utils"
12
 	"github.com/oragono/oragono/irc/utils"
418
 	}
419
 	}
419
 	return
420
 	return
420
 }
421
 }
422
+
423
+type ByCodepoint Modes
424
+
425
+func (a ByCodepoint) Len() int           { return len(a) }
426
+func (a ByCodepoint) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
427
+func (a ByCodepoint) Less(i, j int) bool { return a[i] < a[j] }
428
+
429
+func RplMyInfo() (param1, param2, param3 string) {
430
+	userModes := make(Modes, len(SupportedUserModes))
431
+	copy(userModes, SupportedUserModes)
432
+	sort.Sort(ByCodepoint(userModes))
433
+
434
+	channelModes := make(Modes, len(SupportedChannelModes)+len(ChannelUserModes))
435
+	copy(channelModes, SupportedChannelModes)
436
+	copy(channelModes[len(SupportedChannelModes):], ChannelUserModes)
437
+	sort.Sort(ByCodepoint(channelModes))
438
+
439
+	// XXX enumerate these by hand, i can't see any way to DRY this
440
+	channelParametrizedModes := Modes{BanMask, ExceptMask, InviteMask, Key, UserLimit}
441
+	channelParametrizedModes = append(channelParametrizedModes, ChannelUserModes...)
442
+	sort.Sort(ByCodepoint(channelParametrizedModes))
443
+
444
+	return userModes.String(), channelModes.String(), channelParametrizedModes.String()
445
+}

+ 7
- 7
irc/modes_test.go Целия файл

43
 
43
 
44
 	var parseTests = []struct {
44
 	var parseTests = []struct {
45
 		raw      *string
45
 		raw      *string
46
-		expected modes.ModeChanges
46
+		expected modes.Modes
47
 	}{
47
 	}{
48
-		{&iR, modes.ModeChanges{{Mode: modes.Invisible, Op: modes.Add}, {Mode: modes.RegisteredOnly, Op: modes.Add}}},
49
-		{&i, modes.ModeChanges{{Mode: modes.Invisible, Op: modes.Add}}},
50
-		{&empty, modes.ModeChanges{}},
51
-		{&rminusi, modes.ModeChanges{{Mode: modes.RegisteredOnly, Op: modes.Add}}},
52
-		{nil, modes.ModeChanges{}},
48
+		{&iR, modes.Modes{modes.Invisible, modes.RegisteredOnly}},
49
+		{&i, modes.Modes{modes.Invisible}},
50
+		{&empty, modes.Modes{}},
51
+		{&rminusi, modes.Modes{modes.RegisteredOnly}},
52
+		{nil, modes.Modes{}},
53
 	}
53
 	}
54
 
54
 
55
 	for _, testcase := range parseTests {
55
 	for _, testcase := range parseTests {
56
 		result := ParseDefaultUserModes(testcase.raw)
56
 		result := ParseDefaultUserModes(testcase.raw)
57
 		if !reflect.DeepEqual(result, testcase.expected) {
57
 		if !reflect.DeepEqual(result, testcase.expected) {
58
-			t.Errorf("expected modes %v, got %v", testcase.expected, result)
58
+			t.Errorf("expected modes %s, got %s", testcase.expected, result)
59
 		}
59
 		}
60
 	}
60
 	}
61
 }
61
 }

+ 3
- 0
irc/nickname.go Целия файл

18
 var (
18
 var (
19
 	restrictedNicknames = []string{
19
 	restrictedNicknames = []string{
20
 		"=scene=", // used for rp commands
20
 		"=scene=", // used for rp commands
21
+		"Global",  // global announcements on some networks
22
+		// common services not implemented by us:
23
+		"MemoServ", "BotServ", "OperServ",
21
 	}
24
 	}
22
 
25
 
23
 	restrictedCasefoldedNicks = make(map[string]bool)
26
 	restrictedCasefoldedNicks = make(map[string]bool)

+ 11
- 7
irc/server.go Целия файл

36
 	// common error line to sub values into
36
 	// common error line to sub values into
37
 	errorMsg = "ERROR :%s\r\n"
37
 	errorMsg = "ERROR :%s\r\n"
38
 
38
 
39
-	// supportedUserModesString acts as a cache for when we introduce users
40
-	supportedUserModesString = modes.SupportedUserModes.String()
41
-	// supportedChannelModesString acts as a cache for when we introduce users
42
-	supportedChannelModesString = modes.SupportedChannelModes.String()
39
+	// three final parameters of 004 RPL_MYINFO, enumerating our supported modes
40
+	rplMyInfo1, rplMyInfo2, rplMyInfo3 = modes.RplMyInfo()
43
 
41
 
44
 	// whitelist of caps to serve on the STS-only listener. In particular,
42
 	// whitelist of caps to serve on the STS-only listener. In particular,
45
 	// never advertise SASL, to discourage people from sending their passwords:
43
 	// never advertise SASL, to discourage people from sending their passwords:
266
 		return true
264
 		return true
267
 	}
265
 	}
268
 
266
 
267
+	// Apply default user modes (without updating the invisible counter)
268
+	// The number of invisible users will be updated by server.stats.Register
269
+	// if we're using default user mode +i.
270
+	for _, defaultMode := range server.Config().Accounts.defaultUserModes {
271
+		c.SetMode(defaultMode, true)
272
+	}
273
+
269
 	// registration has succeeded:
274
 	// registration has succeeded:
270
 	c.SetRegistered()
275
 	c.SetRegistered()
271
 
276
 
272
 	// count new user in statistics
277
 	// count new user in statistics
273
-	server.stats.Register()
278
+	server.stats.Register(c.HasMode(modes.Invisible))
274
 	server.monitorManager.AlertAbout(c.Nick(), c.NickCasefolded(), true)
279
 	server.monitorManager.AlertAbout(c.Nick(), c.NickCasefolded(), true)
275
 
280
 
276
 	server.playRegistrationBurst(session)
281
 	server.playRegistrationBurst(session)
290
 	session.Send(nil, server.name, RPL_WELCOME, d.nick, fmt.Sprintf(c.t("Welcome to the Internet Relay Network %s"), d.nick))
295
 	session.Send(nil, server.name, RPL_WELCOME, d.nick, fmt.Sprintf(c.t("Welcome to the Internet Relay Network %s"), d.nick))
291
 	session.Send(nil, server.name, RPL_YOURHOST, d.nick, fmt.Sprintf(c.t("Your host is %[1]s, running version %[2]s"), server.name, Ver))
296
 	session.Send(nil, server.name, RPL_YOURHOST, d.nick, fmt.Sprintf(c.t("Your host is %[1]s, running version %[2]s"), server.name, Ver))
292
 	session.Send(nil, server.name, RPL_CREATED, d.nick, fmt.Sprintf(c.t("This server was created %s"), server.ctime.Format(time.RFC1123)))
297
 	session.Send(nil, server.name, RPL_CREATED, d.nick, fmt.Sprintf(c.t("This server was created %s"), server.ctime.Format(time.RFC1123)))
293
-	//TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
294
-	session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
298
+	session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, rplMyInfo1, rplMyInfo2, rplMyInfo3)
295
 
299
 
296
 	if c.isSTSOnly {
300
 	if c.isSTSOnly {
297
 		for _, line := range server.Config().Server.STS.bannerLines {
301
 		for _, line := range server.Config().Server.STS.bannerLines {

+ 4
- 1
irc/stats.go Целия файл

41
 }
41
 }
42
 
42
 
43
 // Transition a client from unregistered to registered
43
 // Transition a client from unregistered to registered
44
-func (s *Stats) Register() {
44
+func (s *Stats) Register(invisible bool) {
45
 	s.mutex.Lock()
45
 	s.mutex.Lock()
46
 	s.Unknown -= 1
46
 	s.Unknown -= 1
47
+	if invisible {
48
+		s.Invisible += 1
49
+	}
47
 	s.Total += 1
50
 	s.Total += 1
48
 	s.setMax()
51
 	s.setMax()
49
 	s.mutex.Unlock()
52
 	s.mutex.Unlock()

+ 1
- 1
irc/utils/args.go Целия файл

35
 			continue
35
 			continue
36
 		}
36
 		}
37
 
37
 
38
-		if len(buffer) > 1 {
38
+		if len(buffer) > 0 {
39
 			buffer += delim
39
 			buffer += delim
40
 		}
40
 		}
41
 		buffer += arguments[0]
41
 		buffer += arguments[0]

+ 8
- 0
irc/utils/args_test.go Целия файл

5
 
5
 
6
 import "testing"
6
 import "testing"
7
 
7
 
8
+func TestArgsToStrings(t *testing.T) {
9
+	val := ArgsToStrings(512, []string{"a", "b", "c"}, ",")
10
+	assertEqual(val, []string{"a,b,c"}, t)
11
+
12
+	val = ArgsToStrings(10, []string{"abcd", "efgh", "ijkl"}, ",")
13
+	assertEqual(val, []string{"abcd,efgh", "ijkl"}, t)
14
+}
15
+
8
 func TestStringToBool(t *testing.T) {
16
 func TestStringToBool(t *testing.T) {
9
 	val, err := StringToBool("on")
17
 	val, err := StringToBool("on")
10
 	assertEqual(val, true, t)
18
 	assertEqual(val, true, t)

+ 2
- 2
languages/ro-RO-irc.lang.json Целия файл

235
   "That nickname is already reserved by someone else": "Pseudonimul este rezervat de altcineva",
235
   "That nickname is already reserved by someone else": "Pseudonimul este rezervat de altcineva",
236
   "That nickname is not registered": "Pseudonimul nu este înregistrat",
236
   "That nickname is not registered": "Pseudonimul nu este înregistrat",
237
   "That vhost isn't being offered by the server": "Gazda virtuală nu este oferită de către server",
237
   "That vhost isn't being offered by the server": "Gazda virtuală nu este oferită de către server",
238
-  "The following vhosts are available and can be chosen with /HOSTSERV TAKE:": "",
238
+  "The following vhosts are available and can be chosen with /HOSTSERV TAKE:": "Următoarele gazde virtuale sunt disponibile și pot fi alese cu comanda /HOSTSERV TAKE:",
239
   "The server does not offer any vhosts": "Serverul nu oferă nici o gazdă virtuală",
239
   "The server does not offer any vhosts": "Serverul nu oferă nici o gazdă virtuală",
240
   "The server does not offer any vhosts, but you can request one with /HOSTSERV REQUEST": "Serverul nu oferă nici o gazdă virtuală, actualmente. Poți cere una, cu comanda /HOSTSERV REQUEST",
240
   "The server does not offer any vhosts, but you can request one with /HOSTSERV REQUEST": "Serverul nu oferă nici o gazdă virtuală, actualmente. Poți cere una, cu comanda /HOSTSERV REQUEST",
241
   "The stored channel history setting is: %s": "Setarea pentru stocarea istoricului mesajelor canalului este: %s",
241
   "The stored channel history setting is: %s": "Setarea pentru stocarea istoricului mesajelor canalului este: %s",
317
   "You're not logged into an account": "Nu te-ai autentificat la niciun cont",
317
   "You're not logged into an account": "Nu te-ai autentificat la niciun cont",
318
   "You're not on that channel": "Nu te afli pe acel canal",
318
   "You're not on that channel": "Nu te afli pe acel canal",
319
   "You're now logged in as %s": "Te-ai autentificat ca: %s",
319
   "You're now logged in as %s": "Te-ai autentificat ca: %s",
320
-  "Your account credentials are managed externally and cannot be changed here": "",
320
+  "Your account credentials are managed externally and cannot be changed here": "Credențialele contului tău sunt administrate extern și nu pot fi modificate aici",
321
   "Your account is not configured to receive autoreplayed missed messages": "Contul tău nu este configurat pentru derularea automată a mesajelor pierdute",
321
   "Your account is not configured to receive autoreplayed missed messages": "Contul tău nu este configurat pentru derularea automată a mesajelor pierdute",
322
   "Your client does not support BRB": "Clientul folosit de tine nu suportă BRB",
322
   "Your client does not support BRB": "Clientul folosit de tine nu suportă BRB",
323
   "Your host is %[1]s, running version %[2]s": "Gazda ta este %[1]s, rulând versiunea %[2]s",
323
   "Your host is %[1]s, running version %[2]s": "Gazda ta este %[1]s, rulând versiunea %[2]s",

Loading…
Отказ
Запис