|
@@ -450,19 +450,27 @@ func awayHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
450
|
450
|
// CAP <subcmd> [<caps>]
|
451
|
451
|
func capHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
452
|
452
|
subCommand := strings.ToUpper(msg.Params[0])
|
453
|
|
- capabilities := caps.NewSet()
|
|
453
|
+ toAdd := caps.NewSet()
|
|
454
|
+ toRemove := caps.NewSet()
|
454
|
455
|
var capString string
|
455
|
456
|
|
456
|
|
- var badCaps []string
|
|
457
|
+ badCaps := false
|
457
|
458
|
if len(msg.Params) > 1 {
|
458
|
459
|
capString = msg.Params[1]
|
459
|
460
|
strs := strings.Fields(capString)
|
460
|
461
|
for _, str := range strs {
|
|
462
|
+ remove := false
|
|
463
|
+ if str[0] == '-' {
|
|
464
|
+ str = str[1:]
|
|
465
|
+ remove = true
|
|
466
|
+ }
|
461
|
467
|
capab, err := caps.NameToCapability(str)
|
462
|
|
- if err != nil || !SupportedCapabilities.Has(capab) {
|
463
|
|
- badCaps = append(badCaps, str)
|
|
468
|
+ if err != nil || (!remove && !SupportedCapabilities.Has(capab)) {
|
|
469
|
+ badCaps = true
|
|
470
|
+ } else if !remove {
|
|
471
|
+ toAdd.Enable(capab)
|
464
|
472
|
} else {
|
465
|
|
- capabilities.Enable(capab)
|
|
473
|
+ toRemove.Enable(capab)
|
466
|
474
|
}
|
467
|
475
|
}
|
468
|
476
|
}
|
|
@@ -490,16 +498,17 @@ func capHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
|
490
|
498
|
}
|
491
|
499
|
|
492
|
500
|
// make sure all capabilities actually exist
|
493
|
|
- if len(badCaps) > 0 {
|
|
501
|
+ if badCaps {
|
494
|
502
|
rb.Add(nil, server.name, "CAP", client.nick, "NAK", capString)
|
495
|
503
|
return false
|
496
|
504
|
}
|
497
|
|
- client.capabilities.Union(capabilities)
|
|
505
|
+ client.capabilities.Union(toAdd)
|
|
506
|
+ client.capabilities.Subtract(toRemove)
|
498
|
507
|
rb.Add(nil, server.name, "CAP", client.nick, "ACK", capString)
|
499
|
508
|
|
500
|
509
|
// if this is the first time the client is requesting a resume token,
|
501
|
510
|
// send it to them
|
502
|
|
- if capabilities.Has(caps.Resume) {
|
|
511
|
+ if toAdd.Has(caps.Resume) {
|
503
|
512
|
token, err := client.generateResumeToken()
|
504
|
513
|
if err == nil {
|
505
|
514
|
rb.Add(nil, server.name, "RESUME", "TOKEN", token)
|