Add support for TAGMSG and client message tags
Previously we dropped all TAGMSG as well as any client message tag sent from downstream. This adds support for properly forwarding TAGMSG and client message tags from downstreams and upstreams. TAGMSG messages are intentionally not logged, because they are currently typically used for +typing, which can generate a lot of traffic and is only useful for a few seconds after it is sent.
This commit is contained in:
parent
cdef46d0da
commit
f4e0c51366
@ -250,6 +250,9 @@ func (dc *downstreamConn) readMessages(ch chan<- event) error {
|
||||
// This can only called from the user goroutine.
|
||||
func (dc *downstreamConn) SendMessage(msg *irc.Message) {
|
||||
if !dc.caps["message-tags"] {
|
||||
if msg.Command == "TAGMSG" {
|
||||
return
|
||||
}
|
||||
msg = msg.Copy()
|
||||
for name := range msg.Tags {
|
||||
supported := false
|
||||
@ -274,7 +277,7 @@ func (dc *downstreamConn) marshalMessage(msg *irc.Message, net *network) *irc.Me
|
||||
msg.Prefix = dc.marshalUserPrefix(net, msg.Prefix)
|
||||
|
||||
switch msg.Command {
|
||||
case "PRIVMSG", "NOTICE":
|
||||
case "PRIVMSG", "NOTICE", "TAGMSG":
|
||||
msg.Params[0] = dc.marshalEntity(net, msg.Params[0])
|
||||
case "NICK":
|
||||
// Nick change for another user
|
||||
@ -1397,6 +1400,7 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
||||
if err := parseMessageParams(msg, &targetsStr, &text); err != nil {
|
||||
return err
|
||||
}
|
||||
tags := copyClientTags(msg.Tags)
|
||||
|
||||
for _, name := range strings.Split(targetsStr, ",") {
|
||||
if name == serviceNick {
|
||||
@ -1418,14 +1422,15 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
||||
unmarshaledText = dc.unmarshalText(uc, text)
|
||||
}
|
||||
uc.SendMessageLabeled(dc.id, &irc.Message{
|
||||
Tags: tags,
|
||||
Command: "PRIVMSG",
|
||||
Params: []string{upstreamName, unmarshaledText},
|
||||
})
|
||||
|
||||
echoTags := tags.Copy()
|
||||
echoTags["time"] = irc.TagValue(time.Now().UTC().Format(serverTimeLayout))
|
||||
echoMsg := &irc.Message{
|
||||
Tags: irc.Tags{
|
||||
"time": irc.TagValue(time.Now().UTC().Format(serverTimeLayout)),
|
||||
},
|
||||
Tags: echoTags,
|
||||
Prefix: &irc.Prefix{
|
||||
Name: uc.nick,
|
||||
User: uc.username,
|
||||
@ -1440,6 +1445,7 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
||||
if err := parseMessageParams(msg, &targetsStr, &text); err != nil {
|
||||
return err
|
||||
}
|
||||
tags := copyClientTags(msg.Tags)
|
||||
|
||||
for _, name := range strings.Split(targetsStr, ",") {
|
||||
uc, upstreamName, err := dc.unmarshalEntity(name)
|
||||
@ -1452,10 +1458,30 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
|
||||
unmarshaledText = dc.unmarshalText(uc, text)
|
||||
}
|
||||
uc.SendMessageLabeled(dc.id, &irc.Message{
|
||||
Tags: tags,
|
||||
Command: "NOTICE",
|
||||
Params: []string{upstreamName, unmarshaledText},
|
||||
})
|
||||
}
|
||||
case "TAGMSG":
|
||||
var targetsStr string
|
||||
if err := parseMessageParams(msg, &targetsStr); err != nil {
|
||||
return err
|
||||
}
|
||||
tags := copyClientTags(msg.Tags)
|
||||
|
||||
for _, name := range strings.Split(targetsStr, ",") {
|
||||
uc, upstreamName, err := dc.unmarshalEntity(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uc.SendMessageLabeled(dc.id, &irc.Message{
|
||||
Tags: tags,
|
||||
Command: "TAGMSG",
|
||||
Params: []string{upstreamName},
|
||||
})
|
||||
}
|
||||
case "INVITE":
|
||||
var user, channel string
|
||||
if err := parseMessageParams(msg, &user, &channel); err != nil {
|
||||
|
10
irc.go
10
irc.go
@ -274,6 +274,16 @@ func parseMessageParams(msg *irc.Message, out ...*string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyClientTags(tags irc.Tags) irc.Tags {
|
||||
t := make(irc.Tags, len(tags))
|
||||
for k, v := range tags {
|
||||
if strings.HasPrefix(k, "+") {
|
||||
t[k] = v
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
type batch struct {
|
||||
Type string
|
||||
Params []string
|
||||
|
25
upstream.go
25
upstream.go
@ -320,14 +320,20 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
Params: msg.Params,
|
||||
})
|
||||
return nil
|
||||
case "NOTICE", "PRIVMSG":
|
||||
case "NOTICE", "PRIVMSG", "TAGMSG":
|
||||
if msg.Prefix == nil {
|
||||
return fmt.Errorf("expected a prefix")
|
||||
}
|
||||
|
||||
var entity, text string
|
||||
if err := parseMessageParams(msg, &entity, &text); err != nil {
|
||||
return err
|
||||
if msg.Command != "TAGMSG" {
|
||||
if err := parseMessageParams(msg, &entity, &text); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := parseMessageParams(msg, &entity); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if msg.Prefix.Name == serviceNick {
|
||||
@ -341,7 +347,7 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
|
||||
if msg.Prefix.User == "" && msg.Prefix.Host == "" { // server message
|
||||
uc.produce("", msg, nil)
|
||||
} else { // regular user NOTICE or PRIVMSG
|
||||
} else { // regular user message
|
||||
target := entity
|
||||
if target == uc.nick {
|
||||
target = msg.Prefix.Name
|
||||
@ -1274,8 +1280,6 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
||||
})
|
||||
})
|
||||
}
|
||||
case "TAGMSG":
|
||||
// TODO: relay to downstream connections that accept message-tags
|
||||
case "ACK":
|
||||
// Ignore
|
||||
case irc.RPL_NOWAWAY, irc.RPL_UNAWAY:
|
||||
@ -1487,6 +1491,15 @@ func (uc *upstreamConn) readMessages(ch chan<- event) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (uc *upstreamConn) SendMessage(msg *irc.Message) {
|
||||
if !uc.caps["message-tags"] {
|
||||
msg = msg.Copy()
|
||||
msg.Tags = nil
|
||||
}
|
||||
|
||||
uc.conn.SendMessage(msg)
|
||||
}
|
||||
|
||||
func (uc *upstreamConn) SendMessageLabeled(downstreamID uint64, msg *irc.Message) {
|
||||
if uc.caps["labeled-response"] {
|
||||
if msg.Tags == nil {
|
||||
|
Loading…
Reference in New Issue
Block a user