Add downstreamConn.SendBatch helper

This commit is contained in:
Simon Ser 2021-06-05 12:38:52 +02:00
parent bd41e3bd2b
commit 0081c96ec0

View file

@ -187,6 +187,8 @@ type downstreamConn struct {
supportedCaps map[string]string
caps map[string]bool
lastBatchRef uint64
saslServer sasl.Server
}
@ -379,6 +381,10 @@ func (dc *downstreamConn) SendMessage(msg *irc.Message) {
}
}
}
if !dc.caps["batch"] && msg.Tags["batch"] != "" {
msg = msg.Copy()
delete(msg.Tags, "batch")
}
if msg.Command == "JOIN" && !dc.caps["extended-join"] {
msg.Params = msg.Params[:1]
}
@ -389,6 +395,30 @@ func (dc *downstreamConn) SendMessage(msg *irc.Message) {
dc.conn.SendMessage(msg)
}
func (dc *downstreamConn) SendBatch(typ string, params []string, tags irc.Tags, f func(batchRef irc.TagValue)) {
dc.lastBatchRef++
ref := fmt.Sprintf("%v", dc.lastBatchRef)
if dc.caps["batch"] {
dc.SendMessage(&irc.Message{
Tags: tags,
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: append([]string{"+" + ref, typ}, params...),
})
}
f(irc.TagValue(ref))
if dc.caps["batch"] {
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + ref},
})
}
}
// sendMessageWithID sends an outgoing message with the specified internal ID.
func (dc *downstreamConn) sendMessageWithID(msg *irc.Message, id string) {
dc.SendMessage(msg)
@ -1083,26 +1113,18 @@ func (dc *downstreamConn) welcome() error {
dc.updateSupportedCaps()
if dc.caps["soju.im/bouncer-networks-notify"] {
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"+networks", "soju.im/bouncer-networks"},
})
dc.user.forEachNetwork(func(network *network) {
idStr := fmt.Sprintf("%v", network.ID)
attrs := getNetworkAttrs(network)
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": irc.TagValue("networks")},
Prefix: dc.srv.prefix(),
Command: "BOUNCER",
Params: []string{"NETWORK", idStr, attrs.String()},
dc.SendBatch("soju.im/bouncer-networks", nil, nil, func(batchRef irc.TagValue) {
dc.user.forEachNetwork(func(network *network) {
idStr := fmt.Sprintf("%v", network.ID)
attrs := getNetworkAttrs(network)
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": batchRef},
Prefix: dc.srv.prefix(),
Command: "BOUNCER",
Params: []string{"NETWORK", idStr, attrs.String()},
})
})
})
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-networks"},
})
}
dc.forEachUpstream(func(uc *upstreamConn) {
@ -1192,39 +1214,24 @@ func (dc *downstreamConn) sendTargetBacklog(net *network, target, msgID string)
return
}
batchRef := "history"
if dc.caps["batch"] {
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"+" + batchRef, "chathistory", dc.marshalEntity(net, target)},
})
}
for _, msg := range history {
if !dc.messageSupportsHistory(msg) {
continue
}
if ch != nil && ch.Detached {
if net.detachedMessageNeedsRelay(ch, msg) {
dc.relayDetachedMessage(net, msg)
dc.SendBatch("chathistory", []string{dc.marshalEntity(net, target)}, nil, func(batchRef irc.TagValue) {
for _, msg := range history {
if !dc.messageSupportsHistory(msg) {
continue
}
} else {
if dc.caps["batch"] {
msg.Tags["batch"] = irc.TagValue(batchRef)
}
dc.SendMessage(dc.marshalMessage(msg, net))
}
}
if dc.caps["batch"] {
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + batchRef},
})
}
if ch != nil && ch.Detached {
if net.detachedMessageNeedsRelay(ch, msg) {
dc.relayDetachedMessage(net, msg)
}
} else {
if dc.caps["batch"] {
msg.Tags["batch"] = irc.TagValue(batchRef)
}
dc.SendMessage(dc.marshalMessage(msg, net))
}
}
})
}
func (dc *downstreamConn) relayDetachedMessage(net *network, msg *irc.Message) {
@ -2107,30 +2114,19 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
}}
}
batchRef := "history-targets"
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"+" + batchRef, "draft/chathistory-targets"},
})
dc.SendBatch("draft/chathistory-targets", nil, nil, func(batchRef irc.TagValue) {
for _, target := range targets {
if ch := uc.network.channels.Value(target.Name); ch != nil && ch.Detached {
continue
}
for _, target := range targets {
if ch := uc.network.channels.Value(target.Name); ch != nil && ch.Detached {
continue
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": batchRef},
Prefix: dc.srv.prefix(),
Command: "CHATHISTORY",
Params: []string{"TARGETS", target.Name, target.LatestMessage.UTC().Format(serverTimeLayout)},
})
}
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": irc.TagValue(batchRef)},
Prefix: dc.srv.prefix(),
Command: "CHATHISTORY",
Params: []string{"TARGETS", target.Name, target.LatestMessage.UTC().Format(serverTimeLayout)},
})
}
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + batchRef},
})
return nil
@ -2140,22 +2136,11 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
return newChatHistoryError(subcommand, target)
}
batchRef := "history"
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"+" + batchRef, "chathistory", target},
})
for _, msg := range history {
msg.Tags["batch"] = irc.TagValue(batchRef)
dc.SendMessage(dc.marshalMessage(msg, uc.network))
}
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-" + batchRef},
dc.SendBatch("chathistory", []string{target}, nil, func(batchRef irc.TagValue) {
for _, msg := range history {
msg.Tags["batch"] = batchRef
dc.SendMessage(dc.marshalMessage(msg, uc.network))
}
})
case "BOUNCER":
var subcommand string
@ -2165,26 +2150,18 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
switch strings.ToUpper(subcommand) {
case "LISTNETWORKS":
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"+networks", "soju.im/bouncer-networks"},
})
dc.user.forEachNetwork(func(network *network) {
idStr := fmt.Sprintf("%v", network.ID)
attrs := getNetworkAttrs(network)
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": irc.TagValue("networks")},
Prefix: dc.srv.prefix(),
Command: "BOUNCER",
Params: []string{"NETWORK", idStr, attrs.String()},
dc.SendBatch("soju.im/bouncer-networks", nil, nil, func(batchRef irc.TagValue) {
dc.user.forEachNetwork(func(network *network) {
idStr := fmt.Sprintf("%v", network.ID)
attrs := getNetworkAttrs(network)
dc.SendMessage(&irc.Message{
Tags: irc.Tags{"batch": batchRef},
Prefix: dc.srv.prefix(),
Command: "BOUNCER",
Params: []string{"NETWORK", idStr, attrs.String()},
})
})
})
dc.SendMessage(&irc.Message{
Prefix: dc.srv.prefix(),
Command: "BATCH",
Params: []string{"-networks"},
})
case "ADDNETWORK":
var attrsStr string
if err := parseMessageParams(msg, nil, &attrsStr); err != nil {