NAMES responses for global added.
When no parameter is passed all channels and global are returned Now prevents invisible users from being revealed
This commit is contained in:
parent
aa1780a415
commit
e31fe5d24d
19
channel.go
19
channel.go
@ -84,13 +84,15 @@ func (c *Channel) Join(client *Client, key string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Names responds to to IRC NAMES command for the channel
|
// Names responds to to IRC NAMES command for the channel
|
||||||
func (c *Channel) Names(client *Client) {
|
func (c *Channel) Names(client *Client) []string {
|
||||||
|
|
||||||
if c.HasMode(ChannelModeSecret) && !c.HasMember(client) { // If channel is secret and client isn't a member, don't reveal it
|
var named []string
|
||||||
return
|
isMember := c.HasMember(client)
|
||||||
|
if c.HasMode(ChannelModeSecret) && !isMember { // If channel is secret and client isn't a member, don't reveal it
|
||||||
|
return named
|
||||||
}
|
}
|
||||||
if c.HasMode(ChannelModePrivate) && !c.HasMember(client) { // If channel is private and client isn't a member, don't reply
|
if c.HasMode(ChannelModePrivate) && !isMember { // If channel is private and client isn't a member, don't reply
|
||||||
return
|
return named
|
||||||
}
|
}
|
||||||
|
|
||||||
allMembers := make([]string, len(c.members))
|
allMembers := make([]string, len(c.members))
|
||||||
@ -120,6 +122,9 @@ func (c *Channel) Names(client *Client) {
|
|||||||
|
|
||||||
for _, member := range allMembers[i*20 : end] {
|
for _, member := range allMembers[i*20 : end] {
|
||||||
mClient, _ := client.Server.GetClientByNick(member)
|
mClient, _ := client.Server.GetClientByNick(member)
|
||||||
|
if mClient.HasMode(UserModeInvisible) && !isMember { //the requesting client shouldn't know about this client
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if mClient != nil {
|
if mClient != nil {
|
||||||
if c.MemberHasMode(mClient, ChannelModeOperator) {
|
if c.MemberHasMode(mClient, ChannelModeOperator) {
|
||||||
@ -128,6 +133,7 @@ func (c *Channel) Names(client *Client) {
|
|||||||
memberStr += "+"
|
memberStr += "+"
|
||||||
}
|
}
|
||||||
memberStr += mClient.Nickname + " "
|
memberStr += mClient.Nickname + " "
|
||||||
|
named = append(named, mClient.Nickname)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +143,7 @@ func (c *Channel) Names(client *Client) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m := irc.Message{Prefix: c.Server.Prefix, Command: irc.RPL_ENDOFNAMES, Params: []string{client.Nickname, c.Name}, Trailing: "End of NAMES list"}
|
return named
|
||||||
client.Encode(&m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Part handles when a client leaves a channel
|
// Part handles when a client leaves a channel
|
||||||
|
@ -273,8 +273,8 @@ func (c *Client) SendMessagetoVisible(m *irc.Message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendWho rmanages responding to the WHO request for all visible clients of this client
|
// Who rmanages responding to the WHO request for all visible clients of this client
|
||||||
func (c *Client) SendWho() {
|
func (c *Client) Who() {
|
||||||
clients := map[string]*Client{}
|
clients := map[string]*Client{}
|
||||||
for name, client := range c.Server.clientsByNick {
|
for name, client := range c.Server.clientsByNick {
|
||||||
if client.HasMode(UserModeInvisible) {
|
if client.HasMode(UserModeInvisible) {
|
||||||
|
46
commands.go
46
commands.go
@ -315,7 +315,7 @@ func NoticeHandler(message *irc.Message, client *Client) {
|
|||||||
func WhoHandler(message *irc.Message, client *Client) {
|
func WhoHandler(message *irc.Message, client *Client) {
|
||||||
if len(message.Params) == 0 || len(message.Params[0]) == 0 || message.Params[0][0] == '*' {
|
if len(message.Params) == 0 || len(message.Params[0]) == 0 || message.Params[0][0] == '*' {
|
||||||
//return listing of all visible users - visible people and people in channels with this client
|
//return listing of all visible users - visible people and people in channels with this client
|
||||||
client.SendWho()
|
client.Who()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -786,20 +786,58 @@ func ChannelModeHandler(message *irc.Message, client *Client) {
|
|||||||
// Implemented according to RFC 1459 Section 4.2.5 and RFC 2812 Section 3.2.5
|
// Implemented according to RFC 1459 Section 4.2.5 and RFC 2812 Section 3.2.5
|
||||||
func NamesHandler(message *irc.Message, client *Client) {
|
func NamesHandler(message *irc.Message, client *Client) {
|
||||||
if len(message.Params) == 0 { // Send NAMES response for all channels
|
if len(message.Params) == 0 { // Send NAMES response for all channels
|
||||||
|
|
||||||
|
named := map[string]interface{}{}
|
||||||
for _, ch := range client.Server.channels {
|
for _, ch := range client.Server.channels {
|
||||||
ch.Names(client)
|
n := ch.Names(client)
|
||||||
|
for _, k := range n {
|
||||||
|
named[k] = nil
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
count := 0
|
||||||
|
memberStr := ""
|
||||||
|
for n, cl := range client.Server.clientsByNick {
|
||||||
|
_, alreadyNamed := named[n]
|
||||||
|
if !alreadyNamed && !cl.HasMode(UserModeInvisible) { //don't name people that are already named or that shouldn't be named
|
||||||
|
count++
|
||||||
|
if cl != nil {
|
||||||
|
if cl.HasMode(UserModeOperator) || cl.HasMode(UserModeLocalOperator) {
|
||||||
|
memberStr += "@"
|
||||||
|
}
|
||||||
|
memberStr += cl.Nickname + " "
|
||||||
|
|
||||||
|
}
|
||||||
|
if count%20 == 0 { // String is long enough, send message
|
||||||
|
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_NAMREPLY, Params: []string{client.Nickname, "*", "*"}, Trailing: memberStr}
|
||||||
|
client.Encode(&m)
|
||||||
|
memberStr = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_NAMREPLY, Params: []string{client.Nickname, "*", "*"}, Trailing: memberStr}
|
||||||
|
client.Encode(&m)
|
||||||
|
m = irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_ENDOFNAMES, Params: []string{client.Nickname, "*"}, Trailing: "End of NAMES list"}
|
||||||
|
client.Encode(&m)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(message.Params) == 2 { //Client has provided target server for the request
|
||||||
|
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.ERR_NOSUCHSERVER, Params: []string{client.Nickname, message.Params[0]}, Trailing: "No such server"}
|
||||||
|
client.Encode(&m)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
channelNames := strings.Split(message.Params[0], ",")
|
channelNames := strings.Split(message.Params[0], ",")
|
||||||
for _, channelName := range channelNames {
|
for _, channelName := range channelNames {
|
||||||
ch, ok := client.Server.GetChannel(channelName)
|
ch, ok := client.Server.GetChannel(channelName)
|
||||||
if ok {
|
if ok {
|
||||||
ch.Names(client)
|
ch.Names(client)
|
||||||
|
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_ENDOFNAMES, Params: []string{client.Nickname, ch.Name}, Trailing: "End of NAMES list"}
|
||||||
|
client.Encode(&m)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MOTDHandler is a specialized CommandHandler to respond to channel IRC MOTD commands from a client
|
// MOTDHandler is a specialized CommandHandler to respond to channel IRC MOTD commands from a client
|
||||||
// Implemented according to RFC 1459 Section 8.5 and RFC 2812 Section 3.4.1
|
// Implemented according to RFC 1459 Section 8.5 and RFC 2812 Section 3.4.1
|
||||||
|
Loading…
Reference in New Issue
Block a user