|
|
package irc
import ( "strings"
"github.com/gissleh/irc/list" )
// A Channel is a target that manages the userlist
type Channel struct { id string name string userlist *list.List parted bool }
// ID returns a unique ID for the channel target.
func (channel *Channel) ID() string { return channel.id }
// Kind returns "channel"
func (channel *Channel) Kind() string { return "channel" }
// Name gets the channel name
func (channel *Channel) Name() string { return channel.name }
func (channel *Channel) State() ClientStateTarget { return ClientStateTarget{ Kind: "channel", Name: channel.name, Users: channel.userlist.Users(), } }
// UserList gets the channel userlist
func (channel *Channel) UserList() list.Immutable { return channel.userlist.Immutable() }
// Parted returnes whether the channel has been parted
func (channel *Channel) Parted() bool { return channel.parted }
// AddHandler handles messages routed to this channel by the client's event loop
func (channel *Channel) Handle(event *Event, client *Client) { switch event.Name() { case "packet.join": { // Support extended-join
account := "" if accountArg := event.Arg(1); accountArg != "" && accountArg != "*" { account = accountArg }
channel.userlist.Insert(list.User{ Nick: event.Nick, User: event.User, Host: event.Host, Account: account, }) } case "packet.part", "packet.quit": { channel.userlist.Remove(event.Nick) } case "packet.kick": { channel.userlist.Remove(event.Arg(1)) } case "packet.nick": { channel.userlist.Rename(event.Nick, event.Arg(0)) } case "packet.account": { newAccount := event.Arg(0)
if newAccount != "*" && newAccount != "" { channel.userlist.Patch(event.Nick, list.UserPatch{Account: newAccount}) } else { channel.userlist.Patch(event.Nick, list.UserPatch{ClearAccount: true}) } } case "packet.away": { if event.Text != "" { channel.userlist.Patch(event.Nick, list.UserPatch{Away: event.Text}) } else { channel.userlist.Patch(event.Nick, list.UserPatch{ClearAway: true}) } } case "packet.chghost": { newUser := event.Arg(0) newHost := event.Arg(1)
channel.userlist.Patch(event.Nick, list.UserPatch{User: newUser, Host: newHost}) } case "packet.353": // NAMES
{ channel.userlist.SetAutoSort(false) tokens := strings.Split(event.Text, " ") for _, token := range tokens { channel.userlist.InsertFromNamesToken(token) } } case "packet.366": // End of NAMES
{ channel.userlist.SetAutoSort(true) } case "packet.mode": { isupport := client.ISupport() plus := false argIndex := 2
for _, ch := range event.Arg(1) { if ch == '+' { plus = true continue } if ch == '-' { plus = false continue }
arg := "" if isupport.ModeTakesArgument(ch, plus) { arg = event.Arg(argIndex) argIndex++ }
if isupport.IsPermissionMode(ch) { if plus { channel.userlist.AddMode(arg, ch) } else { channel.userlist.RemoveMode(arg, ch) } } else { // TODO: track non-permission modes
} } } case "packet.privmsg", "ctcp.action": { if accountTag, ok := event.Tags["account"]; ok && accountTag != "" { channel.userlist.Patch(event.Nick, list.UserPatch{Account: accountTag}) } } } }
|