mirror of https://github.com/gissleh/irc.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.3 KiB
157 lines
3.3 KiB
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})
|
|
}
|
|
}
|
|
}
|
|
}
|