Handle downstream MODE messages

This commit is contained in:
Simon Ser 2020-02-07 13:08:27 +01:00
parent 519cdd9e38
commit 4de405d3b2
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 73 additions and 4 deletions

View File

@ -246,6 +246,52 @@ func (c *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
c.user.forEachUpstream(func(uc *upstreamConn) { c.user.forEachUpstream(func(uc *upstreamConn) {
uc.messages <- msg uc.messages <- msg
}) })
case "MODE":
var name string
if err := parseMessageParams(msg, &name); err != nil {
return err
}
var modeStr string
if len(msg.Params) > 1 {
modeStr = msg.Params[1]
}
if msg.Prefix.Name != name {
ch, err := c.user.getChannel(name)
if err != nil {
return err
}
if modeStr != "" {
ch.conn.messages <- msg
} else {
c.messages <- &irc.Message{
Prefix: c.srv.prefix(),
Command: irc.RPL_CHANNELMODEIS,
Params: []string{ch.Name, string(ch.modes)},
}
}
} else {
if name != c.nick {
return ircError{&irc.Message{
Command: irc.ERR_USERSDONTMATCH,
Params: []string{c.nick, "Cannot change mode for other users"},
}}
}
if modeStr != "" {
c.user.forEachUpstream(func(uc *upstreamConn) {
uc.messages <- msg
})
} else {
c.messages <- &irc.Message{
Prefix: c.srv.prefix(),
Command: irc.RPL_UMODEIS,
Params: []string{""}, // TODO
}
}
}
default: default:
c.logger.Printf("unhandled message: %v", msg) c.logger.Printf("unhandled message: %v", msg)
return newUnknownCommandError(msg.Command) return newUnknownCommandError(msg.Command)

View File

@ -59,6 +59,27 @@ func (u *user) forEachDownstream(f func(dc *downstreamConn)) {
u.lock.Unlock() u.lock.Unlock()
} }
func (u *user) getChannel(name string) (*upstreamChannel, error) {
var channel *upstreamChannel
var err error
u.forEachUpstream(func(uc *upstreamConn) {
if err != nil {
return
}
if ch, ok := uc.channels[name]; ok {
if channel != nil {
err = fmt.Errorf("ambiguous channel name %q", name)
} else {
channel = ch
}
}
})
if channel == nil {
return nil, fmt.Errorf("unknown channel %q", name)
}
return channel, nil
}
type Upstream struct { type Upstream struct {
Addr string Addr string
Nick string Nick string

View File

@ -14,6 +14,7 @@ import (
type upstreamChannel struct { type upstreamChannel struct {
Name string Name string
conn *upstreamConn
Topic string Topic string
TopicWho string TopicWho string
TopicTime time.Time TopicTime time.Time
@ -126,11 +127,11 @@ func (c *upstreamConn) handleMessage(msg *irc.Message) error {
if err := ch.modes.Apply(modeStr); err != nil { if err := ch.modes.Apply(modeStr); err != nil {
return err return err
} }
c.user.forEachDownstream(func(dc *downstreamConn) {
dc.messages <- msg
})
} }
c.user.forEachDownstream(func(dc *downstreamConn) {
dc.messages <- msg
})
case "NOTICE": case "NOTICE":
c.logger.Print(msg) c.logger.Print(msg)
case irc.RPL_WELCOME: case irc.RPL_WELCOME:
@ -182,6 +183,7 @@ func (c *upstreamConn) handleMessage(msg *irc.Message) error {
c.logger.Printf("joined channel %q", ch) c.logger.Printf("joined channel %q", ch)
c.channels[ch] = &upstreamChannel{ c.channels[ch] = &upstreamChannel{
Name: ch, Name: ch,
conn: c,
Members: make(map[string]membership), Members: make(map[string]membership),
} }
} else { } else {