|
@@ -54,8 +54,8 @@ func zncWireTimeToTime(str string) (result time.Time) {
|
54
|
54
|
}
|
55
|
55
|
|
56
|
56
|
type zncPlaybackTimes struct {
|
57
|
|
- after time.Time
|
58
|
|
- before time.Time
|
|
57
|
+ start time.Time
|
|
58
|
+ end time.Time
|
59
|
59
|
targets StringSet // nil for "*" (everything), otherwise the channel names
|
60
|
60
|
setAt time.Time
|
61
|
61
|
}
|
|
@@ -80,19 +80,26 @@ func (z *zncPlaybackTimes) ValidFor(target string) bool {
|
80
|
80
|
// PRIVMSG *playback :play <target> [lower_bound] [upper_bound]
|
81
|
81
|
// e.g., PRIVMSG *playback :play * 1558374442
|
82
|
82
|
func zncPlaybackHandler(client *Client, command string, params []string, rb *ResponseBuffer) {
|
83
|
|
- if len(params) < 2 {
|
|
83
|
+ if len(params) < 2 || len(params) > 4 {
|
84
|
84
|
return
|
85
|
85
|
} else if strings.ToLower(params[0]) != "play" {
|
86
|
86
|
return
|
87
|
87
|
}
|
88
|
88
|
targetString := params[1]
|
89
|
89
|
|
90
|
|
- var after, before time.Time
|
91
|
|
- if 2 < len(params) {
|
92
|
|
- after = zncWireTimeToTime(params[2])
|
93
|
|
- }
|
94
|
|
- if 3 < len(params) {
|
95
|
|
- before = zncWireTimeToTime(params[3])
|
|
90
|
+ now := time.Now().UTC()
|
|
91
|
+ var start, end time.Time
|
|
92
|
+ switch len(params) {
|
|
93
|
+ case 3:
|
|
94
|
+ // #831: this should have the same semantics as `LATEST timestamp=qux`,
|
|
95
|
+ // or equivalently `BETWEEN timestamp=$now timestamp=qux`, as opposed to
|
|
96
|
+ // `AFTER timestamp=qux` (this matters in the case where there are
|
|
97
|
+ // more than znc-maxmessages available)
|
|
98
|
+ start = now
|
|
99
|
+ end = zncWireTimeToTime(params[2])
|
|
100
|
+ case 4:
|
|
101
|
+ start = zncWireTimeToTime(params[2])
|
|
102
|
+ end = zncWireTimeToTime(params[3])
|
96
|
103
|
}
|
97
|
104
|
|
98
|
105
|
var targets StringSet
|
|
@@ -115,7 +122,7 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
|
115
|
122
|
// channels; redundant JOIN is a complete no-op so we won't replay twice
|
116
|
123
|
|
117
|
124
|
if params[1] == "*" {
|
118
|
|
- zncPlayPrivmsgs(client, rb, "*", after, before)
|
|
125
|
+ zncPlayPrivmsgs(client, rb, "*", start, end)
|
119
|
126
|
} else {
|
120
|
127
|
targets = make(StringSet)
|
121
|
128
|
for _, targetName := range strings.Split(targetString, ",") {
|
|
@@ -132,8 +139,8 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
|
132
|
139
|
}
|
133
|
140
|
|
134
|
141
|
rb.session.zncPlaybackTimes = &zncPlaybackTimes{
|
135
|
|
- after: after,
|
136
|
|
- before: before,
|
|
142
|
+ start: start,
|
|
143
|
+ end: end,
|
137
|
144
|
targets: targets,
|
138
|
145
|
setAt: time.Now().UTC(),
|
139
|
146
|
}
|
|
@@ -146,7 +153,7 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
|
146
|
153
|
}
|
147
|
154
|
|
148
|
155
|
for _, cfNick := range nickTargets {
|
149
|
|
- zncPlayPrivmsgs(client, rb, cfNick, after, before)
|
|
156
|
+ zncPlayPrivmsgs(client, rb, cfNick, start, end)
|
150
|
157
|
rb.Flush(true)
|
151
|
158
|
}
|
152
|
159
|
}
|