Fix MODE downstream support

- Fix replies without client as first argument
- Replace wrong prefix check with a proper entity type check
This commit is contained in:
delthas 2020-03-20 03:05:14 +01:00 committed by Simon Ser
parent b3ad960529
commit aedf66c73d
2 changed files with 28 additions and 27 deletions

View file

@ -150,16 +150,11 @@ func (dc *downstreamConn) upstream() *upstreamConn {
return upstream return upstream
} }
func (dc *downstreamConn) marshalEntity(uc *upstreamConn, name string) string { func (dc *downstreamConn) marshalEntity(uc *upstreamConn, entity string) string {
for _, r := range name { if uc.isChannel(entity) {
switch r { return dc.marshalChannel(uc, entity)
// TODO: support upstream ISUPPORT channel prefixes
case '#', '&', '+', '!':
return dc.marshalChannel(uc, name)
}
break
} }
return dc.marshalNick(uc, name) return dc.marshalNick(uc, entity)
} }
func (dc *downstreamConn) marshalChannel(uc *upstreamConn, name string) string { func (dc *downstreamConn) marshalChannel(uc *upstreamConn, name string) string {
@ -852,10 +847,6 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
} }
} }
case "MODE": case "MODE":
if msg.Prefix == nil {
return fmt.Errorf("missing prefix")
}
var name string var name string
if err := parseMessageParams(msg, &name); err != nil { if err := parseMessageParams(msg, &name); err != nil {
return err return err
@ -866,12 +857,13 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
modeStr = msg.Params[1] modeStr = msg.Params[1]
} }
if msg.Prefix.Name != name { uc, upstreamName, err := dc.unmarshalEntity(name)
uc, upstreamName, err := dc.unmarshalEntity(name) if err != nil {
if err != nil { return err
return err }
}
if uc.isChannel(upstreamName) {
// TODO: handle MODE channel mode arguments
if modeStr != "" { if modeStr != "" {
uc.SendMessage(&irc.Message{ uc.SendMessage(&irc.Message{
Command: "MODE", Command: "MODE",
@ -882,14 +874,14 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
if !ok { if !ok {
return ircError{&irc.Message{ return ircError{&irc.Message{
Command: irc.ERR_NOSUCHCHANNEL, Command: irc.ERR_NOSUCHCHANNEL,
Params: []string{name, "No such channel"}, Params: []string{dc.nick, name, "No such channel"},
}} }}
} }
dc.SendMessage(&irc.Message{ dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(), Prefix: dc.srv.prefix(),
Command: irc.RPL_CHANNELMODEIS, Command: irc.RPL_CHANNELMODEIS,
Params: []string{name, string(ch.modes)}, Params: []string{dc.nick, name, string(ch.modes)},
}) })
} }
} else { } else {
@ -911,7 +903,7 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
dc.SendMessage(&irc.Message{ dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(), Prefix: dc.srv.prefix(),
Command: irc.RPL_UMODEIS, Command: irc.RPL_UMODEIS,
Params: []string{""}, // TODO Params: []string{dc.nick, ""}, // TODO
}) })
} }
} }

View file

@ -134,6 +134,18 @@ func (uc *upstreamConn) getChannel(name string) (*upstreamChannel, error) {
return ch, nil return ch, nil
} }
func (uc *upstreamConn) isChannel(entity string) bool {
for _, r := range entity {
switch r {
// TODO: support upstream ISUPPORT channel prefixes
case '#', '&', '+', '!':
return true
}
break
}
return false
}
func (uc *upstreamConn) handleMessage(msg *irc.Message) error { func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
switch msg.Command { switch msg.Command {
case "PING": case "PING":
@ -143,21 +155,18 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
}) })
return nil return nil
case "MODE": case "MODE":
if msg.Prefix == nil {
return fmt.Errorf("missing prefix")
}
var name, modeStr string var name, modeStr string
if err := parseMessageParams(msg, &name, &modeStr); err != nil { if err := parseMessageParams(msg, &name, &modeStr); err != nil {
return err return err
} }
if name == msg.Prefix.Name { // user mode change if !uc.isChannel(name) { // user mode change
if name != uc.nick { if name != uc.nick {
return fmt.Errorf("received MODE message for unknow nick %q", name) return fmt.Errorf("received MODE message for unknown nick %q", name)
} }
return uc.modes.Apply(modeStr) return uc.modes.Apply(modeStr)
} else { // channel mode change } else { // channel mode change
// TODO: handle MODE channel mode arguments
ch, err := uc.getChannel(name) ch, err := uc.getChannel(name)
if err != nil { if err != nil {
return err return err