3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-29 07:29:31 +01:00

Add nick changing support.

This commit is contained in:
Jeremy Latt 2013-05-12 11:20:55 -07:00
parent c42cd92f91
commit fd814bf969
6 changed files with 61 additions and 36 deletions

View File

@ -53,12 +53,12 @@ func NewChannel(s *Server, name string) *Channel {
} }
// Forward `Reply`s to all `User`s of the `Channel`. // Forward `Reply`s to all `User`s of the `Channel`.
func (ch *Channel) receiveReplies(replies <-chan Reply) { func (channel *Channel) receiveReplies(replies <-chan Reply) {
for reply := range replies { for reply := range replies {
if DEBUG_CHANNEL { if DEBUG_CHANNEL {
log.Printf("%s → %s", ch, reply) log.Printf("%s → %s", channel, reply)
} }
for user := range ch.members { for user := range channel.members {
if user != reply.Source() { if user != reply.Source() {
user.replies <- reply user.replies <- reply
} }
@ -66,27 +66,21 @@ func (ch *Channel) receiveReplies(replies <-chan Reply) {
} }
} }
func (ch *Channel) receiveCommands(commands <-chan ChannelCommand) { func (channel *Channel) receiveCommands(commands <-chan ChannelCommand) {
for command := range commands { for command := range commands {
if DEBUG_CHANNEL { if DEBUG_CHANNEL {
log.Printf("%s ← %s %s", ch, command.Source(), command) log.Printf("%s ← %s %s", channel, command.Source(), command)
} }
command.HandleChannel(ch) command.HandleChannel(channel)
} }
} }
func (ch *Channel) Nicks() []string { func (channel *Channel) Nicks() []string {
nicks := make([]string, len(ch.members)) return channel.members.Nicks()
i := 0
for member := range ch.members {
nicks[i] = member.Nick()
i++
}
return nicks
} }
func (ch *Channel) IsEmpty() bool { func (channel *Channel) IsEmpty() bool {
return len(ch.members) == 0 return len(channel.members) == 0
} }
func (channel *Channel) GetTopic(replier Replier) { func (channel *Channel) GetTopic(replier Replier) {
@ -158,7 +152,7 @@ func (m *PartCommand) HandleChannel(channel *Channel) {
channel.members.Remove(user) channel.members.Remove(user)
user.channels.Remove(channel) user.channels.Remove(channel)
if len(channel.members) == 0 { if channel.IsEmpty() {
channel.server.DeleteChannel(channel) channel.server.DeleteChannel(channel)
} }
} }

View File

@ -45,9 +45,6 @@ func (command *BaseCommand) Client() *Client {
} }
func (command *BaseCommand) SetClient(c *Client) { func (command *BaseCommand) SetClient(c *Client) {
if command.client != nil {
panic("SetClient called twice!")
}
command.client = c command.client = c
} }

View File

@ -27,7 +27,7 @@ func (ns *NickServ) SetBase(base *BaseService) {
ns.BaseService = *base ns.BaseService = *base
} }
func (ns NickServ) Debug() bool { func (ns *NickServ) Debug() bool {
return DEBUG_NICKSERV return DEBUG_NICKSERV
} }

View File

@ -13,7 +13,6 @@ type Identifier interface {
} }
type Replier interface { type Replier interface {
Identifier
Replies() chan<- Reply Replies() chan<- Reply
} }
@ -40,7 +39,10 @@ func NewStringReply(source Identifier, code string,
format string, args ...interface{}) *StringReply { format string, args ...interface{}) *StringReply {
message := fmt.Sprintf(format, args...) message := fmt.Sprintf(format, args...)
fullMessage := fmt.Sprintf(":%s %s %s", source.Id(), code, message) fullMessage := fmt.Sprintf(":%s %s %s", source.Id(), code, message)
return &StringReply{BaseReply{source, fullMessage}, code} return &StringReply{
BaseReply: BaseReply{source, fullMessage},
code: code,
}
} }
func (reply *StringReply) Format(client *Client) string { func (reply *StringReply) Format(client *Client) string {
@ -57,9 +59,12 @@ type NumericReply struct {
code int code int
} }
func NewNumericReply(source Identifier, code int, func NewNumericReply(source Identifier, code int, format string,
format string, args ...interface{}) *NumericReply { args ...interface{}) *NumericReply {
return &NumericReply{BaseReply{source, fmt.Sprintf(format, args...)}, code} return &NumericReply{
BaseReply: BaseReply{source, fmt.Sprintf(format, args...)},
code: code,
}
} }
func (reply *NumericReply) Format(client *Client) string { func (reply *NumericReply) Format(client *Client) string {
@ -78,8 +83,8 @@ func RplPrivMsg(source Identifier, target Identifier, message string) Reply {
return NewStringReply(source, RPL_PRIVMSG, "%s :%s", target.Nick(), message) return NewStringReply(source, RPL_PRIVMSG, "%s :%s", target.Nick(), message)
} }
func RplNick(client *Client, newNick string) Reply { func RplNick(source Identifier, newNick string) Reply {
return NewStringReply(client, RPL_NICK, newNick) return NewStringReply(source, RPL_NICK, newNick)
} }
func RplPrivMsgChannel(channel *Channel, source Identifier, message string) Reply { func RplPrivMsgChannel(channel *Channel, source Identifier, message string) Reply {
@ -129,8 +134,7 @@ func RplMyInfo(server *Server) Reply {
} }
func RplUModeIs(server *Server, client *Client) Reply { func RplUModeIs(server *Server, client *Client) Reply {
return NewNumericReply(server, RPL_UMODEIS, return NewNumericReply(server, RPL_UMODEIS, client.UModeString())
client.UModeString())
} }
func RplNoTopic(channel *Channel) Reply { func RplNoTopic(channel *Channel) Reply {

View File

@ -11,7 +11,6 @@ const (
DEBUG_SERVER = true DEBUG_SERVER = true
) )
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
@ -84,7 +83,7 @@ func (s *Server) GetOrMakeChannel(name string) *Channel {
} }
// Send a message to clients of channels fromClient is a member. // 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 := make(UserSet)
users.Add(fromUser) users.Add(fromUser)
for channel := range fromUser.channels { for channel := range fromUser.channels {
@ -99,16 +98,25 @@ func (s Server) InterestedUsers(fromUser *User) UserSet {
// server functionality // server functionality
func (s *Server) tryRegister(c *Client) { func (s *Server) tryRegister(c *Client) {
if !c.registered && c.HasNick() && c.HasUsername() && (s.password == nil || c.serverPass) { if !c.registered && c.HasNick() && c.HasUsername() && s.CheckPassword(c) {
c.registered = true c.registered = true
replies := []Reply{RplWelcome(s, c), RplYourHost(s, c), RplCreated(s), RplMyInfo(s)} replies := []Reply{
RplWelcome(s, c),
RplYourHost(s, c),
RplCreated(s),
RplMyInfo(s),
}
for _, reply := range replies { for _, reply := range replies {
c.Replies() <- reply c.Replies() <- reply
} }
} }
} }
func (s Server) Id() string { func (s *Server) CheckPassword(c *Client) bool {
return (s.password == nil) || c.serverPass
}
func (s *Server) Id() string {
return s.name return s.name
} }
@ -164,7 +172,19 @@ func (m *NickCommand) HandleServer(s *Server) {
return return
} }
c.user.Replies() <- ErrNoPrivileges(s) user := c.user
if s.users[m.nickname] != nil {
user.Replies() <- ErrNickNameInUse(s, m.nickname)
return
}
delete(s.users, user.nick)
s.users[m.nickname] = user
reply := RplNick(user, m.nickname)
for iuser := range s.InterestedUsers(user) {
iuser.Replies() <- reply
}
user.nick = m.nickname
} }
func (m *UserMsgCommand) HandleServer(s *Server) { func (m *UserMsgCommand) HandleServer(s *Server) {

View File

@ -35,6 +35,16 @@ func (set UserSet) Remove(user *User) {
delete(set, user) delete(set, user)
} }
func (set UserSet) Nicks() []string {
nicks := make([]string, len(set))
i := 0
for member := range set {
nicks[i] = member.Nick()
i++
}
return nicks
}
func NewUser(nick string, password string, server *Server) *User { func NewUser(nick string, password string, server *Server) *User {
commands := make(chan UserCommand) commands := make(chan UserCommand)
replies := make(chan Reply) replies := make(chan Reply)