mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
Mostly style stuff.
This commit is contained in:
parent
39f815df01
commit
65af2b4320
@ -89,14 +89,18 @@ func (channel *Channel) GetTopic(replier Replier) {
|
||||
replier.Replies() <- RplTopic(channel)
|
||||
}
|
||||
|
||||
func (channel *Channel) Id() string {
|
||||
func (channel Channel) Id() string {
|
||||
return channel.name
|
||||
}
|
||||
|
||||
func (channel *Channel) PublicId() string {
|
||||
func (channel Channel) PublicId() string {
|
||||
return channel.name
|
||||
}
|
||||
|
||||
func (channel Channel) Commands() chan<- ChannelCommand {
|
||||
return channel.commands
|
||||
}
|
||||
|
||||
//
|
||||
// commands
|
||||
//
|
||||
|
@ -7,11 +7,6 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Replier interface {
|
||||
Identifier
|
||||
Replies() chan<- Reply
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
conn net.Conn
|
||||
username string
|
||||
@ -53,7 +48,7 @@ func (c *Client) readConn(recv <-chan string) {
|
||||
|
||||
m, err := ParseCommand(str)
|
||||
if err != nil {
|
||||
c.replies <- ErrNeedMoreParams(c.server, str)
|
||||
c.Replies() <- ErrNeedMoreParams(c.server, str)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -70,15 +65,15 @@ func (c *Client) writeConn(write chan<- string, replies <-chan Reply) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Replies() chan<- Reply {
|
||||
func (c Client) Replies() chan<- Reply {
|
||||
return c.replies
|
||||
}
|
||||
|
||||
func (c *Client) Server() *Server {
|
||||
func (c Client) Server() *Server {
|
||||
return c.server
|
||||
}
|
||||
|
||||
func (c *Client) Nick() string {
|
||||
func (c Client) Nick() string {
|
||||
if c.user != nil {
|
||||
return c.user.nick
|
||||
}
|
||||
@ -90,33 +85,33 @@ func (c *Client) Nick() string {
|
||||
return "*"
|
||||
}
|
||||
|
||||
func (c *Client) UModeString() string {
|
||||
func (c Client) UModeString() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Client) HasNick() bool {
|
||||
func (c Client) HasNick() bool {
|
||||
return c.nick != ""
|
||||
}
|
||||
|
||||
func (c *Client) HasUser() bool {
|
||||
func (c Client) HasUser() bool {
|
||||
return c.username != ""
|
||||
}
|
||||
|
||||
func (c *Client) Username() string {
|
||||
func (c Client) Username() string {
|
||||
if c.HasUser() {
|
||||
return c.username
|
||||
}
|
||||
return "*"
|
||||
}
|
||||
|
||||
func (c *Client) UserHost() string {
|
||||
func (c Client) UserHost() string {
|
||||
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Username(), c.hostname)
|
||||
}
|
||||
|
||||
func (c *Client) Id() string {
|
||||
func (c Client) Id() string {
|
||||
return c.UserHost()
|
||||
}
|
||||
|
||||
func (c *Client) PublicId() string {
|
||||
func (c Client) PublicId() string {
|
||||
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Nick(), c.server.Id())
|
||||
}
|
||||
|
@ -6,8 +6,32 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Command interface {
|
||||
Client() *Client
|
||||
HandleServer(*Server)
|
||||
}
|
||||
|
||||
type EditableCommand interface {
|
||||
Command
|
||||
SetClient(*Client)
|
||||
}
|
||||
|
||||
var (
|
||||
NotEnoughArgsError = errors.New("not enough arguments")
|
||||
ErrParseCommand = errors.New("failed to parse message")
|
||||
parseCommandFuncs = map[string]func([]string) (EditableCommand, error){
|
||||
"JOIN": NewJoinCommand,
|
||||
"MODE": NewModeCommand,
|
||||
"NICK": NewNickCommand,
|
||||
"PART": NewPartCommand,
|
||||
"PASS": NewPassCommand,
|
||||
"PING": NewPingCommand,
|
||||
"PONG": NewPongCommand,
|
||||
"PRIVMSG": NewPrivMsgCommand,
|
||||
"QUIT": NewQuitCommand,
|
||||
"TOPIC": NewTopicCommand,
|
||||
"USER": NewUserMsgCommand,
|
||||
}
|
||||
)
|
||||
|
||||
type BaseCommand struct {
|
||||
@ -25,28 +49,6 @@ func (base *BaseCommand) SetClient(c *Client) {
|
||||
base.client = c
|
||||
}
|
||||
|
||||
type EditableCommand interface {
|
||||
Command
|
||||
SetClient(*Client)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrParseCommand = errors.New("failed to parse message")
|
||||
parseCommandFuncs = map[string]func([]string) (EditableCommand, error){
|
||||
"JOIN": NewJoinCommand,
|
||||
"MODE": NewModeCommand,
|
||||
"NICK": NewNickCommand,
|
||||
"PART": NewPartCommand,
|
||||
"PASS": NewPassCommand,
|
||||
"PING": NewPingCommand,
|
||||
"PONG": NewPongCommand,
|
||||
"PRIVMSG": NewPrivMsgCommand,
|
||||
"QUIT": NewQuitCommand,
|
||||
"TOPIC": NewTopicCommand,
|
||||
"USER": NewUserMsgCommand,
|
||||
}
|
||||
)
|
||||
|
||||
func ParseCommand(line string) (EditableCommand, error) {
|
||||
command, args := parseLine(line)
|
||||
constructor := parseCommandFuncs[command]
|
||||
|
@ -12,6 +12,11 @@ type Identifier interface {
|
||||
Nick() string
|
||||
}
|
||||
|
||||
type Replier interface {
|
||||
Identifier
|
||||
Replies() chan<- Reply
|
||||
}
|
||||
|
||||
type Reply interface {
|
||||
String(client *Client) string
|
||||
Source() Identifier
|
||||
@ -30,24 +35,24 @@ func NewBasicReply(source Identifier, code string,
|
||||
return &BasicReply{source, code, fullMessage}
|
||||
}
|
||||
|
||||
func (reply *BasicReply) String(client *Client) string {
|
||||
func (reply BasicReply) String(client *Client) string {
|
||||
return reply.message
|
||||
}
|
||||
|
||||
func (reply *BasicReply) Source() Identifier {
|
||||
func (reply BasicReply) Source() Identifier {
|
||||
return reply.source
|
||||
}
|
||||
|
||||
type NumericReply struct {
|
||||
*BasicReply
|
||||
BasicReply
|
||||
}
|
||||
|
||||
func NewNumericReply(source Identifier, code string,
|
||||
format string, args ...interface{}) *NumericReply {
|
||||
return &NumericReply{&BasicReply{source, code, fmt.Sprintf(format, args...)}}
|
||||
return &NumericReply{BasicReply{source, code, fmt.Sprintf(format, args...)}}
|
||||
}
|
||||
|
||||
func (reply *NumericReply) String(client *Client) string {
|
||||
func (reply NumericReply) String(client *Client) string {
|
||||
return fmt.Sprintf(":%s %s %s %s\r\n", reply.source.Id(), reply.code, client.Nick(),
|
||||
reply.message)
|
||||
}
|
||||
|
@ -12,11 +12,6 @@ type ChannelNameMap map[string]*Channel
|
||||
type UserNameMap map[string]*User
|
||||
type ServiceNameMap map[string]*Service
|
||||
|
||||
type Command interface {
|
||||
Client() *Client
|
||||
HandleServer(*Server)
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
hostname string
|
||||
ctime time.Time
|
||||
@ -83,7 +78,7 @@ func (s *Server) GetOrMakeChannel(name string) *Channel {
|
||||
}
|
||||
|
||||
// Send a message to clients of channels fromClient is a member.
|
||||
func (s *Server) InterestedUsers(fromUser *User) UserSet {
|
||||
func (s Server) InterestedUsers(fromUser *User) UserSet {
|
||||
users := make(UserSet)
|
||||
users.Add(fromUser)
|
||||
for channel := range fromUser.channels {
|
||||
@ -102,20 +97,20 @@ func (s *Server) tryRegister(c *Client) {
|
||||
c.registered = true
|
||||
replies := []Reply{RplWelcome(s, c), RplYourHost(s, c), RplCreated(s), RplMyInfo(s)}
|
||||
for _, reply := range replies {
|
||||
c.replies <- reply
|
||||
c.Replies() <- reply
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Id() string {
|
||||
func (s Server) Id() string {
|
||||
return s.hostname
|
||||
}
|
||||
|
||||
func (s *Server) PublicId() string {
|
||||
func (s Server) PublicId() string {
|
||||
return s.Id()
|
||||
}
|
||||
|
||||
func (s *Server) Nick() string {
|
||||
func (s Server) Nick() string {
|
||||
return s.name
|
||||
}
|
||||
|
||||
@ -128,11 +123,11 @@ func (s *Server) DeleteChannel(channel *Channel) {
|
||||
//
|
||||
|
||||
func (m *UnknownCommand) HandleServer(s *Server) {
|
||||
m.Client().replies <- ErrUnknownCommand(s, m.command)
|
||||
m.Client().Replies() <- ErrUnknownCommand(s, m.command)
|
||||
}
|
||||
|
||||
func (m *PingCommand) HandleServer(s *Server) {
|
||||
m.Client().replies <- RplPong(s)
|
||||
m.Client().Replies() <- RplPong(s)
|
||||
}
|
||||
|
||||
func (m *PongCommand) HandleServer(s *Server) {
|
||||
@ -142,7 +137,7 @@ func (m *PongCommand) HandleServer(s *Server) {
|
||||
func (m *PassCommand) HandleServer(s *Server) {
|
||||
err := bcrypt.CompareHashAndPassword(s.password, []byte(m.password))
|
||||
if err != nil {
|
||||
m.Client().replies <- ErrPasswdMismatch(s)
|
||||
m.Client().Replies() <- ErrPasswdMismatch(s)
|
||||
return
|
||||
}
|
||||
|
||||
@ -153,19 +148,19 @@ func (m *PassCommand) HandleServer(s *Server) {
|
||||
func (m *NickCommand) HandleServer(s *Server) {
|
||||
c := m.Client()
|
||||
if c.user == nil {
|
||||
c.replies <- RplNick(c, m.nickname)
|
||||
c.Replies() <- RplNick(c, m.nickname)
|
||||
c.nick = m.nickname
|
||||
s.tryRegister(c)
|
||||
return
|
||||
}
|
||||
|
||||
c.user.replies <- ErrNoPrivileges(s)
|
||||
c.user.Replies() <- ErrNoPrivileges(s)
|
||||
}
|
||||
|
||||
func (m *UserMsgCommand) HandleServer(s *Server) {
|
||||
c := m.Client()
|
||||
if c.username != "" {
|
||||
c.replies <- ErrAlreadyRegistered(s)
|
||||
c.Replies() <- ErrAlreadyRegistered(s)
|
||||
return
|
||||
}
|
||||
|
||||
@ -180,7 +175,7 @@ func (m *QuitCommand) HandleServer(s *Server) {
|
||||
if user != nil {
|
||||
reply := RplQuit(c, m.message)
|
||||
for user := range s.InterestedUsers(c.user) {
|
||||
user.replies <- reply
|
||||
user.Replies() <- reply
|
||||
}
|
||||
}
|
||||
c.conn.Close()
|
||||
@ -194,7 +189,7 @@ func (m *QuitCommand) HandleServer(s *Server) {
|
||||
BaseCommand: BaseCommand{c},
|
||||
}
|
||||
for channel := range user.channels {
|
||||
channel.commands <- cmd
|
||||
channel.Commands() <- cmd
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,7 +199,7 @@ func (m *JoinCommand) HandleServer(s *Server) {
|
||||
|
||||
if c.user == nil {
|
||||
for name := range m.channels {
|
||||
c.replies <- ErrNoSuchChannel(s, name)
|
||||
c.Replies() <- ErrNoSuchChannel(s, name)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -214,13 +209,13 @@ func (m *JoinCommand) HandleServer(s *Server) {
|
||||
BaseCommand: BaseCommand{c},
|
||||
}
|
||||
for channel := range c.user.channels {
|
||||
channel.commands <- cmd
|
||||
channel.Commands() <- cmd
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for name := range m.channels {
|
||||
s.GetOrMakeChannel(name).commands <- m
|
||||
s.GetOrMakeChannel(name).Commands() <- m
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,7 +224,7 @@ func (m *PartCommand) HandleServer(s *Server) {
|
||||
|
||||
if user == nil {
|
||||
for _, chname := range m.channels {
|
||||
m.Client().replies <- ErrNoSuchChannel(s, chname)
|
||||
m.Client().Replies() <- ErrNoSuchChannel(s, chname)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -238,11 +233,11 @@ func (m *PartCommand) HandleServer(s *Server) {
|
||||
channel := s.channels[chname]
|
||||
|
||||
if channel == nil {
|
||||
user.replies <- ErrNoSuchChannel(s, channel.name)
|
||||
user.Replies() <- ErrNoSuchChannel(s, channel.name)
|
||||
continue
|
||||
}
|
||||
|
||||
channel.commands <- m
|
||||
channel.Commands() <- m
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,52 +245,52 @@ func (m *TopicCommand) HandleServer(s *Server) {
|
||||
user := m.Client().user
|
||||
|
||||
if user == nil {
|
||||
m.Client().replies <- ErrNoSuchChannel(s, m.channel)
|
||||
m.Client().Replies() <- ErrNoSuchChannel(s, m.channel)
|
||||
return
|
||||
}
|
||||
|
||||
channel := s.channels[m.channel]
|
||||
if channel == nil {
|
||||
user.replies <- ErrNoSuchChannel(s, m.channel)
|
||||
user.Replies() <- ErrNoSuchChannel(s, m.channel)
|
||||
return
|
||||
}
|
||||
|
||||
channel.commands <- m
|
||||
channel.Commands() <- m
|
||||
}
|
||||
|
||||
func (m *PrivMsgCommand) HandleServer(s *Server) {
|
||||
service := s.services[m.target]
|
||||
if service != nil {
|
||||
service.commands <- m
|
||||
service.Commands() <- m
|
||||
return
|
||||
}
|
||||
|
||||
user := m.Client().user
|
||||
if user == nil {
|
||||
m.Client().replies <- ErrNoSuchNick(s, m.target)
|
||||
m.Client().Replies() <- ErrNoSuchNick(s, m.target)
|
||||
return
|
||||
}
|
||||
|
||||
if m.TargetIsChannel() {
|
||||
channel := s.channels[m.target]
|
||||
if channel == nil {
|
||||
user.replies <- ErrNoSuchChannel(s, m.target)
|
||||
user.Replies() <- ErrNoSuchChannel(s, m.target)
|
||||
return
|
||||
}
|
||||
|
||||
channel.commands <- m
|
||||
channel.Commands() <- m
|
||||
return
|
||||
}
|
||||
|
||||
target := s.users[m.target]
|
||||
if target == nil {
|
||||
user.replies <- ErrNoSuchNick(s, m.target)
|
||||
user.Replies() <- ErrNoSuchNick(s, m.target)
|
||||
return
|
||||
}
|
||||
|
||||
target.commands <- m
|
||||
target.Commands() <- m
|
||||
}
|
||||
|
||||
func (m *ModeCommand) HandleServer(s *Server) {
|
||||
m.Client().replies <- RplUModeIs(s, m.Client())
|
||||
m.Client().Replies() <- RplUModeIs(s, m.Client())
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ func NewService(s *Server, name string) *Service {
|
||||
return service
|
||||
}
|
||||
|
||||
func (service *Service) HandleMsg(m *PrivMsgCommand) {
|
||||
}
|
||||
func (service *Service) HandleMsg(m *PrivMsgCommand) {}
|
||||
|
||||
func (service *Service) receiveCommands(commands <-chan ServiceCommand) {
|
||||
for command := range commands {
|
||||
@ -38,20 +37,24 @@ func (service *Service) receiveCommands(commands <-chan ServiceCommand) {
|
||||
}
|
||||
}
|
||||
|
||||
func (service *Service) Id() string {
|
||||
func (service Service) Id() string {
|
||||
return fmt.Sprintf("%s!%s@%s", service.name, service.name, service.server.name)
|
||||
}
|
||||
|
||||
func (service *Service) PublicId() string {
|
||||
func (service Service) PublicId() string {
|
||||
return service.Id()
|
||||
}
|
||||
|
||||
func (service *Service) Nick() string {
|
||||
func (service Service) Nick() string {
|
||||
return service.name
|
||||
}
|
||||
|
||||
func (service *Service) Reply(client *Client, message string) {
|
||||
client.replies <- RplPrivMsg(service, client, message)
|
||||
client.Replies() <- RplPrivMsg(service, client, message)
|
||||
}
|
||||
|
||||
func (service Service) Commands() chan<- ServiceCommand {
|
||||
return service.commands
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -32,25 +32,29 @@ func (set UserSet) Remove(user *User) {
|
||||
}
|
||||
|
||||
func NewUser(nick string, password string, server *Server) *User {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
panic("bcrypt failed; cannot generate password hash")
|
||||
}
|
||||
commands := make(chan UserCommand)
|
||||
replies := make(chan Reply)
|
||||
user := &User{
|
||||
nick: nick,
|
||||
hash: hash,
|
||||
server: server,
|
||||
clients: make(ClientSet),
|
||||
channels: make(ChannelSet),
|
||||
replies: replies,
|
||||
}
|
||||
user.SetPassword(password)
|
||||
go user.receiveCommands(commands)
|
||||
go user.receiveReplies(replies)
|
||||
return user
|
||||
}
|
||||
|
||||
func (user *User) SetPassword(password string) {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
panic("bcrypt failed; cannot generate password hash")
|
||||
}
|
||||
user.hash = hash
|
||||
}
|
||||
|
||||
func (user *User) receiveCommands(commands <-chan UserCommand) {
|
||||
for command := range commands {
|
||||
log.Printf("%s %T %+v", user.Id(), command, command)
|
||||
@ -63,25 +67,29 @@ func (user *User) receiveReplies(replies <-chan Reply) {
|
||||
for reply := range replies {
|
||||
log.Printf("%s %T %+v", user.Id(), reply, reply)
|
||||
for client := range user.clients {
|
||||
client.replies <- reply
|
||||
client.Replies() <- reply
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Identifier
|
||||
|
||||
func (user *User) Id() string {
|
||||
func (user User) Id() string {
|
||||
return fmt.Sprintf("%s!%s@%s", user.nick, user.nick, user.server.Id())
|
||||
}
|
||||
|
||||
func (user *User) PublicId() string {
|
||||
func (user User) PublicId() string {
|
||||
return user.Id()
|
||||
}
|
||||
|
||||
func (user *User) Nick() string {
|
||||
func (user User) Nick() string {
|
||||
return user.nick
|
||||
}
|
||||
|
||||
func (user User) Commands() chan<- UserCommand {
|
||||
return user.commands
|
||||
}
|
||||
|
||||
func (user *User) Login(c *Client, nick string, password string) bool {
|
||||
if nick != c.nick {
|
||||
return false
|
||||
@ -93,7 +101,7 @@ func (user *User) Login(c *Client, nick string, password string) bool {
|
||||
|
||||
err := bcrypt.CompareHashAndPassword(user.hash, []byte(password))
|
||||
if err != nil {
|
||||
c.replies <- ErrNoPrivileges(user.server)
|
||||
c.Replies() <- ErrNoPrivileges(user.server)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -101,8 +109,8 @@ func (user *User) Login(c *Client, nick string, password string) bool {
|
||||
c.user = user
|
||||
for channel := range user.channels {
|
||||
channel.GetTopic(c)
|
||||
c.replies <- RplNamReply(channel)
|
||||
c.replies <- RplEndOfNames(channel.server)
|
||||
c.Replies() <- RplNamReply(channel)
|
||||
c.Replies() <- RplEndOfNames(channel.server)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -115,11 +123,11 @@ func (user *User) LogoutClient(c *Client) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (user *User) HasClients() bool {
|
||||
func (user User) HasClients() bool {
|
||||
return len(user.clients) > 0
|
||||
}
|
||||
|
||||
func (user *User) Replies() chan<- Reply {
|
||||
func (user User) Replies() chan<- Reply {
|
||||
return user.replies
|
||||
}
|
||||
|
||||
@ -128,5 +136,5 @@ func (user *User) Replies() chan<- Reply {
|
||||
//
|
||||
|
||||
func (m *PrivMsgCommand) HandleUser(user *User) {
|
||||
user.replies <- RplPrivMsg(m.Client(), user, m.message)
|
||||
user.Replies() <- RplPrivMsg(m.Client(), user, m.message)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user