Browse Source

fix #1850

Add WHO responses for services
tags/v2.11.0-rc1
Shivaram Lingamneni 1 year ago
parent
commit
825cdab67d
2 changed files with 71 additions and 13 deletions
  1. 60
    6
      irc/handlers.go
  2. 11
    7
      irc/services.go

+ 60
- 6
irc/handlers.go View File

@@ -1892,7 +1892,7 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
1892 1892
 
1893 1893
 // get the correct capitalization of a nick (if it's online), otherwise return ""
1894 1894
 func (server *Server) getCurrentNick(nick string) (result string) {
1895
-	if service, isService := OragonoServices[strings.ToLower(nick)]; isService {
1895
+	if service, isService := ErgoServices[strings.ToLower(nick)]; isService {
1896 1896
 		return service.Name
1897 1897
 	} else if iclient := server.clients.Get(nick); iclient != nil {
1898 1898
 		return iclient.Nick()
@@ -2277,7 +2277,7 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi
2277 2277
 		}
2278 2278
 	} else {
2279 2279
 		lowercaseTarget := strings.ToLower(target)
2280
-		service, isService := OragonoServices[lowercaseTarget]
2280
+		service, isService := ErgoServices[lowercaseTarget]
2281 2281
 		_, isZNC := zncHandlers[lowercaseTarget]
2282 2282
 
2283 2283
 		if isService || isZNC {
@@ -3427,6 +3427,59 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response
3427 3427
 	rb.Add(nil, client.server.name, numeric, params...)
3428 3428
 }
3429 3429
 
3430
+func serviceWhoReply(client *Client, service *ircService, rb *ResponseBuffer, isWhox bool, fields whoxFields, whoType string) {
3431
+	params := []string{client.Nick()}
3432
+
3433
+	if fields.Has('t') {
3434
+		params = append(params, whoType)
3435
+	}
3436
+	if fields.Has('c') {
3437
+		params = append(params, "*")
3438
+	}
3439
+	if fields.Has('u') {
3440
+		params = append(params, service.Name)
3441
+	}
3442
+	if fields.Has('i') {
3443
+		params = append(params, "127.0.0.1")
3444
+	}
3445
+	if fields.Has('h') {
3446
+		params = append(params, "localhost")
3447
+	}
3448
+	if fields.Has('s') {
3449
+		params = append(params, client.server.name)
3450
+	}
3451
+	if fields.Has('n') {
3452
+		params = append(params, service.Name)
3453
+	}
3454
+	if fields.Has('f') { // "flags" (away + oper state + channel status prefix + bot)
3455
+		params = append(params, "H")
3456
+	}
3457
+	if fields.Has('d') { // server hops from us to target
3458
+		params = append(params, "0")
3459
+	}
3460
+	if fields.Has('l') { // idle seconds
3461
+		params = append(params, "0")
3462
+	}
3463
+	if fields.Has('a') { // account, services are considered not to have one
3464
+		params = append(params, "0")
3465
+	}
3466
+	if fields.Has('o') { // channel oplevel, not implemented
3467
+		params = append(params, "*")
3468
+	}
3469
+	if fields.Has('r') {
3470
+		params = append(params, service.Realname(client))
3471
+	}
3472
+
3473
+	numeric := RPL_WHOSPCRPL
3474
+	if !isWhox {
3475
+		numeric = RPL_WHOREPLY
3476
+		// if this isn't WHOX, stick hops + realname at the end
3477
+		params = append(params, "0 "+service.Realname(client))
3478
+	}
3479
+
3480
+	rb.Add(nil, client.server.name, numeric, params...)
3481
+}
3482
+
3430 3483
 // WHO <mask> [<filter>%<fields>,<type>]
3431 3484
 func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
3432 3485
 	origMask := utils.SafeErrorParam(msg.Params[0])
@@ -3519,9 +3572,10 @@ func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
3519 3572
 			}
3520 3573
 		}
3521 3574
 	} else if isBareNick {
3522
-		mclient := server.clients.Get(mask)
3523
-		if mclient != nil {
3575
+		if mclient := server.clients.Get(mask); mclient != nil {
3524 3576
 			client.rplWhoReply(nil, mclient, rb, canSeeIPs, oper != nil, includeRFlag, isWhox, fields, whoType)
3577
+		} else if service, ok := ErgoServices[strings.ToLower(mask)]; ok {
3578
+			serviceWhoReply(client, service, rb, isWhox, fields, whoType)
3525 3579
 		}
3526 3580
 	} else {
3527 3581
 		// Construct set of channels the client is in.
@@ -3571,7 +3625,7 @@ func whoisHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
3571 3625
 
3572 3626
 	handleService := func(nick string) bool {
3573 3627
 		cfnick, _ := CasefoldName(nick)
3574
-		service, ok := OragonoServices[cfnick]
3628
+		service, ok := ErgoServices[cfnick]
3575 3629
 		hostname := "localhost"
3576 3630
 		config := server.Config()
3577 3631
 		if config.Server.OverrideServicesHostname != "" {
@@ -3581,7 +3635,7 @@ func whoisHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
3581 3635
 			return false
3582 3636
 		}
3583 3637
 		clientNick := client.Nick()
3584
-		rb.Add(nil, client.server.name, RPL_WHOISUSER, clientNick, service.Name, service.Name, hostname, "*", fmt.Sprintf(client.t("Network service, for more info /msg %s HELP"), service.Name))
3638
+		rb.Add(nil, client.server.name, RPL_WHOISUSER, clientNick, service.Name, service.Name, hostname, "*", service.Realname(client))
3585 3639
 		// #1080:
3586 3640
 		rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, clientNick, service.Name, client.t("is a network service"))
3587 3641
 		// hehe

+ 11
- 7
irc/services.go View File

@@ -26,6 +26,10 @@ type ircService struct {
26 26
 	HelpBanner     string
27 27
 }
28 28
 
29
+func (service *ircService) Realname(client *Client) string {
30
+	return fmt.Sprintf(client.t("Network service, for more info /msg %s HELP"), service.Name)
31
+}
32
+
29 33
 // defines a command associated with a service, e.g., NICKSERV IDENTIFY
30 34
 type serviceCommand struct {
31 35
 	aliasOf           string   // marks this command as an alias of another
@@ -92,7 +96,7 @@ var (
92 96
 )
93 97
 
94 98
 // all services, by lowercase name
95
-var OragonoServices = map[string]*ircService{
99
+var ErgoServices = map[string]*ircService{
96 100
 	"nickserv": nickservService,
97 101
 	"chanserv": chanservService,
98 102
 	"hostserv": hostservService,
@@ -105,7 +109,7 @@ func (service *ircService) Notice(rb *ResponseBuffer, text string) {
105 109
 
106 110
 // all service commands at the protocol level, by uppercase command name
107 111
 // e.g., NICKSERV, NS
108
-var oragonoServicesByCommandAlias map[string]*ircService
112
+var ergoServicesByCommandAlias map[string]*ircService
109 113
 
110 114
 // special-cased command shared by all services
111 115
 var servHelpCmd serviceCommand = serviceCommand{
@@ -117,7 +121,7 @@ HELP returns information on the given command.`,
117 121
 
118 122
 // generic handler for IRC commands like `/NICKSERV INFO`
119 123
 func serviceCmdHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
120
-	service, ok := oragonoServicesByCommandAlias[msg.Command]
124
+	service, ok := ergoServicesByCommandAlias[msg.Command]
121 125
 	if !ok {
122 126
 		server.logger.Warning("internal", "can't handle unrecognized service", msg.Command)
123 127
 		return false
@@ -323,7 +327,7 @@ func overrideServicePrefixes(hostname string) error {
323 327
 	if !utils.IsHostname(hostname) {
324 328
 		return fmt.Errorf("`%s` is an invalid services hostname", hostname)
325 329
 	}
326
-	for _, serv := range OragonoServices {
330
+	for _, serv := range ErgoServices {
327 331
 		serv.prefix = fmt.Sprintf("%s!%s@%s", serv.Name, serv.Name, hostname)
328 332
 	}
329 333
 	return nil
@@ -332,9 +336,9 @@ func overrideServicePrefixes(hostname string) error {
332 336
 func initializeServices() {
333 337
 	// this modifies the global Commands map,
334 338
 	// so it must be called from irc/commands.go's init()
335
-	oragonoServicesByCommandAlias = make(map[string]*ircService)
339
+	ergoServicesByCommandAlias = make(map[string]*ircService)
336 340
 
337
-	for serviceName, service := range OragonoServices {
341
+	for serviceName, service := range ErgoServices {
338 342
 		service.prefix = fmt.Sprintf("%s!%s@localhost", service.Name, service.Name)
339 343
 
340 344
 		// make `/MSG ServiceName HELP` work correctly
@@ -349,7 +353,7 @@ func initializeServices() {
349 353
 		ircCmdDef.handler = serviceCmdHandler
350 354
 		for _, ircCmd := range service.CommandAliases {
351 355
 			Commands[ircCmd] = ircCmdDef
352
-			oragonoServicesByCommandAlias[ircCmd] = service
356
+			ergoServicesByCommandAlias[ircCmd] = service
353 357
 			Help[strings.ToLower(ircCmd)] = HelpEntry{
354 358
 				textGenerator: makeServiceHelpTextGenerator(ircCmd, service.HelpBanner),
355 359
 			}

Loading…
Cancel
Save