mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-10 22:19:31 +01:00
Make NickServ actually work.
This commit is contained in:
parent
65af2b4320
commit
2ff93d74be
@ -44,11 +44,15 @@ func NewClient(server *Server, conn net.Conn) *Client {
|
|||||||
|
|
||||||
func (c *Client) readConn(recv <-chan string) {
|
func (c *Client) readConn(recv <-chan string) {
|
||||||
for str := range recv {
|
for str := range recv {
|
||||||
log.Printf("%s > %s", c.Id(), str)
|
log.Printf("%s → %s", c.conn.RemoteAddr(), str)
|
||||||
|
|
||||||
m, err := ParseCommand(str)
|
m, err := ParseCommand(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == NotEnoughArgsError {
|
||||||
c.Replies() <- ErrNeedMoreParams(c.server, str)
|
c.Replies() <- ErrNeedMoreParams(c.server, str)
|
||||||
|
} else {
|
||||||
|
c.Replies() <- ErrUnknownCommand(c.server, str)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +64,7 @@ func (c *Client) readConn(recv <-chan string) {
|
|||||||
func (c *Client) writeConn(write chan<- string, replies <-chan Reply) {
|
func (c *Client) writeConn(write chan<- string, replies <-chan Reply) {
|
||||||
for reply := range replies {
|
for reply := range replies {
|
||||||
replyStr := reply.String(c)
|
replyStr := reply.String(c)
|
||||||
log.Printf("%s < %s", c.Id(), replyStr)
|
log.Printf("%s ← %s", c.conn.RemoteAddr(), replyStr)
|
||||||
write <- replyStr
|
write <- replyStr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,6 +116,10 @@ func (c Client) Id() string {
|
|||||||
return c.UserHost()
|
return c.UserHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Client) String() string {
|
||||||
|
return c.Id()
|
||||||
|
}
|
||||||
|
|
||||||
func (c Client) PublicId() string {
|
func (c Client) PublicId() string {
|
||||||
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Nick(), c.server.Id())
|
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Nick(), c.server.Id())
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package irc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -38,15 +39,15 @@ type BaseCommand struct {
|
|||||||
client *Client
|
client *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base BaseCommand) Client() *Client {
|
func (command BaseCommand) Client() *Client {
|
||||||
return base.client
|
return command.client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (base *BaseCommand) SetClient(c *Client) {
|
func (command *BaseCommand) SetClient(c *Client) {
|
||||||
if base.client != nil {
|
if command.client != nil {
|
||||||
panic("SetClient called twice!")
|
panic("SetClient called twice!")
|
||||||
}
|
}
|
||||||
base.client = c
|
command.client = c
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseCommand(line string) (EditableCommand, error) {
|
func ParseCommand(line string) (EditableCommand, error) {
|
||||||
@ -108,6 +109,10 @@ type PingCommand struct {
|
|||||||
server2 string
|
server2 string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd PingCommand) String() string {
|
||||||
|
return fmt.Sprintf("PING(server=%s, server2=%s)", cmd.server, cmd.server2)
|
||||||
|
}
|
||||||
|
|
||||||
func NewPingCommand(args []string) (EditableCommand, error) {
|
func NewPingCommand(args []string) (EditableCommand, error) {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -130,6 +135,10 @@ type PongCommand struct {
|
|||||||
server2 string
|
server2 string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd PongCommand) String() string {
|
||||||
|
return fmt.Sprintf("PONG(server1=%s, server2=%s)", cmd.server1, cmd.server2)
|
||||||
|
}
|
||||||
|
|
||||||
func NewPongCommand(args []string) (EditableCommand, error) {
|
func NewPongCommand(args []string) (EditableCommand, error) {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -168,6 +177,10 @@ type NickCommand struct {
|
|||||||
nickname string
|
nickname string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m NickCommand) String() string {
|
||||||
|
return fmt.Sprintf("NICK(nickname=%s)", m.nickname)
|
||||||
|
}
|
||||||
|
|
||||||
func NewNickCommand(args []string) (EditableCommand, error) {
|
func NewNickCommand(args []string) (EditableCommand, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -188,6 +201,11 @@ type UserMsgCommand struct {
|
|||||||
realname string
|
realname string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd UserMsgCommand) String() string {
|
||||||
|
return fmt.Sprintf("USER(user=%s, mode=%o, unused=%s, realname=%s)",
|
||||||
|
cmd.user, cmd.mode, cmd.unused, cmd.realname)
|
||||||
|
}
|
||||||
|
|
||||||
func NewUserMsgCommand(args []string) (EditableCommand, error) {
|
func NewUserMsgCommand(args []string) (EditableCommand, error) {
|
||||||
if len(args) != 4 {
|
if len(args) != 4 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -212,6 +230,10 @@ type QuitCommand struct {
|
|||||||
message string
|
message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd QuitCommand) String() string {
|
||||||
|
return fmt.Sprintf("QUIT(message=%s)", cmd.message)
|
||||||
|
}
|
||||||
|
|
||||||
func NewQuitCommand(args []string) (EditableCommand, error) {
|
func NewQuitCommand(args []string) (EditableCommand, error) {
|
||||||
msg := &QuitCommand{
|
msg := &QuitCommand{
|
||||||
BaseCommand: BaseCommand{},
|
BaseCommand: BaseCommand{},
|
||||||
@ -289,6 +311,10 @@ type PrivMsgCommand struct {
|
|||||||
message string
|
message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd PrivMsgCommand) String() string {
|
||||||
|
return fmt.Sprintf("PRIVMSG(target=%s, message=%s)", cmd.target, cmd.message)
|
||||||
|
}
|
||||||
|
|
||||||
func NewPrivMsgCommand(args []string) (EditableCommand, error) {
|
func NewPrivMsgCommand(args []string) (EditableCommand, error) {
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -336,6 +362,10 @@ type ModeCommand struct {
|
|||||||
modes string
|
modes string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd ModeCommand) String() string {
|
||||||
|
return fmt.Sprintf("MODE(nickname=%s, modes=%s)", cmd.nickname, cmd.modes)
|
||||||
|
}
|
||||||
|
|
||||||
func NewModeCommand(args []string) (EditableCommand, error) {
|
func NewModeCommand(args []string) (EditableCommand, error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package irc
|
package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -11,13 +12,15 @@ type NickServCommand interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NickServ struct {
|
type NickServ struct {
|
||||||
*Service
|
BaseService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNickServ(s *Server) *NickServ {
|
func NewNickServ(s *Server) Service {
|
||||||
return &NickServ{
|
return NewService(new(NickServ), s, "NickServ")
|
||||||
Service: NewService(s, "NickServ"),
|
}
|
||||||
}
|
|
||||||
|
func (ns *NickServ) SetBase(base *BaseService) {
|
||||||
|
ns.BaseService = *base
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -31,7 +34,7 @@ var (
|
|||||||
// commands
|
// commands
|
||||||
//
|
//
|
||||||
|
|
||||||
func (ns *NickServ) HandleMsg(m *PrivMsgCommand) {
|
func (ns *NickServ) HandlePrivMsg(m *PrivMsgCommand) {
|
||||||
command, args := parseLine(m.message)
|
command, args := parseLine(m.message)
|
||||||
constructor := parseNickServCommandFuncs[command]
|
constructor := parseNickServCommandFuncs[command]
|
||||||
if constructor == nil {
|
if constructor == nil {
|
||||||
@ -46,7 +49,7 @@ func (ns *NickServ) HandleMsg(m *PrivMsgCommand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd.SetClient(m.Client())
|
cmd.SetClient(m.Client())
|
||||||
log.Printf("%s %T %+v", ns.Id(), cmd, cmd)
|
log.Printf("%s ← %s", ns, cmd)
|
||||||
|
|
||||||
cmd.HandleNickServ(ns)
|
cmd.HandleNickServ(ns)
|
||||||
}
|
}
|
||||||
@ -61,6 +64,10 @@ type RegisterCommand struct {
|
|||||||
email string
|
email string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m RegisterCommand) String() string {
|
||||||
|
return fmt.Sprintf("REGISTER(email=%s, password=%s)", m.email, m.password)
|
||||||
|
}
|
||||||
|
|
||||||
func NewRegisterCommand(args []string) (NickServCommand, error) {
|
func NewRegisterCommand(args []string) (NickServCommand, error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -104,6 +111,10 @@ type IdentifyCommand struct {
|
|||||||
password string
|
password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m IdentifyCommand) String() string {
|
||||||
|
return fmt.Sprintf("IDENTIFY(password=%s)", m.password)
|
||||||
|
}
|
||||||
|
|
||||||
func NewIdentifyCommand(args []string) (NickServCommand, error) {
|
func NewIdentifyCommand(args []string) (NickServCommand, error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
|
@ -100,7 +100,7 @@ func RplWelcome(source Identifier, client *Client) Reply {
|
|||||||
|
|
||||||
func RplYourHost(server *Server, target *Client) Reply {
|
func RplYourHost(server *Server, target *Client) Reply {
|
||||||
return NewNumericReply(server, RPL_YOURHOST,
|
return NewNumericReply(server, RPL_YOURHOST,
|
||||||
"Your host is %s, running version %s", server.hostname, VERSION)
|
"Your host is %s, running version %s", server.name, VERSION)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplCreated(server *Server) Reply {
|
func RplCreated(server *Server) Reply {
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
type ClientNameMap map[string]*Client
|
type ClientNameMap map[string]*Client
|
||||||
type ChannelNameMap map[string]*Channel
|
type ChannelNameMap map[string]*Channel
|
||||||
type UserNameMap map[string]*User
|
type UserNameMap map[string]*User
|
||||||
type ServiceNameMap map[string]*Service
|
type ServiceNameMap map[string]Service
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
hostname string
|
hostname string
|
||||||
@ -40,7 +40,7 @@ func NewServer(name string) *Server {
|
|||||||
|
|
||||||
func (server *Server) receiveCommands(commands <-chan Command) {
|
func (server *Server) receiveCommands(commands <-chan Command) {
|
||||||
for command := range commands {
|
for command := range commands {
|
||||||
log.Printf("%s %T %+v", server.Id(), command, command)
|
log.Printf("%s ← %s %s", server, command.Client(), command)
|
||||||
command.Client().atime = time.Now()
|
command.Client().atime = time.Now()
|
||||||
command.HandleServer(server)
|
command.HandleServer(server)
|
||||||
}
|
}
|
||||||
@ -103,7 +103,11 @@ func (s *Server) tryRegister(c *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s Server) Id() string {
|
func (s Server) Id() string {
|
||||||
return s.hostname
|
return s.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Server) String() string {
|
||||||
|
return s.Id()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Server) PublicId() string {
|
func (s Server) PublicId() string {
|
||||||
@ -122,7 +126,7 @@ func (s *Server) DeleteChannel(channel *Channel) {
|
|||||||
// commands
|
// commands
|
||||||
//
|
//
|
||||||
|
|
||||||
func (m *UnknownCommand) HandleServer(s *Server) {
|
func (m UnknownCommand) HandleServer(s *Server) {
|
||||||
m.Client().Replies() <- ErrUnknownCommand(s, m.command)
|
m.Client().Replies() <- ErrUnknownCommand(s, m.command)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,60 +7,70 @@ import (
|
|||||||
|
|
||||||
type ServiceCommand interface {
|
type ServiceCommand interface {
|
||||||
Command
|
Command
|
||||||
HandleService(*Service)
|
HandleService(Service)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service struct {
|
type Service interface {
|
||||||
|
Identifier
|
||||||
|
Commands() chan<- ServiceCommand
|
||||||
|
HandlePrivMsg(*PrivMsgCommand)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EditableService interface {
|
||||||
|
Service
|
||||||
|
SetBase(*BaseService)
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseService struct {
|
||||||
server *Server
|
server *Server
|
||||||
name string
|
name string
|
||||||
commands chan<- ServiceCommand
|
commands chan<- ServiceCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(s *Server, name string) *Service {
|
func NewService(service EditableService, s *Server, name string) Service {
|
||||||
commands := make(chan ServiceCommand)
|
commands := make(chan ServiceCommand)
|
||||||
service := &Service{
|
base := &BaseService{
|
||||||
server: s,
|
server: s,
|
||||||
name: name,
|
name: name,
|
||||||
commands: commands,
|
commands: commands,
|
||||||
}
|
}
|
||||||
go service.receiveCommands(commands)
|
go receiveCommands(service, commands)
|
||||||
|
service.SetBase(base)
|
||||||
s.services[name] = service
|
s.services[name] = service
|
||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *Service) HandleMsg(m *PrivMsgCommand) {}
|
func receiveCommands(service Service, commands <-chan ServiceCommand) {
|
||||||
|
|
||||||
func (service *Service) receiveCommands(commands <-chan ServiceCommand) {
|
|
||||||
for command := range commands {
|
for command := range commands {
|
||||||
log.Printf("%s %T %+V", service.Id(), command, command)
|
log.Printf("%s ← %s %s", service.Id(), command.Client(), command)
|
||||||
command.HandleService(service)
|
command.HandleService(service)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service Service) Id() string {
|
func (service BaseService) Id() string {
|
||||||
return fmt.Sprintf("%s!%s@%s", service.name, service.name, service.server.name)
|
return fmt.Sprintf("%s!%s@%s", service.name, service.name, service.server.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service Service) PublicId() string {
|
func (service BaseService) String() string {
|
||||||
return service.Id()
|
return service.Id()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service Service) Nick() string {
|
func (service BaseService) PublicId() string {
|
||||||
|
return service.Id()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service BaseService) Nick() string {
|
||||||
return service.name
|
return service.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *Service) Reply(client *Client, message string) {
|
func (service *BaseService) Reply(client *Client, message string) {
|
||||||
client.Replies() <- RplPrivMsg(service, client, message)
|
client.Replies() <- RplPrivMsg(service, client, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service Service) Commands() chan<- ServiceCommand {
|
func (service BaseService) Commands() chan<- ServiceCommand {
|
||||||
return service.commands
|
return service.commands
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
func (m *PrivMsgCommand) HandleService(service Service) {
|
||||||
// commands
|
service.HandlePrivMsg(m)
|
||||||
//
|
|
||||||
|
|
||||||
func (m *PrivMsgCommand) HandleService(s *Service) {
|
|
||||||
s.HandleMsg(m)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user