mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 11:59:40 +01:00
Clean up BaseCommand interface. Make NickServ a Service.
This commit is contained in:
parent
4b0cfa816c
commit
39f815df01
@ -27,11 +27,6 @@ type Client struct {
|
||||
replies chan<- Reply
|
||||
}
|
||||
|
||||
type ClientMessage interface {
|
||||
Client() *Client
|
||||
SetClient(*Client)
|
||||
}
|
||||
|
||||
type ClientSet map[*Client]bool
|
||||
|
||||
func NewClient(server *Server, conn net.Conn) *Client {
|
||||
|
@ -14,17 +14,25 @@ type BaseCommand struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
func (base *BaseCommand) Client() *Client {
|
||||
func (base BaseCommand) Client() *Client {
|
||||
return base.client
|
||||
}
|
||||
|
||||
func (base *BaseCommand) SetClient(c *Client) {
|
||||
if base.client != nil {
|
||||
panic("SetClient called twice!")
|
||||
}
|
||||
base.client = c
|
||||
}
|
||||
|
||||
type EditableCommand interface {
|
||||
Command
|
||||
SetClient(*Client)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrParseCommand = errors.New("failed to parse message")
|
||||
parseCommandFuncs = map[string]func([]string) (Command, error){
|
||||
parseCommandFuncs = map[string]func([]string) (EditableCommand, error){
|
||||
"JOIN": NewJoinCommand,
|
||||
"MODE": NewModeCommand,
|
||||
"NICK": NewNickCommand,
|
||||
@ -39,7 +47,7 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func ParseCommand(line string) (Command, error) {
|
||||
func ParseCommand(line string) (EditableCommand, error) {
|
||||
command, args := parseLine(line)
|
||||
constructor := parseCommandFuncs[command]
|
||||
if constructor == nil {
|
||||
@ -77,14 +85,14 @@ func parseLine(line string) (command string, args []string) {
|
||||
// <command> [args...]
|
||||
|
||||
type UnknownCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
command string
|
||||
args []string
|
||||
}
|
||||
|
||||
func NewUnknownCommand(command string, args []string) *UnknownCommand {
|
||||
return &UnknownCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
command: command,
|
||||
args: args,
|
||||
}
|
||||
@ -93,17 +101,17 @@ func NewUnknownCommand(command string, args []string) *UnknownCommand {
|
||||
// PING <server1> [ <server2> ]
|
||||
|
||||
type PingCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
server string
|
||||
server2 string
|
||||
}
|
||||
|
||||
func NewPingCommand(args []string) (Command, error) {
|
||||
func NewPingCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &PingCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
server: args[0],
|
||||
}
|
||||
if len(args) > 1 {
|
||||
@ -115,17 +123,17 @@ func NewPingCommand(args []string) (Command, error) {
|
||||
// PONG <server> [ <server2> ]
|
||||
|
||||
type PongCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
server1 string
|
||||
server2 string
|
||||
}
|
||||
|
||||
func NewPongCommand(args []string) (Command, error) {
|
||||
func NewPongCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
message := &PongCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
server1: args[0],
|
||||
}
|
||||
if len(args) > 1 {
|
||||
@ -137,16 +145,16 @@ func NewPongCommand(args []string) (Command, error) {
|
||||
// PASS <password>
|
||||
|
||||
type PassCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
password string
|
||||
}
|
||||
|
||||
func NewPassCommand(args []string) (Command, error) {
|
||||
func NewPassCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &PassCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
password: args[0],
|
||||
}, nil
|
||||
}
|
||||
@ -154,16 +162,16 @@ func NewPassCommand(args []string) (Command, error) {
|
||||
// NICK <nickname>
|
||||
|
||||
type NickCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
nickname string
|
||||
}
|
||||
|
||||
func NewNickCommand(args []string) (Command, error) {
|
||||
func NewNickCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &NickCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
nickname: args[0],
|
||||
}, nil
|
||||
}
|
||||
@ -171,19 +179,19 @@ func NewNickCommand(args []string) (Command, error) {
|
||||
// USER <user> <mode> <unused> <realname>
|
||||
|
||||
type UserMsgCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
user string
|
||||
mode uint8
|
||||
unused string
|
||||
realname string
|
||||
}
|
||||
|
||||
func NewUserMsgCommand(args []string) (Command, error) {
|
||||
func NewUserMsgCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) != 4 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &UserMsgCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
user: args[0],
|
||||
unused: args[2],
|
||||
realname: args[3],
|
||||
@ -198,13 +206,13 @@ func NewUserMsgCommand(args []string) (Command, error) {
|
||||
// QUIT [ <Quit Command> ]
|
||||
|
||||
type QuitCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
message string
|
||||
}
|
||||
|
||||
func NewQuitCommand(args []string) (Command, error) {
|
||||
func NewQuitCommand(args []string) (EditableCommand, error) {
|
||||
msg := &QuitCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
}
|
||||
if len(args) > 0 {
|
||||
msg.message = args[0]
|
||||
@ -215,14 +223,14 @@ func NewQuitCommand(args []string) (Command, error) {
|
||||
// JOIN ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] ) / "0"
|
||||
|
||||
type JoinCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
channels map[string]string
|
||||
zero bool
|
||||
}
|
||||
|
||||
func NewJoinCommand(args []string) (Command, error) {
|
||||
func NewJoinCommand(args []string) (EditableCommand, error) {
|
||||
msg := &JoinCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
channels: make(map[string]string),
|
||||
}
|
||||
|
||||
@ -252,17 +260,17 @@ func NewJoinCommand(args []string) (Command, error) {
|
||||
// PART <channel> *( "," <channel> ) [ <Part Command> ]
|
||||
|
||||
type PartCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
channels []string
|
||||
message string
|
||||
}
|
||||
|
||||
func NewPartCommand(args []string) (Command, error) {
|
||||
func NewPartCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &PartCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
channels: strings.Split(args[0], ","),
|
||||
}
|
||||
if len(args) > 1 {
|
||||
@ -274,17 +282,17 @@ func NewPartCommand(args []string) (Command, error) {
|
||||
// PRIVMSG <target> <message>
|
||||
|
||||
type PrivMsgCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
target string
|
||||
message string
|
||||
}
|
||||
|
||||
func NewPrivMsgCommand(args []string) (Command, error) {
|
||||
func NewPrivMsgCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) < 2 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &PrivMsgCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
target: args[0],
|
||||
message: args[1],
|
||||
}, nil
|
||||
@ -301,17 +309,17 @@ func (m *PrivMsgCommand) TargetIsChannel() bool {
|
||||
// TOPIC [newtopic]
|
||||
|
||||
type TopicCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
channel string
|
||||
topic string
|
||||
}
|
||||
|
||||
func NewTopicCommand(args []string) (Command, error) {
|
||||
func NewTopicCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &TopicCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
channel: args[0],
|
||||
}
|
||||
if len(args) > 1 {
|
||||
@ -321,18 +329,18 @@ func NewTopicCommand(args []string) (Command, error) {
|
||||
}
|
||||
|
||||
type ModeCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
nickname string
|
||||
modes string
|
||||
}
|
||||
|
||||
func NewModeCommand(args []string) (Command, error) {
|
||||
func NewModeCommand(args []string) (EditableCommand, error) {
|
||||
if len(args) == 0 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
|
||||
cmd := &ModeCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
nickname: args[0],
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,9 @@ import (
|
||||
)
|
||||
|
||||
type NickServCommand interface {
|
||||
ClientMessage
|
||||
HandleNickServ(*NickServ)
|
||||
Client() *Client
|
||||
SetClient(*Client)
|
||||
}
|
||||
|
||||
type NickServ struct {
|
||||
@ -14,11 +15,9 @@ type NickServ struct {
|
||||
}
|
||||
|
||||
func NewNickServ(s *Server) *NickServ {
|
||||
ns := &NickServ{}
|
||||
ns.Service = NewService(s, "NickServ", func(m *PrivMsgCommand) {
|
||||
m.HandleNickServ(ns)
|
||||
})
|
||||
return ns
|
||||
return &NickServ{
|
||||
Service: NewService(s, "NickServ"),
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
@ -32,7 +31,7 @@ var (
|
||||
// commands
|
||||
//
|
||||
|
||||
func (m *PrivMsgCommand) HandleNickServ(ns *NickServ) {
|
||||
func (ns *NickServ) HandleMsg(m *PrivMsgCommand) {
|
||||
command, args := parseLine(m.message)
|
||||
constructor := parseNickServCommandFuncs[command]
|
||||
if constructor == nil {
|
||||
@ -48,6 +47,7 @@ func (m *PrivMsgCommand) HandleNickServ(ns *NickServ) {
|
||||
|
||||
cmd.SetClient(m.Client())
|
||||
log.Printf("%s %T %+v", ns.Id(), cmd, cmd)
|
||||
|
||||
cmd.HandleNickServ(ns)
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ func (m *PrivMsgCommand) HandleNickServ(ns *NickServ) {
|
||||
//
|
||||
|
||||
type RegisterCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
password string
|
||||
email string
|
||||
}
|
||||
@ -67,7 +67,7 @@ func NewRegisterCommand(args []string) (NickServCommand, error) {
|
||||
}
|
||||
|
||||
cmd := &RegisterCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
password: args[0],
|
||||
}
|
||||
if len(args) > 1 {
|
||||
@ -100,7 +100,7 @@ func (m *RegisterCommand) HandleNickServ(ns *NickServ) {
|
||||
}
|
||||
|
||||
type IdentifyCommand struct {
|
||||
*BaseCommand
|
||||
BaseCommand
|
||||
password string
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ func NewIdentifyCommand(args []string) (NickServCommand, error) {
|
||||
}
|
||||
|
||||
return &IdentifyCommand{
|
||||
BaseCommand: &BaseCommand{},
|
||||
BaseCommand: BaseCommand{},
|
||||
password: args[0],
|
||||
}, nil
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ type UserNameMap map[string]*User
|
||||
type ServiceNameMap map[string]*Service
|
||||
|
||||
type Command interface {
|
||||
ClientMessage
|
||||
Handle(*Server)
|
||||
Client() *Client
|
||||
HandleServer(*Server)
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
@ -47,7 +47,7 @@ func (server *Server) receiveCommands(commands <-chan Command) {
|
||||
for command := range commands {
|
||||
log.Printf("%s %T %+v", server.Id(), command, command)
|
||||
command.Client().atime = time.Now()
|
||||
command.Handle(server)
|
||||
command.HandleServer(server)
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,19 +127,19 @@ func (s *Server) DeleteChannel(channel *Channel) {
|
||||
// commands
|
||||
//
|
||||
|
||||
func (m *UnknownCommand) Handle(s *Server) {
|
||||
func (m *UnknownCommand) HandleServer(s *Server) {
|
||||
m.Client().replies <- ErrUnknownCommand(s, m.command)
|
||||
}
|
||||
|
||||
func (m *PingCommand) Handle(s *Server) {
|
||||
func (m *PingCommand) HandleServer(s *Server) {
|
||||
m.Client().replies <- RplPong(s)
|
||||
}
|
||||
|
||||
func (m *PongCommand) Handle(s *Server) {
|
||||
func (m *PongCommand) HandleServer(s *Server) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
func (m *PassCommand) Handle(s *Server) {
|
||||
func (m *PassCommand) HandleServer(s *Server) {
|
||||
err := bcrypt.CompareHashAndPassword(s.password, []byte(m.password))
|
||||
if err != nil {
|
||||
m.Client().replies <- ErrPasswdMismatch(s)
|
||||
@ -150,7 +150,7 @@ func (m *PassCommand) Handle(s *Server) {
|
||||
// no reply?
|
||||
}
|
||||
|
||||
func (m *NickCommand) Handle(s *Server) {
|
||||
func (m *NickCommand) HandleServer(s *Server) {
|
||||
c := m.Client()
|
||||
if c.user == nil {
|
||||
c.replies <- RplNick(c, m.nickname)
|
||||
@ -162,7 +162,7 @@ func (m *NickCommand) Handle(s *Server) {
|
||||
c.user.replies <- ErrNoPrivileges(s)
|
||||
}
|
||||
|
||||
func (m *UserMsgCommand) Handle(s *Server) {
|
||||
func (m *UserMsgCommand) HandleServer(s *Server) {
|
||||
c := m.Client()
|
||||
if c.username != "" {
|
||||
c.replies <- ErrAlreadyRegistered(s)
|
||||
@ -173,7 +173,7 @@ func (m *UserMsgCommand) Handle(s *Server) {
|
||||
s.tryRegister(c)
|
||||
}
|
||||
|
||||
func (m *QuitCommand) Handle(s *Server) {
|
||||
func (m *QuitCommand) HandleServer(s *Server) {
|
||||
c := m.Client()
|
||||
|
||||
user := c.user
|
||||
@ -191,7 +191,7 @@ func (m *QuitCommand) Handle(s *Server) {
|
||||
user.LogoutClient(c)
|
||||
if !user.HasClients() {
|
||||
cmd := &PartCommand{
|
||||
BaseCommand: &BaseCommand{c},
|
||||
BaseCommand: BaseCommand{c},
|
||||
}
|
||||
for channel := range user.channels {
|
||||
channel.commands <- cmd
|
||||
@ -199,7 +199,7 @@ func (m *QuitCommand) Handle(s *Server) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *JoinCommand) Handle(s *Server) {
|
||||
func (m *JoinCommand) HandleServer(s *Server) {
|
||||
c := m.Client()
|
||||
|
||||
if c.user == nil {
|
||||
@ -211,7 +211,7 @@ func (m *JoinCommand) Handle(s *Server) {
|
||||
|
||||
if m.zero {
|
||||
cmd := &PartCommand{
|
||||
BaseCommand: &BaseCommand{c},
|
||||
BaseCommand: BaseCommand{c},
|
||||
}
|
||||
for channel := range c.user.channels {
|
||||
channel.commands <- cmd
|
||||
@ -224,7 +224,7 @@ func (m *JoinCommand) Handle(s *Server) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *PartCommand) Handle(s *Server) {
|
||||
func (m *PartCommand) HandleServer(s *Server) {
|
||||
user := m.Client().user
|
||||
|
||||
if user == nil {
|
||||
@ -246,7 +246,7 @@ func (m *PartCommand) Handle(s *Server) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *TopicCommand) Handle(s *Server) {
|
||||
func (m *TopicCommand) HandleServer(s *Server) {
|
||||
user := m.Client().user
|
||||
|
||||
if user == nil {
|
||||
@ -263,7 +263,7 @@ func (m *TopicCommand) Handle(s *Server) {
|
||||
channel.commands <- m
|
||||
}
|
||||
|
||||
func (m *PrivMsgCommand) Handle(s *Server) {
|
||||
func (m *PrivMsgCommand) HandleServer(s *Server) {
|
||||
service := s.services[m.target]
|
||||
if service != nil {
|
||||
service.commands <- m
|
||||
@ -296,6 +296,6 @@ func (m *PrivMsgCommand) Handle(s *Server) {
|
||||
target.commands <- m
|
||||
}
|
||||
|
||||
func (m *ModeCommand) Handle(s *Server) {
|
||||
func (m *ModeCommand) HandleServer(s *Server) {
|
||||
m.Client().replies <- RplUModeIs(s, m.Client())
|
||||
}
|
||||
|
@ -10,28 +10,27 @@ type ServiceCommand interface {
|
||||
HandleService(*Service)
|
||||
}
|
||||
|
||||
type PrivMsgCommandFunc func(*PrivMsgCommand)
|
||||
|
||||
type Service struct {
|
||||
server *Server
|
||||
name string
|
||||
commands chan<- ServiceCommand
|
||||
Handle PrivMsgCommandFunc
|
||||
}
|
||||
|
||||
func NewService(s *Server, name string, Handle PrivMsgCommandFunc) *Service {
|
||||
func NewService(s *Server, name string) *Service {
|
||||
commands := make(chan ServiceCommand)
|
||||
service := &Service{
|
||||
server: s,
|
||||
name: name,
|
||||
commands: commands,
|
||||
Handle: Handle,
|
||||
}
|
||||
go service.receiveCommands(commands)
|
||||
s.services[name] = service
|
||||
return service
|
||||
}
|
||||
|
||||
func (service *Service) HandleMsg(m *PrivMsgCommand) {
|
||||
}
|
||||
|
||||
func (service *Service) receiveCommands(commands <-chan ServiceCommand) {
|
||||
for command := range commands {
|
||||
log.Printf("%s %T %+V", service.Id(), command, command)
|
||||
@ -60,5 +59,5 @@ func (service *Service) Reply(client *Client, message string) {
|
||||
//
|
||||
|
||||
func (m *PrivMsgCommand) HandleService(s *Service) {
|
||||
s.Handle(m)
|
||||
s.HandleMsg(m)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user