123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- // Copyright (c) 2012-2014 Jeremy Latt
- // Copyright (c) 2014-2015 Edmund Huber
- // Copyright (c) 2016-2017 Daniel Oaks <daniel@danieloaks.net>
- // released under the MIT license
-
- package irc
-
- import (
- "github.com/goshuirc/irc-go/ircmsg"
- "github.com/oragono/oragono/irc/modes"
- )
-
- // Command represents a command accepted from a client.
- type Command struct {
- handler func(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool
- oper bool
- usablePreReg bool
- leaveClientIdle bool // if true, leaves the client active time alone
- minParams int
- capabs []string
- }
-
- // Run runs this command with the given client/message.
- func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
- if !client.registered && !cmd.usablePreReg {
- client.Send(nil, server.name, ERR_NOTREGISTERED, client.nick, client.t("You need to register before you can use that command"))
- return false
- }
- if cmd.oper && !client.HasMode(modes.Operator) {
- client.Send(nil, server.name, ERR_NOPRIVILEGES, client.nick, client.t("Permission Denied - You're not an IRC operator"))
- return false
- }
- if len(cmd.capabs) > 0 && !client.HasRoleCapabs(cmd.capabs...) {
- client.Send(nil, server.name, ERR_NOPRIVILEGES, client.nick, client.t("Permission Denied"))
- return false
- }
- if len(msg.Params) < cmd.minParams {
- client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, msg.Command, client.t("Not enough parameters"))
- return false
- }
-
- if client.registered {
- client.fakelag.Touch()
- }
-
- rb := NewResponseBuffer(client)
- rb.Label = GetLabel(msg)
- exiting := cmd.handler(server, client, msg, rb)
- rb.Send(true)
-
- // after each command, see if we can send registration to the client
- if !client.registered {
- server.tryRegister(client)
- }
-
- // most servers do this only for PING/PONG, but we'll do it for any command:
- if client.registered {
- client.idletimer.Touch()
- }
-
- if !cmd.leaveClientIdle {
- client.Active()
- }
-
- return exiting
- }
-
- // Commands holds all commands executable by a client connected to us.
- var Commands map[string]Command
-
- func init() {
- Commands = map[string]Command{
- "ACC": {
- handler: accHandler,
- minParams: 3,
- },
- "AMBIANCE": {
- handler: sceneHandler,
- minParams: 2,
- },
- "AUTHENTICATE": {
- handler: authenticateHandler,
- usablePreReg: true,
- minParams: 1,
- },
- "AWAY": {
- handler: awayHandler,
- minParams: 0,
- },
- "CAP": {
- handler: capHandler,
- usablePreReg: true,
- minParams: 1,
- },
- "CHATHISTORY": {
- handler: chathistoryHandler,
- minParams: 3,
- },
- "DEBUG": {
- handler: debugHandler,
- minParams: 1,
- oper: true,
- },
- "DLINE": {
- handler: dlineHandler,
- minParams: 1,
- oper: true,
- },
- "HELP": {
- handler: helpHandler,
- minParams: 0,
- },
- "HELPOP": {
- handler: helpHandler,
- minParams: 0,
- },
- "HISTORY": {
- handler: historyHandler,
- minParams: 1,
- },
- "INFO": {
- handler: infoHandler,
- },
- "INVITE": {
- handler: inviteHandler,
- minParams: 2,
- },
- "ISON": {
- handler: isonHandler,
- minParams: 1,
- leaveClientIdle: true,
- },
- "JOIN": {
- handler: joinHandler,
- minParams: 1,
- },
- "KICK": {
- handler: kickHandler,
- minParams: 2,
- },
- "KILL": {
- handler: killHandler,
- minParams: 1,
- oper: true,
- capabs: []string{"oper:local_kill"}, //TODO(dan): when we have S2S, this will be checked in the command handler itself
- },
- "KLINE": {
- handler: klineHandler,
- minParams: 1,
- oper: true,
- },
- "LANGUAGE": {
- handler: languageHandler,
- usablePreReg: true,
- minParams: 1,
- },
- "LIST": {
- handler: listHandler,
- minParams: 0,
- },
- "LUSERS": {
- handler: lusersHandler,
- minParams: 0,
- },
- "MODE": {
- handler: modeHandler,
- minParams: 1,
- },
- "MONITOR": {
- handler: monitorHandler,
- minParams: 1,
- },
- "MOTD": {
- handler: motdHandler,
- minParams: 0,
- },
- "NAMES": {
- handler: namesHandler,
- minParams: 0,
- },
- "NICK": {
- handler: nickHandler,
- usablePreReg: true,
- minParams: 1,
- },
- "NOTICE": {
- handler: noticeHandler,
- minParams: 2,
- },
- "NPC": {
- handler: npcHandler,
- minParams: 3,
- },
- "NPCA": {
- handler: npcaHandler,
- minParams: 3,
- },
- "OPER": {
- handler: operHandler,
- minParams: 2,
- },
- "PART": {
- handler: partHandler,
- minParams: 1,
- },
- "PASS": {
- handler: passHandler,
- usablePreReg: true,
- minParams: 1,
- },
- "PING": {
- handler: pingHandler,
- usablePreReg: true,
- minParams: 1,
- leaveClientIdle: true,
- },
- "PONG": {
- handler: pongHandler,
- usablePreReg: true,
- minParams: 1,
- leaveClientIdle: true,
- },
- "PRIVMSG": {
- handler: privmsgHandler,
- minParams: 2,
- },
- "RENAME": {
- handler: renameHandler,
- minParams: 2,
- },
- "RESUME": {
- handler: resumeHandler,
- usablePreReg: true,
- minParams: 1,
- },
- "SAJOIN": {
- handler: sajoinHandler,
- minParams: 1,
- capabs: []string{"sajoin"},
- },
- "SANICK": {
- handler: sanickHandler,
- minParams: 2,
- oper: true,
- },
- "SAMODE": {
- handler: modeHandler,
- minParams: 1,
- capabs: []string{"samode"},
- },
- "SCENE": {
- handler: sceneHandler,
- minParams: 2,
- },
- "SETNAME": {
- handler: setnameHandler,
- minParams: 1,
- },
- "TAGMSG": {
- handler: tagmsgHandler,
- minParams: 1,
- },
- "QUIT": {
- handler: quitHandler,
- usablePreReg: true,
- minParams: 0,
- },
- "REHASH": {
- handler: rehashHandler,
- minParams: 0,
- oper: true,
- capabs: []string{"oper:rehash"},
- },
- "TIME": {
- handler: timeHandler,
- minParams: 0,
- },
- "TOPIC": {
- handler: topicHandler,
- minParams: 1,
- },
- "UNDLINE": {
- handler: unDLineHandler,
- minParams: 1,
- oper: true,
- },
- "UNKLINE": {
- handler: unKLineHandler,
- minParams: 1,
- oper: true,
- },
- "USER": {
- handler: userHandler,
- usablePreReg: true,
- minParams: 4,
- },
- "USERHOST": {
- handler: userhostHandler,
- minParams: 1,
- },
- "VERSION": {
- handler: versionHandler,
- minParams: 0,
- },
- "WEBIRC": {
- handler: webircHandler,
- usablePreReg: true,
- minParams: 4,
- },
- "WHO": {
- handler: whoHandler,
- minParams: 1,
- },
- "WHOIS": {
- handler: whoisHandler,
- minParams: 1,
- },
- "WHOWAS": {
- handler: whowasHandler,
- minParams: 1,
- },
- }
-
- initializeServices()
- }
|