mirror of
https://github.com/ergochat/ergo.git
synced 2025-12-20 10:10:08 -08:00
cleanup and reorganization
This commit is contained in:
parent
2dba5f4c47
commit
55f7c89468
8 changed files with 254 additions and 196 deletions
|
|
@ -1,15 +1,30 @@
|
|||
package irc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Message interface {
|
||||
Handle(s *Server, c *Client)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrNotEnoughArgs = errors.New("not enough arguments")
|
||||
ErrUModeUnknownFlag = errors.New("unknown umode flag")
|
||||
)
|
||||
|
||||
// unknown
|
||||
|
||||
type UnknownMessage struct {
|
||||
command string
|
||||
}
|
||||
|
||||
// NB: no constructor, created on demand in parser for invalid messages.
|
||||
|
||||
func (m *UnknownMessage) Handle(s *Server, c *Client) {
|
||||
c.send <- ErrUnknownCommand(s, m.command)
|
||||
}
|
||||
|
|
@ -21,6 +36,17 @@ type PingMessage struct {
|
|||
server2 string
|
||||
}
|
||||
|
||||
func NewPingMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
msg := &PingMessage{server: args[0]}
|
||||
if len(args) > 1 {
|
||||
msg.server2 = args[1]
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *PingMessage) Handle(s *Server, c *Client) {
|
||||
c.send <- RplPong(s)
|
||||
}
|
||||
|
|
@ -32,8 +58,19 @@ type PongMessage struct {
|
|||
server2 string
|
||||
}
|
||||
|
||||
func NewPongMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
message := &PongMessage{server1: args[0]}
|
||||
if len(args) > 1 {
|
||||
message.server2 = args[1]
|
||||
}
|
||||
return message, nil
|
||||
}
|
||||
|
||||
func (m *PongMessage) Handle(s *Server, c *Client) {
|
||||
// TODO update client atime
|
||||
// no-op
|
||||
}
|
||||
|
||||
// NICK
|
||||
|
|
@ -42,6 +79,13 @@ type NickMessage struct {
|
|||
nickname string
|
||||
}
|
||||
|
||||
func NewNickMessage(args []string) (Message, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
return &NickMessage{args[0]}, nil
|
||||
}
|
||||
|
||||
func (m *NickMessage) Handle(s *Server, c *Client) {
|
||||
s.ChangeNick(c, m.nickname)
|
||||
}
|
||||
|
|
@ -55,8 +99,24 @@ type UserMessage struct {
|
|||
realname string
|
||||
}
|
||||
|
||||
func NewUserMessage(args []string) (Message, error) {
|
||||
if len(args) != 4 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
msg := &UserMessage{
|
||||
user: args[0],
|
||||
unused: args[2],
|
||||
realname: args[3],
|
||||
}
|
||||
mode, err := strconv.ParseUint(args[1], 10, 8)
|
||||
if err == nil {
|
||||
msg.mode = uint8(mode)
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *UserMessage) Handle(s *Server, c *Client) {
|
||||
s.Register(c, m.user, m.realname)
|
||||
s.UserLogin(c, m.user, m.realname)
|
||||
}
|
||||
|
||||
// QUIT
|
||||
|
|
@ -65,6 +125,14 @@ type QuitMessage struct {
|
|||
message string
|
||||
}
|
||||
|
||||
func NewQuitMessage(args []string) (Message, error) {
|
||||
msg := &QuitMessage{}
|
||||
if len(args) > 0 {
|
||||
msg.message = args[0]
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *QuitMessage) Handle(s *Server, c *Client) {
|
||||
s.Quit(c, m.message)
|
||||
}
|
||||
|
|
@ -76,6 +144,28 @@ type ModeMessage struct {
|
|||
modes []string
|
||||
}
|
||||
|
||||
var MODE_RE = regexp.MustCompile("^[-+][a-zA-Z]+$")
|
||||
|
||||
func NewModeMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
msg := &ModeMessage{
|
||||
nickname: args[0],
|
||||
}
|
||||
for _, arg := range args[1:] {
|
||||
if !MODE_RE.MatchString(arg) {
|
||||
return nil, ErrUModeUnknownFlag
|
||||
}
|
||||
prefix := arg[0]
|
||||
for _, c := range arg[1:] {
|
||||
mode := fmt.Sprintf("%c%c", prefix, c)
|
||||
msg.modes = append(msg.modes, mode)
|
||||
}
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *ModeMessage) Handle(s *Server, c *Client) {
|
||||
if m.nickname != c.nick {
|
||||
c.send <- ErrUsersDontMatch(s)
|
||||
|
|
@ -92,6 +182,22 @@ type JoinMessage struct {
|
|||
zero bool
|
||||
}
|
||||
|
||||
func NewJoinMessage(args []string) (Message, error) {
|
||||
msg := &JoinMessage{}
|
||||
if len(args) > 0 {
|
||||
if args[0] == "0" {
|
||||
msg.zero = true
|
||||
} else {
|
||||
msg.channels = strings.Split(args[0], ",")
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
msg.keys = strings.Split(args[1], ",")
|
||||
}
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *JoinMessage) Handle(s *Server, c *Client) {
|
||||
if m.zero {
|
||||
for channel := range c.channels {
|
||||
|
|
@ -116,6 +222,17 @@ type PartMessage struct {
|
|||
message string
|
||||
}
|
||||
|
||||
func NewPartMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
msg := &PartMessage{channels: strings.Split(args[0], ",")}
|
||||
if len(args) > 1 {
|
||||
msg.message = args[1]
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *PartMessage) Handle(s *Server, c *Client) {
|
||||
for _, chname := range m.channels {
|
||||
channel := s.channels[chname]
|
||||
|
|
@ -136,6 +253,16 @@ type PrivMsgMessage struct {
|
|||
message string
|
||||
}
|
||||
|
||||
func NewPrivMsgMessage(args []string) (Message, error) {
|
||||
if len(args) < 2 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
return &PrivMsgMessage{
|
||||
target: args[0],
|
||||
message: args[1],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *PrivMsgMessage) TargetIsChannel() bool {
|
||||
switch m.target[0] {
|
||||
case '&', '#', '+', '!':
|
||||
|
|
@ -169,6 +296,17 @@ type TopicMessage struct {
|
|||
topic string
|
||||
}
|
||||
|
||||
func NewTopicMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
}
|
||||
msg := &TopicMessage{channel: args[0]}
|
||||
if len(args) > 1 {
|
||||
msg.topic = args[1]
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func (m *TopicMessage) Handle(s *Server, c *Client) {
|
||||
channel := s.channels[m.channel]
|
||||
if channel == nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue