Commits

kylelemons committed 5c4bb52

Added NAMES and WHO replies

Comments (0)

Files changed (4)

 				}
 				// Send topic reply
 				client.Numeric(RPL_NOTOPIC, chn.Name, "No topic is set")
-				// Send names reply
-				chtype := "=" // TODO =public *private @secret
-				unjoined := make([]string, 0, len(chn.users))
-				for user := range chn.users {
-					// TODO @op %hop +voice
-					unjoined = append(unjoined, user.Nick)
-				}
-				joined := ircjoin(unjoined, 10)
-				for _,group := range joined {
-					client.Numeric(RPL_NAMEREPLY, chtype, chn.Name, group)
-				}
-				client.Numeric(RPL_ENDOFNAMES, chn.Name, "End of NAMES list")
+				chn.sendnames(client)
+			case "sendnames":
+				client := ev.Args["client"].(*Client)
+				chn.sendnames(client)
+			case "sendwho":
+				client := ev.Args["client"].(*Client)
+				chn.sendwho(client)
+			//case "getpeers":
+				//ev.Result["peers"] = chn.getpeers()
+				//// peers []*Client
 			case "part": // We don't handle the quit message, just remove
 				// client *Client
 				client := ev.Args["client"].(*Client)
 	}
 	//TODO: chn.Close()
 }
+
+func (chn *Channel) sendnames(client *Client) {
+	// Send names reply
+	chtype := "=" // TODO =public *private @secret
+	unjoined := chn.getpeernames()
+	joined := ircjoin(unjoined, 10)
+	for _,group := range joined {
+		client.Numeric(RPL_NAMEREPLY, chtype, chn.Name, group)
+	}
+	client.Numeric(RPL_ENDOFNAMES, chn.Name, "End of NAMES list")
+}
+
+func (chn *Channel) sendwho(client *Client) {
+	for peer := range chn.users {
+		//channel
+		//user
+		//host
+		//server
+		//nick
+		//<H|G>[*][@+]
+		//:0
+		//realname
+		client.RawNumeric(RPL_WHOREPLY, chn.Name,
+			peer.User, peer.Host, chn.Server.Name, peer.Nick,
+			"H", ":0", peer.Name)
+	}
+	client.Numeric(RPL_ENDOFWHO, chn.Name, "End of WHO list")
+}
+
+func (chn *Channel) getpeernames() []string {
+	peers := make([]string, 0, len(chn.users))
+	for user := range chn.users {
+		// TODO @op %hop +voice
+		peers = append(peers, user.Nick)
+	}
+	return peers
+}
+
+func (chn *Channel) getpeers() []*Client {
+	peers := make([]*Client, 0, len(chn.users))
+	for user := range chn.users {
+		peers = append(peers, user)
+	}
+	return peers
+}
 	CMD_QUIT:       {client_quit,     0, true,  false, true,  false},
 	CMD_PRIVMSG:    {client_privmsg,  2, true,  false, true,  false},
 	CMD_NOTICE:     {client_notice,   0, true,  true,  true,  true},
+	CMD_NAMES:      {client_names,    0, true,  false, true,  false},
+	CMD_WHO:        {client_who,      0, true,  false, true,  false},
 }
 
 func dispatch_cmessage(cli *Client, srv *Server, msg *ClientMessage) {
 func client_join(cli *Client, srv *Server, message *ClientMessage) os.Error {
 	// TODO: Check already joined
 	// Get the channel that's being joined
-	ev := NewEvent("getchan")
+	ev := NewEvent("newchan")
 	ev.Args["name"] = message.Args[0]
-	ev.Args["create"] = true
 	srv.Events <- ev
 	<-ev.Reply
 	channel := ev.Result["channel"].(*Channel)
 	}
 	return nil
 }
+
+func client_names(cli *Client, srv *Server, message *ClientMessage) os.Error {
+	if len(message.Args) == 0 { return nil }
+	chanlist := strings.Split(message.Args[0], ",", -1)
+	for _,channame := range chanlist {
+		ev := NewEvent("getchan")
+		ev.Args["name"] = channame
+		srv.Events <- ev
+		if <-ev.Reply {
+			channel := ev.Result["channel"].(*Channel)
+			ev = NewEvent("sendnames")
+			ev.Args["client"] = cli
+			channel.Events <- ev
+			<-ev.Reply
+		} else {
+			cli.Numeric(RPL_ENDOFNAMES, channame, "End of NAMES list")
+		}
+	}
+	return nil
+}
+
+func client_who(cli *Client, srv *Server, message *ClientMessage) os.Error {
+	// First, check if it wants ALL peers
+	if len(message.Args) == 0 {
+		// TODO
+		cli.Numeric(RPL_ENDOFWHO, "End of WHO list")
+		return nil
+	}
+
+	// Only show opers?
+	operonly := len(message.Args) > 1 && message.Args[1] == "o"
+
+	for _,srch := range strings.Split(message.Args[0], ",", -1) {
+		// Second, check if it's a channel
+		ev := NewEvent("getchan")
+		ev.Args["name"] = srch
+		srv.Events <- ev
+		if <-ev.Reply {
+			channel := ev.Result["channel"].(*Channel)
+			ev = NewEvent("sendwho")
+			ev.Args["client"] = cli
+			channel.Events <- ev
+			<-ev.Reply
+			return nil
+		}
+
+		// Third, check if it's a mask (optionally operonly with "o" flag)
+		operonly = operonly
+		cli.Numeric(RPL_ENDOFWHO, srch, "End of WHO list")
+	}
+
+	return nil
+}
+
+// TODO: Remove the os.Error return

irc/protocol_numerics.go

 	CMD_ERROR   = "ERROR"
 	CMD_JOIN    = "JOIN"
 	CMD_MODE    = "MODE"
+	CMD_NAMES   = "NAMES"
 	CMD_NICK    = "NICK"
 	CMD_NOTICE  = "NOTICE"
 	CMD_OPER    = "OPER"
 				// peers    map[Client*]bool
 				// nick    *Client
 				// channel *Channel
-			case "getchan":
+			case "newchan":
 				// channel string
 				name := ev.Args["name"].(string)
 				key := irctolower(name)
 				}
 				ev.Result["channel"] = srv.channels[key]
 				// channel *Channel
+			case "getchan":
+				// channel string
+				name := ev.Args["name"].(string)
+				key := irctolower(name)
+				_,exists := srv.channels[key]
+				if exists {
+					ev.Result["channel"] = srv.channels[key]
+				}
+				success = exists
+				// channel *Channel
 			default:
 				success = false
 		}