added ISON and NOTIFY
This commit is contained in:
parent
f921f53669
commit
55d69d96c1
85
main.go
85
main.go
@ -31,6 +31,7 @@ type Client struct {
|
||||
conn net.Conn
|
||||
host string
|
||||
channels map[string]*Channel
|
||||
monitorTargets map[string]bool
|
||||
registered bool
|
||||
saslRequired bool
|
||||
saslComplete bool
|
||||
@ -153,10 +154,11 @@ func handleConn(conn net.Conn) {
|
||||
|
||||
reader := bufio.NewReader(conn)
|
||||
client := &Client{
|
||||
conn: conn,
|
||||
host: host,
|
||||
channels: make(map[string]*Channel),
|
||||
registered: false,
|
||||
conn: conn,
|
||||
host: host,
|
||||
channels: make(map[string]*Channel),
|
||||
monitorTargets: make(map[string]bool),
|
||||
registered: false,
|
||||
}
|
||||
defer client.cleanup()
|
||||
for {
|
||||
@ -186,6 +188,10 @@ func handleConn(conn net.Conn) {
|
||||
}
|
||||
clients[newNick] = client
|
||||
cliMu.Unlock()
|
||||
if oldNick != "" {
|
||||
notifyMonitorsOffline(oldNick)
|
||||
}
|
||||
notifyMonitorsOnline(newNick)
|
||||
for _, ch := range client.channels {
|
||||
ch.mu.Lock()
|
||||
if oldNick != "" {
|
||||
@ -461,6 +467,22 @@ func handleConn(conn net.Conn) {
|
||||
} else {
|
||||
fmt.Fprintf(client.conn, ":server 461 %s NAMES :Not enough parameters\r\n", client.nick)
|
||||
}
|
||||
case "ISON":
|
||||
if len(msg.Params) < 1 {
|
||||
client.fwrite(":server 461 %s ISON :Not enough parameters\r\n", client.nick)
|
||||
continue
|
||||
}
|
||||
requested := msg.Params
|
||||
var online []string
|
||||
|
||||
cliMu.RLock()
|
||||
for _, nick := range requested {
|
||||
if _, ok := clients[nick]; ok {
|
||||
online = append(online, nick)
|
||||
}
|
||||
}
|
||||
cliMu.RUnlock()
|
||||
client.fwrite(":server 303 %s :%s\r\n", client.nick, strings.Join(online, " "))
|
||||
// ircv3 stuff
|
||||
case "CHATHISTORY":
|
||||
if len(msg.Params) < 4 {
|
||||
@ -475,6 +497,38 @@ func handleConn(conn net.Conn) {
|
||||
continue
|
||||
}
|
||||
client.serveHistory(subcmd, target, count, msg.Params)
|
||||
case "MONITOR":
|
||||
if len(msg.Params) < 1 {
|
||||
client.fwrite(":server 461 %s MONITOR :Not enough parameters\r\n", client.nick)
|
||||
continue
|
||||
}
|
||||
subcmd := strings.ToUpper(msg.Params[0])
|
||||
switch subcmd {
|
||||
case "+":
|
||||
for _, nick := range msg.Params[1:] {
|
||||
client.monitorTargets[nick] = true
|
||||
cliMu.RLock()
|
||||
if _, ok := clients[nick]; ok {
|
||||
client.fwrite(":server 730 %s %s :is online\r\n", client.nick, nick)
|
||||
}
|
||||
cliMu.RUnlock()
|
||||
}
|
||||
case "-":
|
||||
for _, nick := range msg.Params[1:] {
|
||||
delete(client.monitorTargets, nick)
|
||||
}
|
||||
case "C":
|
||||
client.monitorTargets = make(map[string]bool)
|
||||
case "L":
|
||||
var nicks []string
|
||||
for nick := range client.monitorTargets {
|
||||
nicks = append(nicks, nick)
|
||||
}
|
||||
client.fwrite(":server 732 %s :%s\r\n", client.nick, strings.Join(nicks, " "))
|
||||
client.fwrite(":server 733 %s :End of MONITOR list\r\n", client.nick)
|
||||
default:
|
||||
client.fwrite(":server 461 %s MONITOR :Invalid subcommand\r\n", client.nick)
|
||||
}
|
||||
default:
|
||||
if client.nick != "" {
|
||||
fmt.Fprintf(conn, ":server 421 %s %s :Unknown command or command is not implemented\r\n", client.nick, msg.Command)
|
||||
@ -884,6 +938,7 @@ func (c *Client) checkRegistration() {
|
||||
return
|
||||
}
|
||||
c.registered = true
|
||||
notifyMonitorsOnline(c.nick)
|
||||
c.fwrite(":server 001 %s :Welcome to Gocirc, %s!\r\n", c.nick, c.nick)
|
||||
c.fwrite(":server 002 %s :Your host is server\r\n", c.nick)
|
||||
c.fwrite(":server 003 %s :This server has %d users right now\r\n", c.nick, len(clients))
|
||||
@ -1010,6 +1065,7 @@ func (c *Client) cleanup() {
|
||||
cliMu.Lock()
|
||||
delete(clients, c.nick)
|
||||
cliMu.Unlock()
|
||||
notifyMonitorsOffline(c.nick)
|
||||
for name, ch := range c.channels {
|
||||
ch.mu.Lock()
|
||||
delete(ch.members, c.nick)
|
||||
@ -1139,3 +1195,24 @@ func scanRows(rows *sql.Rows, channel string) []HistoryMessage {
|
||||
}
|
||||
return msgs
|
||||
}
|
||||
|
||||
// IRC MONITOR command stuff
|
||||
func notifyMonitorsOnline(nick string) {
|
||||
cliMu.RLock()
|
||||
defer cliMu.RUnlock()
|
||||
for _, c := range clients {
|
||||
if c.monitorTargets[nick] {
|
||||
c.fwrite(":server 730 %s %s :is online\r\n", c.nick, nick)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func notifyMonitorsOffline(nick string) {
|
||||
cliMu.RLock()
|
||||
defer cliMu.RUnlock()
|
||||
for _, c := range clients {
|
||||
if c.monitorTargets[nick] {
|
||||
c.fwrite(":server 731 %s %s :is offline\r\n", c.nick, nick)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user