mirror of https://github.com/fluffle/goirc
De-duplicate mode parsing and move to nickchan.go.
This commit is contained in:
parent
e611672b06
commit
00d25810b5
135
irc/handlers.go
135
irc/handlers.go
|
@ -3,10 +3,7 @@ package irc
|
||||||
// this file contains the basic set of event handlers
|
// this file contains the basic set of event handlers
|
||||||
// to manage tracking an irc connection etc.
|
// to manage tracking an irc connection etc.
|
||||||
|
|
||||||
import (
|
import "strings"
|
||||||
"strings"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddHandler() adds an event handler for a specific IRC command.
|
// AddHandler() adds an event handler for a specific IRC command.
|
||||||
//
|
//
|
||||||
|
@ -214,100 +211,17 @@ func (conn *Conn) h_QUIT(line *Line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle MODE changes for channels we know about (and our nick personally)
|
// Handle MODE changes for channels we know about (and our nick personally)
|
||||||
// this is moderately ugly. suggestions for improvement welcome
|
|
||||||
func (conn *Conn) h_MODE(line *Line) {
|
func (conn *Conn) h_MODE(line *Line) {
|
||||||
// channel modes first
|
// channel modes first
|
||||||
if ch := conn.GetChannel(line.Args[0]); ch != nil {
|
if ch := conn.GetChannel(line.Args[0]); ch != nil {
|
||||||
modeargs := line.Args[2:len(line.Args)]
|
conn.ParseChannelModes(ch, line.Args[1], line.Args[2:len(line.Args)])
|
||||||
var modeop bool // true => add mode, false => remove mode
|
|
||||||
var modestr string
|
|
||||||
for i := 0; i < len(line.Args[1]); i++ {
|
|
||||||
switch m := line.Args[1][i]; m {
|
|
||||||
case '+':
|
|
||||||
modeop = true
|
|
||||||
modestr = string(m)
|
|
||||||
case '-':
|
|
||||||
modeop = false
|
|
||||||
modestr = string(m)
|
|
||||||
case 'i':
|
|
||||||
ch.Modes.InviteOnly = modeop
|
|
||||||
case 'm':
|
|
||||||
ch.Modes.Moderated = modeop
|
|
||||||
case 'n':
|
|
||||||
ch.Modes.NoExternalMsg = modeop
|
|
||||||
case 'p':
|
|
||||||
ch.Modes.Private = modeop
|
|
||||||
case 's':
|
|
||||||
ch.Modes.Secret = modeop
|
|
||||||
case 't':
|
|
||||||
ch.Modes.ProtectedTopic = modeop
|
|
||||||
case 'z':
|
|
||||||
ch.Modes.SSLOnly = modeop
|
|
||||||
case 'O':
|
|
||||||
ch.Modes.OperOnly = modeop
|
|
||||||
case 'k':
|
|
||||||
if len(modeargs) != 0 {
|
|
||||||
ch.Modes.Key, modeargs = modeargs[0], modeargs[1:len(modeargs)]
|
|
||||||
} else {
|
|
||||||
conn.error("irc.MODE(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
|
||||||
}
|
|
||||||
case 'l':
|
|
||||||
if len(modeargs) != 0 {
|
|
||||||
ch.Modes.Limit, _ = strconv.Atoi(modeargs[0])
|
|
||||||
modeargs = modeargs[1:len(modeargs)]
|
|
||||||
} else {
|
|
||||||
conn.error("irc.MODE(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
|
||||||
}
|
|
||||||
case 'q', 'a', 'o', 'h', 'v':
|
|
||||||
if len(modeargs) != 0 {
|
|
||||||
n := conn.GetNick(modeargs[0])
|
|
||||||
if p, ok := ch.Nicks[n]; ok && n != nil {
|
|
||||||
switch m {
|
|
||||||
case 'q':
|
|
||||||
p.Owner = modeop
|
|
||||||
case 'a':
|
|
||||||
p.Admin = modeop
|
|
||||||
case 'o':
|
|
||||||
p.Op = modeop
|
|
||||||
case 'h':
|
|
||||||
p.HalfOp = modeop
|
|
||||||
case 'v':
|
|
||||||
p.Voice = modeop
|
|
||||||
}
|
|
||||||
modeargs = modeargs[1:len(modeargs)]
|
|
||||||
} else {
|
|
||||||
conn.error("irc.MODE(): MODE %s %s%s %s: buh? state tracking failure.", ch.Name, modestr, m, modeargs[0])
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
conn.error("irc.MODE(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if n := conn.GetNick(line.Args[0]); n != nil {
|
} else if n := conn.GetNick(line.Args[0]); n != nil {
|
||||||
// nick mode change, should be us
|
// nick mode change, should be us
|
||||||
if n != conn.Me {
|
if n != conn.Me {
|
||||||
conn.error("irc.MODE(): buh? recieved MODE %s for (non-me) nick %s", line.Text, n.Nick)
|
conn.error("irc.MODE(): buh? recieved MODE %s for (non-me) nick %s", line.Text, n.Nick)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var modeop bool // true => add mode, false => remove mode
|
conn.ParseNickModes(n, line.Text)
|
||||||
for i := 0; i < len(line.Text); i++ {
|
|
||||||
switch m := line.Text[i]; m {
|
|
||||||
case '+':
|
|
||||||
modeop = true
|
|
||||||
case '-':
|
|
||||||
modeop = false
|
|
||||||
case 'i':
|
|
||||||
n.Modes.Invisible = modeop
|
|
||||||
case 'o':
|
|
||||||
n.Modes.Oper = modeop
|
|
||||||
case 'w':
|
|
||||||
n.Modes.WallOps = modeop
|
|
||||||
case 'x':
|
|
||||||
n.Modes.HiddenHost = modeop
|
|
||||||
case 'z':
|
|
||||||
n.Modes.SSL = modeop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if line.Text != "" {
|
if line.Text != "" {
|
||||||
conn.error("irc.MODE(): buh? not sure what to do with nick MODE %s %s", line.Args[0], line.Text)
|
conn.error("irc.MODE(): buh? not sure what to do with nick MODE %s %s", line.Args[0], line.Text)
|
||||||
|
@ -341,48 +255,7 @@ func (conn *Conn) h_311(line *Line) {
|
||||||
func (conn *Conn) h_324(line *Line) {
|
func (conn *Conn) h_324(line *Line) {
|
||||||
// XXX: copypasta from MODE, needs tidying.
|
// XXX: copypasta from MODE, needs tidying.
|
||||||
if ch := conn.GetChannel(line.Args[1]); ch != nil {
|
if ch := conn.GetChannel(line.Args[1]); ch != nil {
|
||||||
modeargs := line.Args[3:len(line.Args)]
|
conn.ParseChannelModes(ch, line.Args[2], line.Args[3:len(line.Args)])
|
||||||
var modeop bool // true => add mode, false => remove mode
|
|
||||||
var modestr string
|
|
||||||
for i := 0; i < len(line.Args[2]); i++ {
|
|
||||||
switch m := line.Args[2][i]; m {
|
|
||||||
case '+':
|
|
||||||
modeop = true
|
|
||||||
modestr = string(m)
|
|
||||||
case '-':
|
|
||||||
modeop = false
|
|
||||||
modestr = string(m)
|
|
||||||
case 'i':
|
|
||||||
ch.Modes.InviteOnly = modeop
|
|
||||||
case 'm':
|
|
||||||
ch.Modes.Moderated = modeop
|
|
||||||
case 'n':
|
|
||||||
ch.Modes.NoExternalMsg = modeop
|
|
||||||
case 'p':
|
|
||||||
ch.Modes.Private = modeop
|
|
||||||
case 's':
|
|
||||||
ch.Modes.Secret = modeop
|
|
||||||
case 't':
|
|
||||||
ch.Modes.ProtectedTopic = modeop
|
|
||||||
case 'z':
|
|
||||||
ch.Modes.SSLOnly = modeop
|
|
||||||
case 'O':
|
|
||||||
ch.Modes.OperOnly = modeop
|
|
||||||
case 'k':
|
|
||||||
if len(modeargs) != 0 {
|
|
||||||
ch.Modes.Key, modeargs = modeargs[0], modeargs[1:len(modeargs)]
|
|
||||||
} else {
|
|
||||||
conn.error("irc.324(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
|
||||||
}
|
|
||||||
case 'l':
|
|
||||||
if len(modeargs) != 0 {
|
|
||||||
ch.Modes.Limit, _ = strconv.Atoi(modeargs[0])
|
|
||||||
modeargs = modeargs[1:len(modeargs)]
|
|
||||||
} else {
|
|
||||||
conn.error("irc.324(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
conn.error("irc.324(): buh? received MODE settings for unknown channel %s", line.Args[1])
|
conn.error("irc.324(): buh? received MODE settings for unknown channel %s", line.Args[1])
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package irc
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A struct representing an IRC channel
|
// A struct representing an IRC channel
|
||||||
|
@ -96,6 +97,97 @@ func (conn *Conn) GetChannel(c string) *Channel {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parses mode strings for a channel
|
||||||
|
func (conn *Conn) ParseChannelModes(ch *Channel, modes string, modeargs []string) {
|
||||||
|
var modeop bool // true => add mode, false => remove mode
|
||||||
|
var modestr string
|
||||||
|
for i := 0; i < len(modes); i++ {
|
||||||
|
switch m := modes[i]; m {
|
||||||
|
case '+':
|
||||||
|
modeop = true
|
||||||
|
modestr = string(m)
|
||||||
|
case '-':
|
||||||
|
modeop = false
|
||||||
|
modestr = string(m)
|
||||||
|
case 'i':
|
||||||
|
ch.Modes.InviteOnly = modeop
|
||||||
|
case 'm':
|
||||||
|
ch.Modes.Moderated = modeop
|
||||||
|
case 'n':
|
||||||
|
ch.Modes.NoExternalMsg = modeop
|
||||||
|
case 'p':
|
||||||
|
ch.Modes.Private = modeop
|
||||||
|
case 's':
|
||||||
|
ch.Modes.Secret = modeop
|
||||||
|
case 't':
|
||||||
|
ch.Modes.ProtectedTopic = modeop
|
||||||
|
case 'z':
|
||||||
|
ch.Modes.SSLOnly = modeop
|
||||||
|
case 'O':
|
||||||
|
ch.Modes.OperOnly = modeop
|
||||||
|
case 'k':
|
||||||
|
if len(modeargs) != 0 {
|
||||||
|
ch.Modes.Key, modeargs = modeargs[0], modeargs[1:len(modeargs)]
|
||||||
|
} else {
|
||||||
|
conn.error("irc.ParseChanModes(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
||||||
|
}
|
||||||
|
case 'l':
|
||||||
|
if len(modeargs) != 0 {
|
||||||
|
ch.Modes.Limit, _ = strconv.Atoi(modeargs[0])
|
||||||
|
modeargs = modeargs[1:len(modeargs)]
|
||||||
|
} else {
|
||||||
|
conn.error("irc.ParseChanModes(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
||||||
|
}
|
||||||
|
case 'q', 'a', 'o', 'h', 'v':
|
||||||
|
if len(modeargs) != 0 {
|
||||||
|
n := conn.GetNick(modeargs[0])
|
||||||
|
if p, ok := ch.Nicks[n]; ok && n != nil {
|
||||||
|
switch m {
|
||||||
|
case 'q':
|
||||||
|
p.Owner = modeop
|
||||||
|
case 'a':
|
||||||
|
p.Admin = modeop
|
||||||
|
case 'o':
|
||||||
|
p.Op = modeop
|
||||||
|
case 'h':
|
||||||
|
p.HalfOp = modeop
|
||||||
|
case 'v':
|
||||||
|
p.Voice = modeop
|
||||||
|
}
|
||||||
|
modeargs = modeargs[1:len(modeargs)]
|
||||||
|
} else {
|
||||||
|
conn.error("irc.ParseChanModes(): MODE %s %s%s %s: buh? state tracking failure.", ch.Name, modestr, m, modeargs[0])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
conn.error("irc.ParseChanModes(): buh? not enough arguments to process MODE %s %s%s", ch.Name, modestr, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse mode strings for a nick
|
||||||
|
func (conn *Conn) ParseNickModes(n *Nick, modes string) {
|
||||||
|
var modeop bool // true => add mode, false => remove mode
|
||||||
|
for i := 0; i < len(modes); i++ {
|
||||||
|
switch m := modes[i]; m {
|
||||||
|
case '+':
|
||||||
|
modeop = true
|
||||||
|
case '-':
|
||||||
|
modeop = false
|
||||||
|
case 'i':
|
||||||
|
n.Modes.Invisible = modeop
|
||||||
|
case 'o':
|
||||||
|
n.Modes.Oper = modeop
|
||||||
|
case 'w':
|
||||||
|
n.Modes.WallOps = modeop
|
||||||
|
case 'x':
|
||||||
|
n.Modes.HiddenHost = modeop
|
||||||
|
case 'z':
|
||||||
|
n.Modes.SSL = modeop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Channel methods for state management
|
* Channel methods for state management
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue