Fixed duplicate nickname issues and /quit bug
This commit is contained in:
parent
afe61051b7
commit
7980ec0b7f
77
rosella.go
77
rosella.go
@ -27,6 +27,7 @@ type Client struct {
|
|||||||
outputChan chan string
|
outputChan chan string
|
||||||
nick string
|
nick string
|
||||||
registered bool
|
registered bool
|
||||||
|
connected bool
|
||||||
channelMap map[string]*Channel
|
channelMap map[string]*Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ const (
|
|||||||
rplNoTopic
|
rplNoTopic
|
||||||
rplNames
|
rplNames
|
||||||
rplNickChange
|
rplNickChange
|
||||||
|
rplKill
|
||||||
errMoreArgs
|
errMoreArgs
|
||||||
errNoNick
|
errNoNick
|
||||||
errInvalidNick
|
errInvalidNick
|
||||||
@ -88,8 +90,9 @@ func (s *Server) HandleConnection(conn net.Conn) {
|
|||||||
client := &Client{server: s,
|
client := &Client{server: s,
|
||||||
connection: conn,
|
connection: conn,
|
||||||
outputChan: make(chan string),
|
outputChan: make(chan string),
|
||||||
signalChan: make(chan int),
|
signalChan: make(chan int, 3),
|
||||||
channelMap: make(map[string]*Channel)}
|
channelMap: make(map[string]*Channel),
|
||||||
|
connected: true}
|
||||||
|
|
||||||
go client.clientThread()
|
go client.clientThread()
|
||||||
}
|
}
|
||||||
@ -137,7 +140,13 @@ func (s *Server) handleEvent(e Event) {
|
|||||||
e.client.setNick(newNick)
|
e.client.setNick(newNick)
|
||||||
|
|
||||||
case command == "USER":
|
case command == "USER":
|
||||||
//This command is completely disused, we use nick to register
|
if e.client.nick == "" {
|
||||||
|
e.client.reply(rplKill, "Your nickname is already being used")
|
||||||
|
e.client.disconnect()
|
||||||
|
} else {
|
||||||
|
e.client.reply(rplWelcome)
|
||||||
|
e.client.registered = true
|
||||||
|
}
|
||||||
|
|
||||||
case command == "JOIN":
|
case command == "JOIN":
|
||||||
if e.client.registered == false {
|
if e.client.registered == false {
|
||||||
@ -220,7 +229,8 @@ func (s *Server) handleEvent(e Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//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.disconnect()
|
||||||
|
|
||||||
case command == "TOPIC":
|
case command == "TOPIC":
|
||||||
if e.client.registered == false {
|
if e.client.registered == false {
|
||||||
e.client.reply(errNotReg)
|
e.client.reply(errNotReg)
|
||||||
@ -313,8 +323,8 @@ func (s *Server) partChannel(client *Client, channelName string) {
|
|||||||
func (c *Client) clientThread() {
|
func (c *Client) clientThread() {
|
||||||
defer c.connection.Close()
|
defer c.connection.Close()
|
||||||
|
|
||||||
readSignalChan := make(chan int, 1)
|
readSignalChan := make(chan int, 3)
|
||||||
writeSignalChan := make(chan int, 1)
|
writeSignalChan := make(chan int, 3)
|
||||||
writeChan := make(chan string, 100)
|
writeChan := make(chan string, 100)
|
||||||
|
|
||||||
go c.readThread(readSignalChan)
|
go c.readThread(readSignalChan)
|
||||||
@ -345,8 +355,8 @@ func (c *Client) clientThread() {
|
|||||||
c.server.partChannel(c, channelName)
|
c.server.partChannel(c, channelName)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove from client list
|
|
||||||
delete(c.server.clientMap, c.nick)
|
delete(c.server.clientMap, c.nick)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) readThread(signalChan chan int) {
|
func (c *Client) readThread(signalChan chan int) {
|
||||||
@ -401,8 +411,17 @@ func (c *Client) writeThread(signalChan chan int, outputChan chan string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) disconnect() {
|
||||||
|
c.connected = false
|
||||||
|
c.signalChan <- signalStop
|
||||||
|
}
|
||||||
|
|
||||||
//Send a reply to a user with the code specified
|
//Send a reply to a user with the code specified
|
||||||
func (c *Client) reply(code int, args ...string) {
|
func (c *Client) reply(code int, args ...string) {
|
||||||
|
if c.connected == false {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch code {
|
switch code {
|
||||||
case rplWelcome:
|
case rplWelcome:
|
||||||
c.outputChan <- fmt.Sprintf(":%s 001 %s :Welcome to %s", c.server.name, c.nick, c.server.name)
|
c.outputChan <- fmt.Sprintf(":%s 001 %s :Welcome to %s", c.server.name, c.nick, c.server.name)
|
||||||
@ -420,6 +439,8 @@ func (c *Client) reply(code int, args ...string) {
|
|||||||
c.outputChan <- fmt.Sprintf(":%s 366 %s", c.server.name, c.nick)
|
c.outputChan <- fmt.Sprintf(":%s 366 %s", c.server.name, c.nick)
|
||||||
case rplNickChange:
|
case rplNickChange:
|
||||||
c.outputChan <- fmt.Sprintf(":%s NICK %s", args[0], args[1])
|
c.outputChan <- fmt.Sprintf(":%s NICK %s", args[0], args[1])
|
||||||
|
case rplKill:
|
||||||
|
c.outputChan <- fmt.Sprintf(":%s KILL %s A A %s", c.server.name, c.nick, args[0])
|
||||||
case errMoreArgs:
|
case errMoreArgs:
|
||||||
c.outputChan <- fmt.Sprintf(":%s 461 %s %s :Not enough params", c.server.name, c.nick, args[0])
|
c.outputChan <- fmt.Sprintf(":%s 461 %s %s :Not enough params", c.server.name, c.nick, args[0])
|
||||||
case errNoNick:
|
case errNoNick:
|
||||||
@ -452,35 +473,29 @@ func (c *Client) setNick(nick string) {
|
|||||||
c.nick = nick
|
c.nick = nick
|
||||||
c.server.clientMap[c.nick] = c
|
c.server.clientMap[c.nick] = c
|
||||||
|
|
||||||
if oldNick == "" {
|
clients := make([]string, 0, 100)
|
||||||
//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)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user