From 9f6c4363b7111fd3cc7bf23583ef5c97724ccf54 Mon Sep 17 00:00:00 2001 From: Daniel Oaks Date: Mon, 6 Mar 2017 09:14:15 +1000 Subject: [PATCH] USERHOST: Clean up a bit, support multiple nicks --- irc/help.go | 5 +++-- irc/server.go | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/irc/help.go b/irc/help.go index 7a60c67f..23751a2f 100644 --- a/irc/help.go +++ b/irc/help.go @@ -371,8 +371,9 @@ Used in connection registration, sets your username and realname to the given values (though your username may also be looked up with Ident).`, }, "userhost": { - text: `Show the nick, user and host of a user. Normally only used by the client or in scripts. -Note: if you are not an IRCOp then it will show a cloaked hostname if the user is +x (and it's not yourself). `, + text: `USERHOST { } + +Shows information about the given users. Takes up to 10 nicknames.`, }, "version": { text: `VERSION [server] diff --git a/irc/server.go b/irc/server.go index a1b71af1..673cfd3b 100644 --- a/irc/server.go +++ b/irc/server.go @@ -339,7 +339,7 @@ func (server *Server) setISupport() { server.isupport.Add("RPCHAN", "E") server.isupport.Add("RPUSER", "E") server.isupport.Add("STATUSMSG", "~&@%+") - server.isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%s,TAGMSG:%s,NOTICE:%s,MONITOR:", maxTargetsString, maxTargetsString, maxTargetsString)) + server.isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:%s,TAGMSG:%s,NOTICE:%s,MONITOR:", maxTargetsString, maxTargetsString, maxTargetsString)) server.isupport.Add("TOPICLEN", strconv.Itoa(server.limits.TopicLen)) // account registration @@ -1851,19 +1851,38 @@ func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { // USERHOST [ ...] func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { - nickname := msg.Params[0] + returnedNicks := make(map[string]bool) - casefoldedNickname, err := CasefoldName(nickname) - target := server.clients.Get(casefoldedNickname) - if err != nil || target == nil { - client.Send(nil, client.server.name, ERR_NOSUCHNICK, nickname, "No such nick") - return false + for i, nickname := range msg.Params { + if i >= 10 { + break + } + + casefoldedNickname, err := CasefoldName(nickname) + target := server.clients.Get(casefoldedNickname) + if err != nil || target == nil { + client.Send(nil, client.server.name, ERR_NOSUCHNICK, nickname, "No such nick") + return false + } + if returnedNicks[casefoldedNickname] { + continue + } + + // to prevent returning multiple results for a single nick + returnedNicks[casefoldedNickname] = true + + var isOper, isAway string + + if target.flags[Operator] { + isOper = "*" + } + if target.flags[Away] { + isAway = "-" + } else { + isAway = "+" + } + client.Send(nil, client.server.name, RPL_USERHOST, client.nick, fmt.Sprintf("%s%s=%s%s@%s", target.nick, isOper, isAway, target.username, target.hostname)) } - if target.flags[Away] { - client.Send(nil, client.server.name, RPL_USERHOST, client.nick, fmt.Sprintf("%s=-%s@%s", target.nick, target.username, target.hostname)) - } else { - client.Send(nil, client.server.name, RPL_USERHOST, client.nick, fmt.Sprintf("%s=+%s@%s", target.nick, target.username, target.hostname)) - } return false }