|
@@ -3435,12 +3435,21 @@ func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
|
3435
|
3435
|
return false
|
3436
|
3436
|
}
|
3437
|
3437
|
|
|
3438
|
+ // https://modern.ircdocs.horse/#who-message
|
|
3439
|
+ // "1. A channel name, in which case the channel members are listed."
|
|
3440
|
+ // "2. An exact nickname, in which case a single user is returned."
|
|
3441
|
+ // "3. A mask pattern, in which case all visible users whose nickname matches are listed."
|
|
3442
|
+ var isChannel bool
|
|
3443
|
+ var isBareNick bool
|
3438
|
3444
|
mask := origMask
|
3439
|
3445
|
var err error
|
3440
|
|
- if mask[0] == '#' {
|
3441
|
|
- mask, err = CasefoldChannel(msg.Params[0])
|
|
3446
|
+ if origMask[0] == '#' {
|
|
3447
|
+ mask, err = CasefoldChannel(origMask)
|
|
3448
|
+ isChannel = true
|
|
3449
|
+ } else if !strings.ContainsAny(origMask, protocolBreakingNameCharacters) {
|
|
3450
|
+ isBareNick = true
|
3442
|
3451
|
} else {
|
3443
|
|
- mask, err = CanonicalizeMaskWildcard(mask)
|
|
3452
|
+ mask, err = CanonicalizeMaskWildcard(origMask)
|
3444
|
3453
|
}
|
3445
|
3454
|
|
3446
|
3455
|
if err != nil {
|
|
@@ -3491,7 +3500,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
|
3491
|
3500
|
oper := client.Oper()
|
3492
|
3501
|
hasPrivs := oper.HasRoleCapab("sajoin")
|
3493
|
3502
|
canSeeIPs := oper.HasRoleCapab("ban")
|
3494
|
|
- if mask[0] == '#' {
|
|
3503
|
+ if isChannel {
|
3495
|
3504
|
channel := server.channels.Get(mask)
|
3496
|
3505
|
if channel != nil {
|
3497
|
3506
|
isJoined := channel.hasClient(client)
|
|
@@ -3509,6 +3518,11 @@ func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
|
3509
|
3518
|
}
|
3510
|
3519
|
}
|
3511
|
3520
|
}
|
|
3521
|
+ } else if isBareNick {
|
|
3522
|
+ mclient := server.clients.Get(mask)
|
|
3523
|
+ if mclient != nil {
|
|
3524
|
+ client.rplWhoReply(nil, mclient, rb, canSeeIPs, oper != nil, includeRFlag, isWhox, fields, whoType)
|
|
3525
|
+ }
|
3512
|
3526
|
} else {
|
3513
|
3527
|
// Construct set of channels the client is in.
|
3514
|
3528
|
userChannels := make(ChannelSet)
|