From 6a102e8587085ae522444590f8fc0b586d39c9f4 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 27 Aug 2013 13:40:51 +0100 Subject: [PATCH] Improved nick/channel case handling --- client.go | 44 +++++++++++++++++++++++++------------------- server.go | 14 +++++++------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/client.go b/client.go index ac76dd3..d045b3e 100644 --- a/client.go +++ b/client.go @@ -11,25 +11,27 @@ import ( func (c *Client) setNick(nick string) { if c.nick != "" { - delete(c.server.clientMap, c.nick) + oldNickKey := strings.ToLower(c.nick) + delete(c.server.clientMap, oldNickKey) for _, channel := range c.channelMap { - delete(channel.clientMap, c.nick) + delete(channel.clientMap, oldNickKey) } } //Set up new nick oldNick := c.nick c.nick = nick - c.server.clientMap[c.nick] = c + nickKey := strings.ToLower(c.nick) + c.server.clientMap[nickKey] = c clients := make([]string, 0, 100) for _, channel := range c.channelMap { - channel.clientMap[c.nick] = c + channel.clientMap[nickKey] = c //Collect list of client nicks who can see us - for client := range channel.clientMap { - clients = append(clients, client) + for _, client := range channel.clientMap { + clients = append(clients, client.nick) } } @@ -42,7 +44,7 @@ func (c *Client) setNick(nick string) { } prevNick = nick - client, exists := c.server.clientMap[nick] + client, exists := c.server.clientMap[strings.ToLower(nick)] if exists { client.reply(rplNickChange, oldNick, c.nick) } @@ -50,16 +52,17 @@ func (c *Client) setNick(nick string) { } func (c *Client) joinChannel(channelName string) { - channel, exists := c.server.channelMap[channelName] + channelKey := strings.ToLower(channelName) + channel, exists := c.server.channelMap[channelKey] if exists == false { channel = &Channel{name: channelName, topic: "", clientMap: make(map[string]*Client)} - c.server.channelMap[channelName] = channel + c.server.channelMap[channelKey] = channel } - channel.clientMap[c.nick] = c - c.channelMap[channelName] = channel + channel.clientMap[strings.ToLower(c.nick)] = c + c.channelMap[channelKey] = channel for _, client := range channel.clientMap { client.reply(rplJoin, c.nick, channelName) @@ -72,15 +75,16 @@ func (c *Client) joinChannel(channelName string) { } nicks := make([]string, 0, 100) - for nick := range channel.clientMap { - nicks = append(nicks, nick) + for _, client := range channel.clientMap { + nicks = append(nicks, client.nick) } c.reply(rplNames, channelName, strings.Join(nicks, " ")) } func (c *Client) partChannel(channelName string) { - channel, exists := c.server.channelMap[channelName] + channelKey := strings.ToLower(channelName) + channel, exists := c.server.channelMap[channelKey] if exists == false { return } @@ -90,8 +94,11 @@ func (c *Client) partChannel(channelName string) { client.reply(rplPart, c.nick, channelName) } - delete(channel.clientMap, c.nick) - delete(c.channelMap, channelName) + delete(channel.clientMap, strings.ToLower(c.nick)) + + if len(channel.clientMap) == 0 { + delete(c.channelMap, channelKey) + } } func (c *Client) disconnect() { @@ -171,7 +178,7 @@ func (c *Client) clientThread() { c.partChannel(channelName) } - delete(c.server.clientMap, c.nick) + delete(c.server.clientMap, strings.ToLower(c.nick)) c.connection.Close() }() @@ -237,8 +244,7 @@ func (c *Client) writeThread(signalChan chan signalCode, outputChan chan string) line := []byte(fmt.Sprintf("%s\r\n", output)) c.connection.SetWriteDeadline(time.Now().Add(time.Second * 30)) - _, err := c.connection.Write(line) - if err != nil { + if _, err := c.connection.Write(line); err != nil { c.disconnect() return } diff --git a/server.go b/server.go index 9f02b8a..8d7dbc1 100644 --- a/server.go +++ b/server.go @@ -11,7 +11,7 @@ import ( var ( nickRegexp = regexp.MustCompile(`^[a-zA-Z\[\]_^{|}][a-zA-Z0-9\[\]_^{|}]*$`) - channelRegexp = regexp.MustCompile(`^#[a-z0-9_\-]+$`) + channelRegexp = regexp.MustCompile(`^#[a-zA-Z0-9_\-]+$`) ) func NewServer() *Server { @@ -68,7 +68,7 @@ func (s *Server) handleEvent(e Event) { return } - if _, exists := s.clientMap[newNick]; exists { + if _, exists := s.clientMap[strings.ToLower(newNick)]; exists { e.client.reply(errNickInUse, newNick) return } @@ -149,8 +149,8 @@ func (s *Server) handleEvent(e Event) { message := strings.Join(args[1:], " ") - channel, chanExists := s.channelMap[args[0]] - client, clientExists := s.clientMap[args[0]] + channel, chanExists := s.channelMap[strings.ToLower(args[0])] + client, clientExists := s.clientMap[strings.ToLower(args[0])] if chanExists { for _, c := range channel.clientMap { @@ -183,7 +183,7 @@ func (s *Server) handleEvent(e Event) { return } - channel, exists := s.channelMap[args[0]] + channel, exists := s.channelMap[strings.ToLower(args[0])] if exists == false { e.client.reply(errNoSuchNick, args[0]) return @@ -232,7 +232,7 @@ func (s *Server) handleEvent(e Event) { chanList := make([]string, 0, len(channels)) for _, channelName := range channels { - if channel, exists := s.channelMap[channelName]; exists { + if channel, exists := s.channelMap[strings.ToLower(channelName)]; exists { listItem := fmt.Sprintf("%s %d :%s", channelName, len(channel.clientMap), channel.topic) chanList = append(chanList, listItem) } @@ -284,7 +284,7 @@ func (s *Server) handleEvent(e Event) { nick := args[0] - if client, exists := s.clientMap[nick]; exists { + if client, exists := s.clientMap[strings.ToLower(nick)]; exists { client.reply(rplKill, "An operator has disconnected you.") client.disconnect() } else {