diff --git a/irc/channel.go b/irc/channel.go index 604e87f4..beb76648 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -241,3 +241,12 @@ func (msg *ChannelModeCommand) HandleChannel(channel *Channel) { client.Reply(RplChannelModeIs(channel)) } + +func (m *NoticeCommand) HandleChannel(channel *Channel) { + client := m.Client() + if channel.noOutside && !channel.members.Has(client) { + client.Reply(ErrCannotSendToChan(channel)) + return + } + channel.Reply(RplNotice(client, channel, m.message)) +} diff --git a/irc/commands.go b/irc/commands.go index 2716eac9..bb34f39e 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -25,6 +25,7 @@ var ( "MODE": NewModeCommand, "MOTD": NewMOTDCommand, "NICK": NewNickCommand, + "NOTICE": NewNoticeCommand, "OPER": NewOperCommand, "PART": NewPartCommand, "PASS": NewPassCommand, @@ -665,3 +666,23 @@ func NewMOTDCommand(args []string) (editableCommand, error) { } return cmd, nil } + +type NoticeCommand struct { + BaseCommand + target string + message string +} + +func (cmd *NoticeCommand) String() string { + return fmt.Sprintf("NOTICE(target=%s, message=%s)", cmd.target, cmd.message) +} + +func NewNoticeCommand(args []string) (editableCommand, error) { + if len(args) < 2 { + return nil, NotEnoughArgsError + } + return &NoticeCommand{ + target: args[0], + message: args[1], + }, nil +} diff --git a/irc/constants.go b/irc/constants.go index 2155a7cf..13385b1e 100644 --- a/irc/constants.go +++ b/irc/constants.go @@ -167,6 +167,7 @@ const ( RPL_INVITE = "INVITE" RPL_JOIN = "JOIN" RPL_NICK = "NICK" + RPL_NOTICE = "NOTICE" RPL_PART = "PART" RPL_PING = "PING" RPL_PONG = "PONG" diff --git a/irc/reply.go b/irc/reply.go index 3d5992bb..82d23900 100644 --- a/irc/reply.go +++ b/irc/reply.go @@ -128,6 +128,10 @@ func RplPrivMsg(source Identifier, target Identifier, message string) Reply { return NewStringReply(source, RPL_PRIVMSG, "%s :%s", target.Nick(), message) } +func RplNotice(source Identifier, target Identifier, message string) Reply { + return NewStringReply(source, RPL_NOTICE, "%s :%s", target.Nick(), message) +} + func RplNick(source Identifier, newNick string) Reply { return NewStringReply(source, RPL_NICK, newNick) } diff --git a/irc/server.go b/irc/server.go index c698387c..06c82320 100644 --- a/irc/server.go +++ b/irc/server.go @@ -475,3 +475,23 @@ func (msg *IsOnCommand) HandleServer(server *Server) { func (msg *MOTDCommand) HandleServer(server *Server) { server.MOTD(msg.Client()) } + +func (msg *NoticeCommand) HandleServer(server *Server) { + if IsChannel(msg.target) { + channel := server.channels[msg.target] + if channel == nil { + msg.Client().Reply(ErrNoSuchChannel(server, msg.target)) + return + } + + channel.commands <- msg + return + } + + target := server.clients[msg.target] + if target == nil { + msg.Client().Reply(ErrNoSuchNick(server, msg.target)) + return + } + target.Reply(RplPrivMsg(msg.Client(), target, msg.message)) +}