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:
parent
c42cd92f91
commit
fd814bf969
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user