also, handle nickname targets in znc.in/playback
This commit is contained in:
Shivaram Lingamneni 2020-02-27 14:43:59 -05:00
parent e0f2475b80
commit 1dc93bbb9f
3 changed files with 42 additions and 8 deletions

View File

@ -773,7 +773,7 @@ func (channel *Channel) autoReplayHistory(client *Client, rb *ResponseBuffer, sk
var items []history.Item var items []history.Item
var after, before time.Time var after, before time.Time
if rb.session.zncPlaybackTimes != nil && (rb.session.zncPlaybackTimes.targets == nil || rb.session.zncPlaybackTimes.targets.Has(channel.NameCasefolded())) { if rb.session.zncPlaybackTimes.ValidFor(channel.NameCasefolded()) {
after, before = rb.session.zncPlaybackTimes.after, rb.session.zncPlaybackTimes.before after, before = rb.session.zncPlaybackTimes.after, rb.session.zncPlaybackTimes.before
} else if !rb.session.autoreplayMissedSince.IsZero() { } else if !rb.session.autoreplayMissedSince.IsZero() {
// we already checked for history caps in `playReattachMessages` // we already checked for history caps in `playReattachMessages`

View File

@ -668,7 +668,7 @@ func (client *Client) playReattachMessages(session *Session) {
} }
if !session.autoreplayMissedSince.IsZero() && !hasHistoryCaps { if !session.autoreplayMissedSince.IsZero() && !hasHistoryCaps {
rb := NewResponseBuffer(session) rb := NewResponseBuffer(session)
zncPlayPrivmsgs(client, rb, session.autoreplayMissedSince, time.Time{}) zncPlayPrivmsgs(client, rb, "*", session.autoreplayMissedSince, time.Time{})
rb.Send(true) rb.Send(true)
} }
session.autoreplayMissedSince = time.Time{} session.autoreplayMissedSince = time.Time{}

View File

@ -12,6 +12,11 @@ import (
"github.com/oragono/oragono/irc/history" "github.com/oragono/oragono/irc/history"
) )
const (
// #829, also see "Case 2" in the "three cases" below:
zncPlaybackCommandExpiration = time.Second * 30
)
type zncCommandHandler func(client *Client, command string, params []string, rb *ResponseBuffer) type zncCommandHandler func(client *Client, command string, params []string, rb *ResponseBuffer)
var zncHandlers = map[string]zncCommandHandler{ var zncHandlers = map[string]zncCommandHandler{
@ -52,6 +57,23 @@ type zncPlaybackTimes struct {
after time.Time after time.Time
before time.Time before time.Time
targets StringSet // nil for "*" (everything), otherwise the channel names targets StringSet // nil for "*" (everything), otherwise the channel names
setAt time.Time
}
func (z *zncPlaybackTimes) ValidFor(target string) bool {
if z == nil {
return false
}
if time.Now().Sub(z.setAt) > zncPlaybackCommandExpiration {
return false
}
if z.targets == nil {
return true
}
return z.targets.Has(target)
} }
// https://wiki.znc.in/Playback // https://wiki.znc.in/Playback
@ -74,6 +96,7 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
} }
var targets StringSet var targets StringSet
var nickTargets []string
// three cases: // three cases:
// 1. the user's PMs get played back immediately upon receiving this // 1. the user's PMs get played back immediately upon receiving this
@ -92,14 +115,19 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
// channels; redundant JOIN is a complete no-op so we won't replay twice // channels; redundant JOIN is a complete no-op so we won't replay twice
if params[1] == "*" { if params[1] == "*" {
zncPlayPrivmsgs(client, rb, after, before) zncPlayPrivmsgs(client, rb, "*", after, before)
} else { } else {
targets = make(StringSet) targets = make(StringSet)
// TODO actually handle nickname targets
for _, targetName := range strings.Split(targetString, ",") { for _, targetName := range strings.Split(targetString, ",") {
if strings.HasPrefix(targetName, "#") {
if cfTarget, err := CasefoldChannel(targetName); err == nil { if cfTarget, err := CasefoldChannel(targetName); err == nil {
targets.Add(cfTarget) targets.Add(cfTarget)
} }
} else {
if cfNick, err := CasefoldName(targetName); err == nil {
nickTargets = append(nickTargets, cfNick)
}
}
} }
} }
@ -107,6 +135,7 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
after: after, after: after,
before: before, before: before,
targets: targets, targets: targets,
setAt: time.Now().UTC(),
} }
for _, channel := range client.Channels() { for _, channel := range client.Channels() {
@ -115,10 +144,15 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
rb.Flush(true) rb.Flush(true)
} }
} }
for _, cfNick := range nickTargets {
zncPlayPrivmsgs(client, rb, cfNick, after, before)
rb.Flush(true)
}
} }
func zncPlayPrivmsgs(client *Client, rb *ResponseBuffer, after, before time.Time) { func zncPlayPrivmsgs(client *Client, rb *ResponseBuffer, target string, after, before time.Time) {
_, sequence, _ := client.server.GetHistorySequence(nil, client, "*") _, sequence, _ := client.server.GetHistorySequence(nil, client, target)
if sequence == nil { if sequence == nil {
return return
} }