Fixed duplicate nick registration

This commit is contained in:
Harry Jeffery 2013-08-23 16:24:06 +01:00
parent 8994c1bb55
commit afe61051b7

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"io" "io"
"log" "log"
"math/rand"
"net" "net"
"regexp" "regexp"
"sort" "sort"
@ -27,6 +26,7 @@ type Client struct {
signalChan chan int signalChan chan int
outputChan chan string outputChan chan string
nick string nick string
registered bool
channelMap map[string]*Channel channelMap map[string]*Channel
} }
@ -60,6 +60,7 @@ const (
errAlreadyReg errAlreadyReg
errNoSuchNick errNoSuchNick
errUnknownCommand errUnknownCommand
errNotReg
) )
var ( var (
@ -127,19 +128,23 @@ func (s *Server) handleEvent(e Event) {
return return
} }
//Protect the server name from being used
if newNick == s.name {
e.client.reply(errNickInUse, newNick)
return
}
e.client.setNick(newNick) e.client.setNick(newNick)
case command == "USER": case command == "USER":
if e.client.nick == "" { //This command is completely disused, we use nick to register
//Give them a unique Guest nick
newNick := fmt.Sprintf("Guest%d", rand.Int())
for s.clientMap[newNick] != nil {
newNick = fmt.Sprintf("Guest%d", rand.Int())
}
}
e.client.reply(rplWelcome)
case command == "JOIN": case command == "JOIN":
if e.client.registered == false {
e.client.reply(errNotReg)
return
}
if len(args) < 1 { if len(args) < 1 {
e.client.reply(errMoreArgs) e.client.reply(errMoreArgs)
return return
@ -162,6 +167,11 @@ func (s *Server) handleEvent(e Event) {
} }
case command == "PART": case command == "PART":
if e.client.registered == false {
e.client.reply(errNotReg)
return
}
if len(args) < 1 { if len(args) < 1 {
e.client.reply(errMoreArgs) e.client.reply(errMoreArgs)
return return
@ -176,6 +186,11 @@ func (s *Server) handleEvent(e Event) {
} }
case command == "PRIVMSG": case command == "PRIVMSG":
if e.client.registered == false {
e.client.reply(errNotReg)
return
}
if len(args) < 2 { if len(args) < 2 {
e.client.reply(errMoreArgs) e.client.reply(errMoreArgs)
return return
@ -199,9 +214,19 @@ func (s *Server) handleEvent(e Event) {
} }
case command == "QUIT": case command == "QUIT":
if e.client.registered == false {
e.client.reply(errNotReg)
return
}
//Stop the client, which will auto part channels and quit //Stop the client, which will auto part channels and quit
e.client.signalChan <- signalStop e.client.signalChan <- signalStop
case command == "TOPIC": case command == "TOPIC":
if e.client.registered == false {
e.client.reply(errNotReg)
return
}
if len(args) < 1 { if len(args) < 1 {
e.client.reply(errMoreArgs) e.client.reply(errMoreArgs)
return return
@ -409,6 +434,8 @@ func (c *Client) reply(code int, args ...string) {
c.outputChan <- fmt.Sprintf(":%s 401 %s %s :No such nick/channel", c.server.name, c.nick, args[0]) c.outputChan <- fmt.Sprintf(":%s 401 %s %s :No such nick/channel", c.server.name, c.nick, args[0])
case errUnknownCommand: case errUnknownCommand:
c.outputChan <- fmt.Sprintf(":%s 421 %s %s :Unknown command", c.server.name, c.nick, args[0]) c.outputChan <- fmt.Sprintf(":%s 421 %s %s :Unknown command", c.server.name, c.nick, args[0])
case errNotReg:
c.outputChan <- fmt.Sprintf(":%s 451 :You have not registered", c.server.name)
} }
} }
@ -425,29 +452,35 @@ func (c *Client) setNick(nick string) {
c.nick = nick c.nick = nick
c.server.clientMap[c.nick] = c c.server.clientMap[c.nick] = c
clients := make([]string, 0, 100) if oldNick == "" {
//Oldnick is ""
c.registered = true
c.reply(rplWelcome)
} else {
clients := make([]string, 0, 100)
for _, channel := range c.channelMap { for _, channel := range c.channelMap {
channel.clientMap[c.nick] = c channel.clientMap[c.nick] = 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)
}
} }
}
//By sorting the nicks and skipping duplicates we send each client one message //By sorting the nicks and skipping duplicates we send each client one message
sort.Strings(clients) sort.Strings(clients)
prevNick := "" prevNick := ""
for _, nick := range clients { for _, nick := range clients {
if nick == prevNick { if nick == prevNick {
continue continue
} }
prevNick = nick prevNick = nick
client, exists := c.server.clientMap[nick] client, exists := c.server.clientMap[nick]
if exists { if exists {
client.reply(rplNickChange, oldNick, c.nick) client.reply(rplNickChange, oldNick, c.nick)
}
} }
} }
} }