Put handlers into a seperate file
This commit is contained in:
parent
5100578e7b
commit
3424c8e396
|
@ -0,0 +1,246 @@
|
|||
// vim:ts=4:sts=4:sw=4:noet:tw=72
|
||||
|
||||
package ircd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"code.dnix.de/an/irc"
|
||||
"code.dnix.de/an/xlog"
|
||||
)
|
||||
|
||||
type commandHook struct {
|
||||
HookFn func(sv *Server, msg *irc.Message)
|
||||
MinArgs int
|
||||
NeedTrail bool
|
||||
NeedMode string
|
||||
}
|
||||
|
||||
var svCommandHooks = map[string]commandHook{
|
||||
"PRIVMSG": {handleCmdPrivmsg, 1, true, ""},
|
||||
"JOIN": {handleCmdJoin, 1, false, ""},
|
||||
"PART": {handleCmdPart, 1, false, ""},
|
||||
"QUIT": {handleCmdQuit, 0, false, ""},
|
||||
"MODE": {handleCmdMode, 1, false, ""},
|
||||
"TOPIC": {handleCmdTopic, 1, false, ""},
|
||||
"KICK": {handleCmdKick, 2, false, ""},
|
||||
"NAMES": {handleCmdNames, 1, false, ""},
|
||||
"WHOIS": {handleCmdWhois, 0, false, ""},
|
||||
"PING": {handleCmdPing, 1, false, ""},
|
||||
"REHASH": {handleCmdRehash, 0, false, "ao"},
|
||||
"KILL": {handleCmdKill, 0, false, "ao"},
|
||||
/*
|
||||
"LIST": {handleCmdList, 0, false, false},
|
||||
"VERSION": {handleCmdVersion, 0, false, false},
|
||||
"STATS": {handleCmdStats, 0, false, false},
|
||||
"TIME": {handleCmdTime, 0, false, false},
|
||||
"OPER": {handleCmdOper, 1, false, false},
|
||||
"ADMIN": {handleCmdAdmin, 0, false, false},
|
||||
"INFO": {handleCmdInfo, 0, false, false},
|
||||
"WHO": {handleCmdWho, 0, false, false},
|
||||
"WHOWAS": {handleCmdWhowas, 0, false, false},
|
||||
"PONG": {handleCmdPong, 0, false, false},
|
||||
"ERROR": {handleCmdError, 0, false, false},
|
||||
"AWAY": {handleCmdAway, 0, false, false},
|
||||
"RESTART": {handleCmdRestart, 0, false, false},
|
||||
"SUMMON": {handleCmdSummon, 0, false, false},
|
||||
"USERS": {handleCmdUsers, 0, false, false},
|
||||
"USERHOST": {handleCmdUserhost, 0, false, false},
|
||||
"ISON": {handleCmdIson, 0, false, false},
|
||||
*/
|
||||
}
|
||||
|
||||
func handleCmdPrivmsg(sv *Server, msg *irc.Message) {
|
||||
if strings.HasPrefix(msg.Args[0], "#") {
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if sv.channelCheckMode(chid, "m") &&
|
||||
!sv.channelCheckPerm(chid, clid, "ohv") {
|
||||
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
|
||||
return
|
||||
}
|
||||
if _, exists := sv.chUsers[chid][clid]; !exists {
|
||||
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
|
||||
return
|
||||
}
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
}
|
||||
|
||||
func handleCmdJoin(sv *Server, msg *irc.Message) {
|
||||
first := false
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
sv.chUsers[chid] = make(map[string]string)
|
||||
sv.chTopics[chid] = ""
|
||||
sv.chModes[chid] = make(map[string]bool)
|
||||
first = true
|
||||
}
|
||||
if _, exists := sv.chUsers[chid][clid]; exists {
|
||||
return
|
||||
}
|
||||
sv.chUsers[chid][clid] = ""
|
||||
sv.sendMsg(msg)
|
||||
sv.sendReply(msg.Pre, RPL_TOPIC, msg.Args[0], sv.chTopics[msg.Args[0]])
|
||||
sv.channelNames(msg.Pre, msg.Args[0])
|
||||
_, isop := sv.opers[clid]
|
||||
if first || isop {
|
||||
mode := "o " + clid
|
||||
sv.chModes[chid][mode] = true
|
||||
sv.sendMsg(irc.M(sv.host, "MODE", chid+" +o "+clid, ""))
|
||||
}
|
||||
if isop {
|
||||
sv.sendMsg(irc.M(sv.host, "PRIVMSG", chid, clid+" is a server operator"))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle user parting the channel and delete channel if last user has
|
||||
// left
|
||||
func handleCmdPart(sv *Server, msg *irc.Message) {
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
return
|
||||
}
|
||||
if _, exists := sv.chUsers[chid][clid]; !exists {
|
||||
return
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
delete(sv.chUsers[chid], clid)
|
||||
delete(sv.chModes[chid], "o "+clid)
|
||||
delete(sv.chModes[chid], "h "+clid)
|
||||
delete(sv.chModes[chid], "v "+clid)
|
||||
if len(sv.chUsers[chid]) == 0 {
|
||||
delete(sv.chUsers, chid)
|
||||
delete(sv.chTopics, chid)
|
||||
delete(sv.chModes, chid)
|
||||
}
|
||||
}
|
||||
|
||||
func handleCmdQuit(sv *Server, msg *irc.Message) {
|
||||
|
||||
}
|
||||
|
||||
func handleCmdMode(sv *Server, msg *irc.Message) {
|
||||
if strings.HasPrefix(msg.Args[0], "#") {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
return
|
||||
}
|
||||
if len(msg.Args) < 2 {
|
||||
return
|
||||
}
|
||||
mode := ""
|
||||
modeSwitch := msg.Args[1]
|
||||
modeTarget := ""
|
||||
if len(modeSwitch) < 2 {
|
||||
return
|
||||
}
|
||||
if len(msg.Args) > 2 {
|
||||
modeTarget = strings.ToLower(msg.Args[2])
|
||||
}
|
||||
switch modeSwitch[1] {
|
||||
// maybe this can be done more elegant
|
||||
case 'o':
|
||||
if !sv.channelCheckPerm(chid, clid, "o") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'h':
|
||||
if !sv.channelCheckPerm(chid, clid, "o") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'b':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'v':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'm':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
case 't':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
mode = string(modeSwitch[1])
|
||||
if modeTarget != "" {
|
||||
mode = mode + " " + modeTarget
|
||||
}
|
||||
if modeSwitch[0] == '+' {
|
||||
sv.chModes[chid][mode] = true
|
||||
} else {
|
||||
delete(sv.chModes[chid], mode)
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
return
|
||||
noPerm:
|
||||
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||
}
|
||||
}
|
||||
|
||||
func handleCmdTopic(sv *Server, msg *irc.Message) {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
|
||||
}
|
||||
if msg.Trail == "" {
|
||||
sv.sendReply(msg.Pre, RPL_TOPIC, chid, sv.chTopics[chid])
|
||||
} else {
|
||||
if sv.channelCheckMode(chid, "t") &&
|
||||
!sv.channelCheckPerm(chid, clid, "oh") {
|
||||
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||
return
|
||||
}
|
||||
sv.chTopics[chid] = msg.Trail
|
||||
sv.sendMsg(msg)
|
||||
//sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
|
||||
}
|
||||
}
|
||||
|
||||
func handleCmdKick(sv *Server, msg *irc.Message) {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
target := strings.ToLower(msg.Args[1])
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
delete(sv.chUsers[chid], target)
|
||||
delete(sv.chModes[chid], "o "+target)
|
||||
delete(sv.chModes[chid], "h "+target)
|
||||
delete(sv.chModes[chid], "v "+target)
|
||||
}
|
||||
|
||||
func handleCmdNames(sv *Server, msg *irc.Message) {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
|
||||
}
|
||||
sv.channelNames(msg.Pre, chid)
|
||||
}
|
||||
|
||||
func handleCmdWhois(sv *Server, msg *irc.Message) {
|
||||
sv.sendReply(msg.Pre, RPL_WHOISUSER, "nick user host *", "real name")
|
||||
}
|
||||
|
||||
func handleCmdPing(sv *Server, msg *irc.Message) {
|
||||
sv.sendReply(msg.Pre, "PONG", msg.Args[0], "")
|
||||
}
|
||||
|
||||
func handleCmdRehash(sv *Server, msg *irc.Message) {
|
||||
sv.loadConfig()
|
||||
sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.")
|
||||
xlog.Info("Rehashing")
|
||||
}
|
||||
|
||||
func handleCmdKill(sv *Server, msg *irc.Message) {
|
||||
}
|
236
server.go
236
server.go
|
@ -355,239 +355,3 @@ func (sv *Server) channelCheckPerm(chid, clid, modes string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type commandHook struct {
|
||||
HookFn func(sv *Server, msg *irc.Message)
|
||||
MinArgs int
|
||||
NeedTrail bool
|
||||
NeedMode string
|
||||
}
|
||||
|
||||
var svCommandHooks = map[string]commandHook{
|
||||
"PRIVMSG": {handleCmdPrivmsg, 1, true, ""},
|
||||
"JOIN": {handleCmdJoin, 1, false, ""},
|
||||
"PART": {handleCmdPart, 1, false, ""},
|
||||
"QUIT": {handleCmdQuit, 0, false, ""},
|
||||
"MODE": {handleCmdMode, 1, false, ""},
|
||||
"TOPIC": {handleCmdTopic, 1, false, ""},
|
||||
"KICK": {handleCmdKick, 2, false, ""},
|
||||
"NAMES": {handleCmdNames, 1, false, ""},
|
||||
"WHOIS": {handleCmdWhois, 0, false, ""},
|
||||
"PING": {handleCmdPing, 1, false, ""},
|
||||
"REHASH": {handleCmdRehash, 0, false, "ao"},
|
||||
"KILL": {handleCmdKill, 0, false, "ao"},
|
||||
/*
|
||||
"LIST": {handleCmdList, 0, false, false},
|
||||
"VERSION": {handleCmdVersion, 0, false, false},
|
||||
"STATS": {handleCmdStats, 0, false, false},
|
||||
"TIME": {handleCmdTime, 0, false, false},
|
||||
"OPER": {handleCmdOper, 1, false, false},
|
||||
"ADMIN": {handleCmdAdmin, 0, false, false},
|
||||
"INFO": {handleCmdInfo, 0, false, false},
|
||||
"WHO": {handleCmdWho, 0, false, false},
|
||||
"WHOWAS": {handleCmdWhowas, 0, false, false},
|
||||
"PONG": {handleCmdPong, 0, false, false},
|
||||
"ERROR": {handleCmdError, 0, false, false},
|
||||
"AWAY": {handleCmdAway, 0, false, false},
|
||||
"RESTART": {handleCmdRestart, 0, false, false},
|
||||
"SUMMON": {handleCmdSummon, 0, false, false},
|
||||
"USERS": {handleCmdUsers, 0, false, false},
|
||||
"USERHOST": {handleCmdUserhost, 0, false, false},
|
||||
"ISON": {handleCmdIson, 0, false, false},
|
||||
*/
|
||||
}
|
||||
|
||||
func handleCmdPrivmsg(sv *Server, msg *irc.Message) {
|
||||
if strings.HasPrefix(msg.Args[0], "#") {
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if sv.channelCheckMode(chid, "m") &&
|
||||
!sv.channelCheckPerm(chid, clid, "ohv") {
|
||||
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
|
||||
return
|
||||
}
|
||||
if _, exists := sv.chUsers[chid][clid]; !exists {
|
||||
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
|
||||
return
|
||||
}
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
}
|
||||
|
||||
func handleCmdJoin(sv *Server, msg *irc.Message) {
|
||||
first := false
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
sv.chUsers[chid] = make(map[string]string)
|
||||
sv.chTopics[chid] = ""
|
||||
sv.chModes[chid] = make(map[string]bool)
|
||||
first = true
|
||||
}
|
||||
if _, exists := sv.chUsers[chid][clid]; exists {
|
||||
return
|
||||
}
|
||||
sv.chUsers[chid][clid] = ""
|
||||
sv.sendMsg(msg)
|
||||
sv.sendReply(msg.Pre, RPL_TOPIC, msg.Args[0], sv.chTopics[msg.Args[0]])
|
||||
sv.channelNames(msg.Pre, msg.Args[0])
|
||||
_, isop := sv.opers[clid]
|
||||
if first || isop {
|
||||
mode := "o " + clid
|
||||
sv.chModes[chid][mode] = true
|
||||
sv.sendMsg(irc.M(sv.host, "MODE", chid+" +o "+clid, ""))
|
||||
}
|
||||
if isop {
|
||||
sv.sendMsg(irc.M(sv.host, "PRIVMSG", chid, clid+" is a server operator"))
|
||||
}
|
||||
}
|
||||
|
||||
// Handle user parting the channel and delete channel if last user has
|
||||
// left
|
||||
func handleCmdPart(sv *Server, msg *irc.Message) {
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
return
|
||||
}
|
||||
if _, exists := sv.chUsers[chid][clid]; !exists {
|
||||
return
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
delete(sv.chUsers[chid], clid)
|
||||
delete(sv.chModes[chid], "o "+clid)
|
||||
delete(sv.chModes[chid], "h "+clid)
|
||||
delete(sv.chModes[chid], "v "+clid)
|
||||
if len(sv.chUsers[chid]) == 0 {
|
||||
delete(sv.chUsers, chid)
|
||||
delete(sv.chTopics, chid)
|
||||
delete(sv.chModes, chid)
|
||||
}
|
||||
}
|
||||
|
||||
func handleCmdQuit(sv *Server, msg *irc.Message) {
|
||||
|
||||
}
|
||||
|
||||
func handleCmdMode(sv *Server, msg *irc.Message) {
|
||||
if strings.HasPrefix(msg.Args[0], "#") {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
return
|
||||
}
|
||||
if len(msg.Args) < 2 {
|
||||
return
|
||||
}
|
||||
mode := ""
|
||||
modeSwitch := msg.Args[1]
|
||||
modeTarget := ""
|
||||
if len(modeSwitch) < 2 {
|
||||
return
|
||||
}
|
||||
if len(msg.Args) > 2 {
|
||||
modeTarget = strings.ToLower(msg.Args[2])
|
||||
}
|
||||
switch modeSwitch[1] {
|
||||
// maybe this can be done more elegant
|
||||
case 'o':
|
||||
if !sv.channelCheckPerm(chid, clid, "o") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'h':
|
||||
if !sv.channelCheckPerm(chid, clid, "o") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'b':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'v':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
case 'm':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
case 't':
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
goto noPerm
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
mode = string(modeSwitch[1])
|
||||
if modeTarget != "" {
|
||||
mode = mode + " " + modeTarget
|
||||
}
|
||||
if modeSwitch[0] == '+' {
|
||||
sv.chModes[chid][mode] = true
|
||||
} else {
|
||||
delete(sv.chModes[chid], mode)
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
return
|
||||
noPerm:
|
||||
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||
}
|
||||
}
|
||||
|
||||
func handleCmdTopic(sv *Server, msg *irc.Message) {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
|
||||
}
|
||||
if msg.Trail == "" {
|
||||
sv.sendReply(msg.Pre, RPL_TOPIC, chid, sv.chTopics[chid])
|
||||
} else {
|
||||
if sv.channelCheckMode(chid, "t") &&
|
||||
!sv.channelCheckPerm(chid, clid, "oh") {
|
||||
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||
return
|
||||
}
|
||||
sv.chTopics[chid] = msg.Trail
|
||||
sv.sendMsg(msg)
|
||||
//sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
|
||||
}
|
||||
}
|
||||
|
||||
func handleCmdKick(sv *Server, msg *irc.Message) {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
target := strings.ToLower(msg.Args[1])
|
||||
if !sv.channelCheckPerm(chid, clid, "oh") {
|
||||
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
|
||||
}
|
||||
sv.sendMsg(msg)
|
||||
delete(sv.chUsers[chid], target)
|
||||
delete(sv.chModes[chid], "o "+target)
|
||||
delete(sv.chModes[chid], "h "+target)
|
||||
delete(sv.chModes[chid], "v "+target)
|
||||
}
|
||||
|
||||
func handleCmdNames(sv *Server, msg *irc.Message) {
|
||||
chid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.chUsers[chid]; !exists {
|
||||
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
|
||||
}
|
||||
sv.channelNames(msg.Pre, chid)
|
||||
}
|
||||
|
||||
func handleCmdWhois(sv *Server, msg *irc.Message) {
|
||||
sv.sendReply(msg.Pre, RPL_WHOISUSER, "nick user host *", "real name")
|
||||
}
|
||||
|
||||
func handleCmdPing(sv *Server, msg *irc.Message) {
|
||||
sv.sendReply(msg.Pre, "PONG", msg.Args[0], "")
|
||||
}
|
||||
|
||||
func handleCmdRehash(sv *Server, msg *irc.Message) {
|
||||
sv.loadConfig()
|
||||
sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.")
|
||||
xlog.Info("Rehashing")
|
||||
}
|
||||
|
||||
func handleCmdKill(sv *Server, msg *irc.Message) {
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue