mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-29 15:40:02 +01:00
commands: Simplify and unify minimum required number of args handling
This commit is contained in:
parent
1bafaa0488
commit
9acdeedec6
132
irc/commands.go
132
irc/commands.go
@ -58,6 +58,39 @@ var (
|
|||||||
WHOIS: ParseWhoisCommand,
|
WHOIS: ParseWhoisCommand,
|
||||||
WHOWAS: ParseWhoWasCommand,
|
WHOWAS: ParseWhoWasCommand,
|
||||||
}
|
}
|
||||||
|
commandMinimumArgs = map[StringCode]int{
|
||||||
|
AWAY: 0,
|
||||||
|
CAP: 1,
|
||||||
|
DEBUG: 1,
|
||||||
|
INVITE: 2,
|
||||||
|
ISON: 1,
|
||||||
|
JOIN: 1,
|
||||||
|
KICK: 2,
|
||||||
|
KILL: 2,
|
||||||
|
LIST: 0,
|
||||||
|
MODE: 1,
|
||||||
|
MOTD: 0,
|
||||||
|
NAMES: 0,
|
||||||
|
NICK: 1,
|
||||||
|
NOTICE: 2,
|
||||||
|
ONICK: 2,
|
||||||
|
OPER: 2,
|
||||||
|
PART: 1,
|
||||||
|
PASS: 1,
|
||||||
|
PING: 1,
|
||||||
|
PONG: 1,
|
||||||
|
PRIVMSG: 2,
|
||||||
|
PROXY: 5,
|
||||||
|
QUIT: 0,
|
||||||
|
THEATER: 1,
|
||||||
|
TIME: 0,
|
||||||
|
TOPIC: 1,
|
||||||
|
USER: 4,
|
||||||
|
VERSION: 0,
|
||||||
|
WHO: 0,
|
||||||
|
WHOIS: 1,
|
||||||
|
WHOWAS: 1,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseCommand struct {
|
type BaseCommand struct {
|
||||||
@ -81,13 +114,33 @@ func (command *BaseCommand) SetCode(code StringCode) {
|
|||||||
command.code = code
|
command.code = code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NeedMoreParamsCommand struct {
|
||||||
|
BaseCommand
|
||||||
|
code StringCode
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseNeedMoreParams(code StringCode) *NeedMoreParamsCommand {
|
||||||
|
return &NeedMoreParamsCommand{
|
||||||
|
code: code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ParseCommand(line string) (cmd Command, err error) {
|
func ParseCommand(line string) (cmd Command, err error) {
|
||||||
code, args := ParseLine(line)
|
code, args := ParseLine(line)
|
||||||
constructor := parseCommandFuncs[code]
|
constructor := parseCommandFuncs[code]
|
||||||
|
minArgs := commandMinimumArgs[code]
|
||||||
if constructor == nil {
|
if constructor == nil {
|
||||||
cmd = ParseUnknownCommand(args)
|
cmd = ParseUnknownCommand(args)
|
||||||
|
} else if len(args) < minArgs {
|
||||||
|
cmd = ParseNeedMoreParams(code)
|
||||||
} else {
|
} else {
|
||||||
cmd, err = constructor(args)
|
cmd, err = constructor(args)
|
||||||
|
|
||||||
|
// if NotEnoughArgsError was returned in the command handler itself
|
||||||
|
if err == NotEnoughArgsError {
|
||||||
|
cmd = ParseNeedMoreParams(code)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
cmd.SetCode(code)
|
cmd.SetCode(code)
|
||||||
@ -150,9 +203,6 @@ type PingCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParsePingCommand(args []string) (Command, error) {
|
func ParsePingCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
msg := &PingCommand{
|
msg := &PingCommand{
|
||||||
server: NewName(args[0]),
|
server: NewName(args[0]),
|
||||||
}
|
}
|
||||||
@ -171,9 +221,6 @@ type PongCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParsePongCommand(args []string) (Command, error) {
|
func ParsePongCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
message := &PongCommand{
|
message := &PongCommand{
|
||||||
server1: NewName(args[0]),
|
server1: NewName(args[0]),
|
||||||
}
|
}
|
||||||
@ -204,9 +251,6 @@ func (cmd *PassCommand) CheckPassword() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParsePassCommand(args []string) (Command, error) {
|
func ParsePassCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
return &PassCommand{
|
return &PassCommand{
|
||||||
password: []byte(args[0]),
|
password: []byte(args[0]),
|
||||||
}, nil
|
}, nil
|
||||||
@ -215,9 +259,6 @@ func ParsePassCommand(args []string) (Command, error) {
|
|||||||
// NICK <nickname>
|
// NICK <nickname>
|
||||||
|
|
||||||
func ParseNickCommand(args []string) (Command, error) {
|
func ParseNickCommand(args []string) (Command, error) {
|
||||||
if len(args) != 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
return &NickCommand{
|
return &NickCommand{
|
||||||
nickname: NewName(args[0]),
|
nickname: NewName(args[0]),
|
||||||
}, nil
|
}, nil
|
||||||
@ -255,9 +296,6 @@ func (cmd *RFC2812UserCommand) Flags() []UserMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseUserCommand(args []string) (Command, error) {
|
func ParseUserCommand(args []string) (Command, error) {
|
||||||
if len(args) != 4 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
mode, err := strconv.ParseUint(args[1], 10, 8)
|
mode, err := strconv.ParseUint(args[1], 10, 8)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
msg := &RFC2812UserCommand{
|
msg := &RFC2812UserCommand{
|
||||||
@ -314,10 +352,6 @@ func ParseJoinCommand(args []string) (Command, error) {
|
|||||||
channels: make(map[Name]Text),
|
channels: make(map[Name]Text),
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
if args[0] == "0" {
|
if args[0] == "0" {
|
||||||
msg.zero = true
|
msg.zero = true
|
||||||
return msg, nil
|
return msg, nil
|
||||||
@ -356,9 +390,6 @@ func (cmd *PartCommand) Message() Text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParsePartCommand(args []string) (Command, error) {
|
func ParsePartCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
msg := &PartCommand{
|
msg := &PartCommand{
|
||||||
channels: NewNames(strings.Split(args[0], ",")),
|
channels: NewNames(strings.Split(args[0], ",")),
|
||||||
}
|
}
|
||||||
@ -377,9 +408,6 @@ type PrivMsgCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParsePrivMsgCommand(args []string) (Command, error) {
|
func ParsePrivMsgCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
return &PrivMsgCommand{
|
return &PrivMsgCommand{
|
||||||
target: NewName(args[0]),
|
target: NewName(args[0]),
|
||||||
message: NewText(args[1]),
|
message: NewText(args[1]),
|
||||||
@ -396,9 +424,6 @@ type TopicCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseTopicCommand(args []string) (Command, error) {
|
func ParseTopicCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
msg := &TopicCommand{
|
msg := &TopicCommand{
|
||||||
channel: NewName(args[0]),
|
channel: NewName(args[0]),
|
||||||
}
|
}
|
||||||
@ -579,10 +604,6 @@ func ParseChannelModeCommand(channel Name, args []string) (Command, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseModeCommand(args []string) (Command, error) {
|
func ParseModeCommand(args []string) (Command, error) {
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
name := NewName(args[0])
|
name := NewName(args[0])
|
||||||
if name.IsChannel() {
|
if name.IsChannel() {
|
||||||
return ParseChannelModeCommand(name, args[1:])
|
return ParseChannelModeCommand(name, args[1:])
|
||||||
@ -599,10 +620,6 @@ type WhoisCommand struct {
|
|||||||
|
|
||||||
// WHOIS [ <target> ] <mask> *( "," <mask> )
|
// WHOIS [ <target> ] <mask> *( "," <mask> )
|
||||||
func ParseWhoisCommand(args []string) (Command, error) {
|
func ParseWhoisCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
var masks string
|
var masks string
|
||||||
var target string
|
var target string
|
||||||
|
|
||||||
@ -651,10 +668,6 @@ func (msg *OperCommand) LoadPassword(server *Server) {
|
|||||||
|
|
||||||
// OPER <name> <password>
|
// OPER <name> <password>
|
||||||
func ParseOperCommand(args []string) (Command, error) {
|
func ParseOperCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := &OperCommand{
|
cmd := &OperCommand{
|
||||||
name: NewName(args[0]),
|
name: NewName(args[0]),
|
||||||
}
|
}
|
||||||
@ -669,10 +682,6 @@ type CapCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseCapCommand(args []string) (Command, error) {
|
func ParseCapCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := &CapCommand{
|
cmd := &CapCommand{
|
||||||
subCommand: CapSubCommand(strings.ToUpper(args[0])),
|
subCommand: CapSubCommand(strings.ToUpper(args[0])),
|
||||||
capabilities: make(CapabilitySet),
|
capabilities: make(CapabilitySet),
|
||||||
@ -707,9 +716,6 @@ func NewProxyCommand(hostname Name) *ProxyCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseProxyCommand(args []string) (Command, error) {
|
func ParseProxyCommand(args []string) (Command, error) {
|
||||||
if len(args) < 5 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
return &ProxyCommand{
|
return &ProxyCommand{
|
||||||
net: NewName(args[0]),
|
net: NewName(args[0]),
|
||||||
sourceIP: NewName(args[1]),
|
sourceIP: NewName(args[1]),
|
||||||
@ -741,10 +747,6 @@ type IsOnCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseIsOnCommand(args []string) (Command, error) {
|
func ParseIsOnCommand(args []string) (Command, error) {
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
return &IsOnCommand{
|
return &IsOnCommand{
|
||||||
nicks: NewNames(args),
|
nicks: NewNames(args),
|
||||||
}, nil
|
}, nil
|
||||||
@ -770,9 +772,6 @@ type NoticeCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseNoticeCommand(args []string) (Command, error) {
|
func ParseNoticeCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
return &NoticeCommand{
|
return &NoticeCommand{
|
||||||
target: NewName(args[0]),
|
target: NewName(args[0]),
|
||||||
message: NewText(args[1]),
|
message: NewText(args[1]),
|
||||||
@ -793,9 +792,6 @@ func (msg *KickCommand) Comment() Text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseKickCommand(args []string) (Command, error) {
|
func ParseKickCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
channels := NewNames(strings.Split(args[0], ","))
|
channels := NewNames(strings.Split(args[0], ","))
|
||||||
users := NewNames(strings.Split(args[1], ","))
|
users := NewNames(strings.Split(args[1], ","))
|
||||||
if (len(channels) != len(users)) && (len(users) != 1) {
|
if (len(channels) != len(users)) && (len(users) != 1) {
|
||||||
@ -857,10 +853,6 @@ type DebugCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseDebugCommand(args []string) (Command, error) {
|
func ParseDebugCommand(args []string) (Command, error) {
|
||||||
if len(args) == 0 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
return &DebugCommand{
|
return &DebugCommand{
|
||||||
subCommand: NewName(strings.ToUpper(args[0])),
|
subCommand: NewName(strings.ToUpper(args[0])),
|
||||||
}, nil
|
}, nil
|
||||||
@ -886,10 +878,6 @@ type InviteCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseInviteCommand(args []string) (Command, error) {
|
func ParseInviteCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
return &InviteCommand{
|
return &InviteCommand{
|
||||||
nickname: NewName(args[0]),
|
nickname: NewName(args[0]),
|
||||||
channel: NewName(args[1]),
|
channel: NewName(args[1]),
|
||||||
@ -897,9 +885,7 @@ func ParseInviteCommand(args []string) (Command, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseTheaterCommand(args []string) (Command, error) {
|
func ParseTheaterCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
if upperSubCmd := strings.ToUpper(args[0]); upperSubCmd == "IDENTIFY" && len(args) == 3 {
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
} else if upperSubCmd := strings.ToUpper(args[0]); upperSubCmd == "IDENTIFY" && len(args) == 3 {
|
|
||||||
return &TheaterIdentifyCommand{
|
return &TheaterIdentifyCommand{
|
||||||
channel: NewName(args[1]),
|
channel: NewName(args[1]),
|
||||||
PassCommand: PassCommand{password: []byte(args[2])},
|
PassCommand: PassCommand{password: []byte(args[2])},
|
||||||
@ -941,9 +927,6 @@ type KillCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseKillCommand(args []string) (Command, error) {
|
func ParseKillCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
return &KillCommand{
|
return &KillCommand{
|
||||||
nickname: NewName(args[0]),
|
nickname: NewName(args[0]),
|
||||||
comment: NewText(args[1]),
|
comment: NewText(args[1]),
|
||||||
@ -958,9 +941,6 @@ type WhoWasCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseWhoWasCommand(args []string) (Command, error) {
|
func ParseWhoWasCommand(args []string) (Command, error) {
|
||||||
if len(args) < 1 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
cmd := &WhoWasCommand{
|
cmd := &WhoWasCommand{
|
||||||
nicknames: NewNames(strings.Split(args[0], ",")),
|
nicknames: NewNames(strings.Split(args[0], ",")),
|
||||||
}
|
}
|
||||||
@ -974,10 +954,6 @@ func ParseWhoWasCommand(args []string) (Command, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseOperNickCommand(args []string) (Command, error) {
|
func ParseOperNickCommand(args []string) (Command, error) {
|
||||||
if len(args) < 2 {
|
|
||||||
return nil, NotEnoughArgsError
|
|
||||||
}
|
|
||||||
|
|
||||||
return &OperNickCommand{
|
return &OperNickCommand{
|
||||||
target: NewName(args[0]),
|
target: NewName(args[0]),
|
||||||
nick: NewName(args[1]),
|
nick: NewName(args[1]),
|
||||||
|
@ -64,6 +64,14 @@ func NewServer(config *Config) *Server {
|
|||||||
theaters: config.Theaters(),
|
theaters: config.Theaters(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure that there is a minimum number of args specified for every command
|
||||||
|
for name, _ := range parseCommandFuncs {
|
||||||
|
_, exists := commandMinimumArgs[name]
|
||||||
|
if !exists {
|
||||||
|
log.Fatal("commandMinArgs not found for ", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if config.Server.MOTD != "" {
|
if config.Server.MOTD != "" {
|
||||||
file, err := os.Open(config.Server.MOTD)
|
file, err := os.Open(config.Server.MOTD)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -162,6 +170,12 @@ func (server *Server) loadChannels() {
|
|||||||
func (server *Server) processCommand(cmd Command) {
|
func (server *Server) processCommand(cmd Command) {
|
||||||
client := cmd.Client()
|
client := cmd.Client()
|
||||||
|
|
||||||
|
numCmd, ok := cmd.(*NeedMoreParamsCommand)
|
||||||
|
if ok {
|
||||||
|
client.ErrNeedMoreParams(numCmd.code)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !client.registered {
|
if !client.registered {
|
||||||
regCmd, ok := cmd.(RegServerCommand)
|
regCmd, ok := cmd.(RegServerCommand)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
Loading…
Reference in New Issue
Block a user