forked from External/ergo
Add MONITOR command
This commit is contained in:
parent
859d0cd607
commit
1bab81091f
10 changed files with 266 additions and 21 deletions
205
irc/monitor.go
Normal file
205
irc/monitor.go
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
// Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
|
||||
// released under the MIT license
|
||||
|
||||
package irc
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/DanielOaks/girc-go/ircmsg"
|
||||
)
|
||||
|
||||
// alertMonitors alerts everyone monitoring us that we're online.
|
||||
func (client *Client) alertMonitors() {
|
||||
// alert monitors
|
||||
for _, mClient := range client.server.monitoring[client.nickCasefolded] {
|
||||
// don't have to notify ourselves
|
||||
if &mClient != client {
|
||||
mClient.Send(nil, client.server.name, RPL_MONONLINE, mClient.nick, client.nickMaskString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clearMonitorList clears our MONITOR list.
|
||||
func (client *Client) clearMonitorList() {
|
||||
for name := range client.monitoring {
|
||||
// just removes current client from the list
|
||||
orig := client.server.monitoring[name]
|
||||
var index int
|
||||
for i, cli := range orig {
|
||||
if &cli == client {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
client.server.monitoring[name] = append(orig[:index], orig[index+1:]...)
|
||||
}
|
||||
|
||||
client.monitoring = make(map[string]bool)
|
||||
}
|
||||
|
||||
var (
|
||||
metadataSubcommands = map[string]func(server *Server, client *Client, msg ircmsg.IrcMessage) bool{
|
||||
"-": monitorRemoveHandler,
|
||||
"+": monitorAddHandler,
|
||||
"c": monitorClearHandler,
|
||||
"l": monitorListHandler,
|
||||
"s": monitorStatusHandler,
|
||||
}
|
||||
)
|
||||
|
||||
func monitorHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
handler, exists := metadataSubcommands[strings.ToLower(msg.Params[0])]
|
||||
|
||||
if !exists {
|
||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "MONITOR", msg.Params[0], "Unknown subcommand")
|
||||
return false
|
||||
}
|
||||
|
||||
return handler(server, client, msg)
|
||||
}
|
||||
|
||||
func monitorRemoveHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
if len(msg.Params) < 2 {
|
||||
client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, msg.Command, "Not enough parameters")
|
||||
return false
|
||||
}
|
||||
|
||||
targets := strings.Split(msg.Params[1], ",")
|
||||
for len(targets) > 0 {
|
||||
// check name length
|
||||
if len(targets[0]) < 1 {
|
||||
targets = targets[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
// remove target
|
||||
casefoldedTarget, err := CasefoldName(targets[0])
|
||||
if err != nil {
|
||||
// skip silently I guess
|
||||
targets = targets[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
if client.monitoring[casefoldedTarget] {
|
||||
// just removes current client from the list
|
||||
orig := server.monitoring[casefoldedTarget]
|
||||
var index int
|
||||
for i, cli := range orig {
|
||||
if &cli == client {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
server.monitoring[casefoldedTarget] = append(orig[:index], orig[index+1:]...)
|
||||
|
||||
delete(client.monitoring, casefoldedTarget)
|
||||
}
|
||||
|
||||
// remove first element of targets list
|
||||
targets = targets[1:]
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func monitorAddHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
if len(msg.Params) < 2 {
|
||||
client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, msg.Command, "Not enough parameters")
|
||||
return false
|
||||
}
|
||||
|
||||
var online []string
|
||||
var offline []string
|
||||
|
||||
targets := strings.Split(msg.Params[1], ",")
|
||||
for len(targets) > 0 {
|
||||
// check name length
|
||||
if len(targets[0]) < 1 {
|
||||
targets = targets[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
// check the monitor list length
|
||||
if len(client.monitoring) >= server.limits.MonitorEntries {
|
||||
client.Send(nil, server.name, ERR_MONLISTFULL, client.nick, strconv.Itoa(server.limits.MonitorEntries), strings.Join(targets, ","))
|
||||
break
|
||||
}
|
||||
|
||||
// add target
|
||||
casefoldedTarget, err := CasefoldName(targets[0])
|
||||
if err != nil {
|
||||
// skip silently I guess
|
||||
targets = targets[1:]
|
||||
continue
|
||||
}
|
||||
|
||||
if !client.monitoring[casefoldedTarget] {
|
||||
client.monitoring[casefoldedTarget] = true
|
||||
|
||||
orig := server.monitoring[casefoldedTarget]
|
||||
server.monitoring[casefoldedTarget] = append(orig, *client)
|
||||
}
|
||||
|
||||
// add to online / offline lists
|
||||
target := server.clients.Get(casefoldedTarget)
|
||||
if target == nil {
|
||||
offline = append(offline, targets[0])
|
||||
} else {
|
||||
online = append(online, target.nickMaskString)
|
||||
}
|
||||
|
||||
// remove first element of targets list
|
||||
targets = targets[1:]
|
||||
}
|
||||
|
||||
if len(online) > 0 {
|
||||
client.Send(nil, server.name, RPL_MONONLINE, client.nick, strings.Join(online, ","))
|
||||
}
|
||||
if len(offline) > 0 {
|
||||
client.Send(nil, server.name, RPL_MONOFFLINE, client.nick, strings.Join(offline, ","))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func monitorClearHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
client.clearMonitorList()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func monitorListHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
var monitorList []string
|
||||
for name := range client.monitoring {
|
||||
monitorList = append(monitorList, name)
|
||||
}
|
||||
|
||||
client.Send(nil, server.name, RPL_MONLIST, client.nick, strings.Join(monitorList, ","))
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func monitorStatusHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
var online []string
|
||||
var offline []string
|
||||
|
||||
for name := range client.monitoring {
|
||||
target := server.clients.Get(name)
|
||||
if target == nil {
|
||||
offline = append(offline, name)
|
||||
} else {
|
||||
online = append(online, target.nickMaskString)
|
||||
}
|
||||
}
|
||||
|
||||
if len(online) > 0 {
|
||||
client.Send(nil, server.name, RPL_MONONLINE, client.nick, strings.Join(online, ","))
|
||||
}
|
||||
if len(offline) > 0 {
|
||||
client.Send(nil, server.name, RPL_MONOFFLINE, client.nick, strings.Join(offline, ","))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue