Added support for IRC LIST command

This commit is contained in:
Justin 2015-08-08 10:57:25 -07:00
parent e8faa15312
commit 72875efb89
2 changed files with 76 additions and 1 deletions

View File

@ -1,6 +1,7 @@
package irc
import (
"strconv"
"strings"
"sync"
@ -350,6 +351,7 @@ func (c *Channel) TopicCommand(client *Client, topic string) {
//Client is trying to get topic
if len(topic) == 0 { //Get channels topic
if len(c.Topic) == 0 { // No topic is not set
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_NOTOPIC, Params: []string{c.Name}, Trailing: "No topic is set"}
client.Encode(&m)
@ -449,3 +451,17 @@ func (c *Channel) GetLimit() int {
return val.(int)
}
// ListMessage creates and returns the message that should be sent for an IRC LIST query
func (c *Channel) ListMessage(client *Client) (m *irc.Message) {
if c.HasMode(ChannelModeSecret) && !c.HasMember(client) { // If channel is secret and client isn't a member, don't reveal it
return
}
m = &irc.Message{Prefix: c.Server.Prefix, Command: irc.RPL_LIST, Params: []string{client.Nickname, c.Name, strconv.Itoa(c.GetMemberCount())}, Trailing: c.Topic + " "}
if c.HasMode(ChannelModePrivate) && !c.HasMember(client) { // If channel is private and client isn't a member, don't return topic
m.Trailing = " "
return
}
return
}

View File

@ -359,7 +359,7 @@ func TopicHandler(message *irc.Message, client *Client) {
channelName := message.Params[0]
channel, ok := client.Server.GetChannel(channelName)
if !ok {
if !ok || channel.HasMode(ChannelModeSecret) {
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.ERR_NOSUCHCHANNEL, Params: []string{client.Nickname, channelName}, Trailing: "No such channel"}
client.Encode(&m)
return
@ -625,6 +625,29 @@ func ChannelModeHandler(message *irc.Message, client *Client) {
if modifier == ModeModifierAdd {
needsArgs = append(needsArgs, fullFlag{modifier, flag, ""})
}
default:
found := channel.HasMode(flag)
if modifier == ModeModifierAdd {
if !found {
if flag == ChannelModePrivate && channel.HasMode(ChannelModeSecret) {
// Secret and private can't both be set
continue
}
if flag == ChannelModeSecret && channel.HasMode(ChannelModePrivate) {
// Secret and private can't both be set
channel.RemoveMode(ChannelModePrivate)
}
channel.AddMode(flag)
changes = append(changes, fullFlag{modifier, flag, ""})
}
} else {
if found {
channel.RemoveMode(flag)
changes = append(changes, fullFlag{modifier, flag, ""})
}
}
}
}
@ -678,3 +701,39 @@ func NamesHandler(message *irc.Message, client *Client) {
func MOTDHandler(message *irc.Message, client *Client) {
client.MOTD()
}
// ListHandler is a specialized CommandHandler to respond to channel IRC LIST commands from a client
// Implemented according to RFC 1459 Section 4.2.6 and RFC 2812 Section 3.2.6
func ListHandler(message *irc.Message, client *Client) {
/* Deprecated in RFC 2812
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_LISTSTART, Params: []string{client.Nickname, "Channel :Users Name"}}
client.Encode(&m)
*/
if len(message.Params) == 0 || len(message.Params[0]) == 0 { // Send LIST response for all channels
for _, ch := range client.Server.channels {
m := ch.ListMessage(client)
if m != nil {
fmt.Println(m.String())
client.Encode(m)
}
}
} else {
channelNames := strings.Split(message.Params[0], ",")
for _, channelName := range channelNames {
ch, ok := client.Server.GetChannel(channelName)
if ok {
m := ch.ListMessage(client)
if m != nil {
fmt.Println(m.String())
client.Encode(m)
}
}
}
}
m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_LISTEND, Params: []string{client.Nickname}, Trailing: "End of LIST"}
client.Encode(&m)
}