Improved nick/channel case handling

This commit is contained in:
Harry Jeffery 2013-08-27 13:40:51 +01:00
parent 399c18cdf6
commit 6a102e8587
2 changed files with 32 additions and 26 deletions

View File

@ -11,25 +11,27 @@ import (
func (c *Client) setNick(nick string) { func (c *Client) setNick(nick string) {
if c.nick != "" { if c.nick != "" {
delete(c.server.clientMap, c.nick) oldNickKey := strings.ToLower(c.nick)
delete(c.server.clientMap, oldNickKey)
for _, channel := range c.channelMap { for _, channel := range c.channelMap {
delete(channel.clientMap, c.nick) delete(channel.clientMap, oldNickKey)
} }
} }
//Set up new nick //Set up new nick
oldNick := c.nick oldNick := c.nick
c.nick = 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) clients := make([]string, 0, 100)
for _, channel := range c.channelMap { for _, channel := range c.channelMap {
channel.clientMap[c.nick] = c channel.clientMap[nickKey] = c
//Collect list of client nicks who can see us //Collect list of client nicks who can see us
for client := range channel.clientMap { for _, client := range channel.clientMap {
clients = append(clients, client) clients = append(clients, client.nick)
} }
} }
@ -42,7 +44,7 @@ func (c *Client) setNick(nick string) {
} }
prevNick = nick prevNick = nick
client, exists := c.server.clientMap[nick] client, exists := c.server.clientMap[strings.ToLower(nick)]
if exists { if exists {
client.reply(rplNickChange, oldNick, c.nick) client.reply(rplNickChange, oldNick, c.nick)
} }
@ -50,16 +52,17 @@ func (c *Client) setNick(nick string) {
} }
func (c *Client) joinChannel(channelName 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 { if exists == false {
channel = &Channel{name: channelName, channel = &Channel{name: channelName,
topic: "", topic: "",
clientMap: make(map[string]*Client)} clientMap: make(map[string]*Client)}
c.server.channelMap[channelName] = channel c.server.channelMap[channelKey] = channel
} }
channel.clientMap[c.nick] = c channel.clientMap[strings.ToLower(c.nick)] = c
c.channelMap[channelName] = channel c.channelMap[channelKey] = channel
for _, client := range channel.clientMap { for _, client := range channel.clientMap {
client.reply(rplJoin, c.nick, channelName) client.reply(rplJoin, c.nick, channelName)
@ -72,15 +75,16 @@ func (c *Client) joinChannel(channelName string) {
} }
nicks := make([]string, 0, 100) nicks := make([]string, 0, 100)
for nick := range channel.clientMap { for _, client := range channel.clientMap {
nicks = append(nicks, nick) nicks = append(nicks, client.nick)
} }
c.reply(rplNames, channelName, strings.Join(nicks, " ")) c.reply(rplNames, channelName, strings.Join(nicks, " "))
} }
func (c *Client) partChannel(channelName string) { 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 { if exists == false {
return return
} }
@ -90,8 +94,11 @@ func (c *Client) partChannel(channelName string) {
client.reply(rplPart, c.nick, channelName) client.reply(rplPart, c.nick, channelName)
} }
delete(channel.clientMap, c.nick) delete(channel.clientMap, strings.ToLower(c.nick))
delete(c.channelMap, channelName)
if len(channel.clientMap) == 0 {
delete(c.channelMap, channelKey)
}
} }
func (c *Client) disconnect() { func (c *Client) disconnect() {
@ -171,7 +178,7 @@ func (c *Client) clientThread() {
c.partChannel(channelName) c.partChannel(channelName)
} }
delete(c.server.clientMap, c.nick) delete(c.server.clientMap, strings.ToLower(c.nick))
c.connection.Close() 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)) line := []byte(fmt.Sprintf("%s\r\n", output))
c.connection.SetWriteDeadline(time.Now().Add(time.Second * 30)) c.connection.SetWriteDeadline(time.Now().Add(time.Second * 30))
_, err := c.connection.Write(line) if _, err := c.connection.Write(line); err != nil {
if err != nil {
c.disconnect() c.disconnect()
return return
} }

View File

@ -11,7 +11,7 @@ import (
var ( var (
nickRegexp = regexp.MustCompile(`^[a-zA-Z\[\]_^{|}][a-zA-Z0-9\[\]_^{|}]*$`) 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 { func NewServer() *Server {
@ -68,7 +68,7 @@ func (s *Server) handleEvent(e Event) {
return return
} }
if _, exists := s.clientMap[newNick]; exists { if _, exists := s.clientMap[strings.ToLower(newNick)]; exists {
e.client.reply(errNickInUse, newNick) e.client.reply(errNickInUse, newNick)
return return
} }
@ -149,8 +149,8 @@ func (s *Server) handleEvent(e Event) {
message := strings.Join(args[1:], " ") message := strings.Join(args[1:], " ")
channel, chanExists := s.channelMap[args[0]] channel, chanExists := s.channelMap[strings.ToLower(args[0])]
client, clientExists := s.clientMap[args[0]] client, clientExists := s.clientMap[strings.ToLower(args[0])]
if chanExists { if chanExists {
for _, c := range channel.clientMap { for _, c := range channel.clientMap {
@ -183,7 +183,7 @@ func (s *Server) handleEvent(e Event) {
return return
} }
channel, exists := s.channelMap[args[0]] channel, exists := s.channelMap[strings.ToLower(args[0])]
if exists == false { if exists == false {
e.client.reply(errNoSuchNick, args[0]) e.client.reply(errNoSuchNick, args[0])
return return
@ -232,7 +232,7 @@ func (s *Server) handleEvent(e Event) {
chanList := make([]string, 0, len(channels)) chanList := make([]string, 0, len(channels))
for _, channelName := range 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) listItem := fmt.Sprintf("%s %d :%s", channelName, len(channel.clientMap), channel.topic)
chanList = append(chanList, listItem) chanList = append(chanList, listItem)
} }
@ -284,7 +284,7 @@ func (s *Server) handleEvent(e Event) {
nick := args[0] 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.reply(rplKill, "An operator has disconnected you.")
client.disconnect() client.disconnect()
} else { } else {