123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- // Copyright (c) 2016-2017 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.SendFromClient("", client, nil, 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 || len(targets[0]) > server.limits.NickLen {
- 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)
- }
-
- for _, line := range argsToStrings(maxLastArgLength, monitorList, ",") {
- client.Send(nil, server.name, RPL_MONLIST, client.nick, line)
- }
-
- 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 {
- for _, line := range argsToStrings(maxLastArgLength, online, ",") {
- client.Send(nil, server.name, RPL_MONONLINE, client.nick, line)
- }
- }
- if len(offline) > 0 {
- for _, line := range argsToStrings(maxLastArgLength, offline, ",") {
- client.Send(nil, server.name, RPL_MONOFFLINE, client.nick, line)
- }
- }
-
- return false
- }
|