Relay detached channel backlog as BouncerServ NOTICE if necessary
Instead of ignoring detached channels wehn replaying backlog, process them as usual and relay messages as BouncerServ NOTICEs if necessary. Advance the delivery receipts as if the channel was attached. Closes: https://todo.sr.ht/~emersion/soju/98
This commit is contained in:
parent
76e332b50a
commit
a2c207d357
@ -1030,9 +1030,8 @@ func (dc *downstreamConn) sendTargetBacklog(net *network, target, msgID string)
|
|||||||
if dc.caps["draft/chathistory"] || dc.user.msgStore == nil {
|
if dc.caps["draft/chathistory"] || dc.user.msgStore == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ch := net.channels.Value(target); ch != nil && ch.Detached {
|
|
||||||
return
|
ch := net.channels.Value(target)
|
||||||
}
|
|
||||||
|
|
||||||
limit := 4000
|
limit := 4000
|
||||||
targetCM := net.casemap(target)
|
targetCM := net.casemap(target)
|
||||||
@ -1056,11 +1055,17 @@ func (dc *downstreamConn) sendTargetBacklog(net *network, target, msgID string)
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ch != nil && ch.Detached {
|
||||||
|
if net.detachedMessageNeedsRelay(ch, msg) {
|
||||||
|
dc.relayDetachedMessage(net, msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if dc.caps["batch"] {
|
if dc.caps["batch"] {
|
||||||
msg.Tags["batch"] = irc.TagValue(batchRef)
|
msg.Tags["batch"] = irc.TagValue(batchRef)
|
||||||
}
|
}
|
||||||
dc.SendMessage(dc.marshalMessage(msg, net))
|
dc.SendMessage(dc.marshalMessage(msg, net))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if dc.caps["batch"] {
|
if dc.caps["batch"] {
|
||||||
dc.SendMessage(&irc.Message{
|
dc.SendMessage(&irc.Message{
|
||||||
@ -1071,6 +1076,20 @@ func (dc *downstreamConn) sendTargetBacklog(net *network, target, msgID string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dc *downstreamConn) relayDetachedMessage(net *network, msg *irc.Message) {
|
||||||
|
if msg.Command != "PRIVMSG" && msg.Command != "NOTICE" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sender := msg.Prefix.Name
|
||||||
|
target, text := msg.Params[0], msg.Params[1]
|
||||||
|
if net.isHighlight(msg) {
|
||||||
|
sendServiceNOTICE(dc, fmt.Sprintf("highlight in %v: <%v> %v", dc.marshalEntity(net, target), sender, text))
|
||||||
|
} else {
|
||||||
|
sendServiceNOTICE(dc, fmt.Sprintf("message in %v: <%v> %v", dc.marshalEntity(net, target), sender, text))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (dc *downstreamConn) runUntilRegistered() error {
|
func (dc *downstreamConn) runUntilRegistered() error {
|
||||||
for !dc.registered {
|
for !dc.registered {
|
||||||
msg, err := dc.ReadMessage()
|
msg, err := dc.ReadMessage()
|
||||||
|
23
upstream.go
23
upstream.go
@ -391,10 +391,10 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
|||||||
ch := uc.network.channels.Value(target)
|
ch := uc.network.channels.Value(target)
|
||||||
if ch != nil {
|
if ch != nil {
|
||||||
if ch.Detached {
|
if ch.Detached {
|
||||||
uc.handleDetachedMessage(msg.Prefix.Name, text, ch)
|
uc.handleDetachedMessage(ch, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
highlight := msg.Prefix.Name != uc.nick && isHighlight(text, uc.nick)
|
highlight := uc.network.isHighlight(msg)
|
||||||
if ch.DetachOn == FilterMessage || ch.DetachOn == FilterDefault || (ch.DetachOn == FilterHighlight && highlight) {
|
if ch.DetachOn == FilterMessage || ch.DetachOn == FilterDefault || (ch.DetachOn == FilterHighlight && highlight) {
|
||||||
uc.updateChannelAutoDetach(target)
|
uc.updateChannelAutoDetach(target)
|
||||||
}
|
}
|
||||||
@ -1437,18 +1437,13 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uc *upstreamConn) handleDetachedMessage(sender string, text string, ch *Channel) {
|
func (uc *upstreamConn) handleDetachedMessage(ch *Channel, msg *irc.Message) {
|
||||||
highlight := sender != uc.nick && isHighlight(text, uc.nick)
|
if uc.network.detachedMessageNeedsRelay(ch, msg) {
|
||||||
if ch.RelayDetached == FilterMessage || ((ch.RelayDetached == FilterHighlight || ch.RelayDetached == FilterDefault) && highlight) {
|
|
||||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||||
if highlight {
|
dc.relayDetachedMessage(uc.network, msg)
|
||||||
sendServiceNOTICE(dc, fmt.Sprintf("highlight in %v: <%v> %v", dc.marshalEntity(uc.network, ch.Name), sender, text))
|
|
||||||
} else {
|
|
||||||
sendServiceNOTICE(dc, fmt.Sprintf("message in %v: <%v> %v", dc.marshalEntity(uc.network, ch.Name), sender, text))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if ch.ReattachOn == FilterMessage || (ch.ReattachOn == FilterHighlight && highlight) {
|
if ch.ReattachOn == FilterMessage || (ch.ReattachOn == FilterHighlight && uc.network.isHighlight(msg)) {
|
||||||
uc.network.attach(ch)
|
uc.network.attach(ch)
|
||||||
if err := uc.srv.db.StoreChannel(uc.network.ID, ch); err != nil {
|
if err := uc.srv.db.StoreChannel(uc.network.ID, ch); err != nil {
|
||||||
uc.logger.Printf("failed to update channel %q: %v", ch.Name, err)
|
uc.logger.Printf("failed to update channel %q: %v", ch.Name, err)
|
||||||
@ -1743,12 +1738,10 @@ func (uc *upstreamConn) produce(target string, msg *irc.Message, origin *downstr
|
|||||||
|
|
||||||
// Don't forward messages if it's a detached channel
|
// Don't forward messages if it's a detached channel
|
||||||
ch := uc.network.channels.Value(target)
|
ch := uc.network.channels.Value(target)
|
||||||
if ch != nil && ch.Detached {
|
detached := ch != nil && ch.Detached
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||||
if dc != origin || dc.caps["echo-message"] {
|
if !detached && (dc != origin || dc.caps["echo-message"]) {
|
||||||
dc.sendMessageWithID(dc.marshalMessage(msg, uc.network), msgID)
|
dc.sendMessageWithID(dc.marshalMessage(msg, uc.network), msgID)
|
||||||
} else {
|
} else {
|
||||||
dc.advanceMessageWithID(msg, msgID)
|
dc.advanceMessageWithID(msg, msgID)
|
||||||
|
21
user.go
21
user.go
@ -351,6 +351,27 @@ func (net *network) storeClientDeliveryReceipts(clientName string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (net *network) isHighlight(msg *irc.Message) bool {
|
||||||
|
if msg.Command != "PRIVMSG" && msg.Command != "NOTICE" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
text := msg.Params[1]
|
||||||
|
|
||||||
|
nick := net.Nick
|
||||||
|
if net.conn != nil {
|
||||||
|
nick = net.conn.nick
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use case-mapping aware comparison here
|
||||||
|
return msg.Prefix.Name != nick && isHighlight(text, nick)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (net *network) detachedMessageNeedsRelay(ch *Channel, msg *irc.Message) bool {
|
||||||
|
highlight := net.isHighlight(msg)
|
||||||
|
return ch.RelayDetached == FilterMessage || ((ch.RelayDetached == FilterHighlight || ch.RelayDetached == FilterDefault) && highlight)
|
||||||
|
}
|
||||||
|
|
||||||
type user struct {
|
type user struct {
|
||||||
User
|
User
|
||||||
srv *Server
|
srv *Server
|
||||||
|
Loading…
Reference in New Issue
Block a user