Browse Source

fix #1205

tags/v2.2.0
Shivaram Lingamneni 3 years ago
parent
commit
e827bc0f9c
3 changed files with 50 additions and 6 deletions
  1. 6
    1
      irc/handlers.go
  2. 1
    2
      irc/history/queries.go
  3. 43
    3
      irc/znc.go

+ 6
- 1
irc/handlers.go View File

@@ -3131,7 +3131,12 @@ func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
3131 3131
 
3132 3132
 // ZNC <module> [params]
3133 3133
 func zncHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
3134
-	zncModuleHandler(client, msg.Params[0], msg.Params[1:], rb)
3134
+	params := msg.Params[1:]
3135
+	// #1205: compatibility with Palaver, which sends `ZNC *playback :play ...`
3136
+	if len(params) == 1 && strings.IndexByte(params[0], ' ') != -1 {
3137
+		params = strings.Fields(params[0])
3138
+	}
3139
+	zncModuleHandler(client, msg.Params[0], params, rb)
3135 3140
 	return false
3136 3141
 }
3137 3142
 

+ 1
- 2
irc/history/queries.go View File

@@ -7,8 +7,7 @@ import (
7 7
 	"time"
8 8
 )
9 9
 
10
-// Selector represents a parameter to a CHATHISTORY command;
11
-// at most one of Msgid or Time may be nonzero
10
+// Selector represents a parameter to a CHATHISTORY command
12 11
 type Selector struct {
13 12
 	Msgid string
14 13
 	Time  time.Time

+ 43
- 3
irc/znc.go View File

@@ -53,6 +53,12 @@ func zncWireTimeToTime(str string) (result time.Time) {
53 53
 	return time.Unix(seconds, int64(fraction*1000000000)).UTC()
54 54
 }
55 55
 
56
+func timeToZncWireTime(t time.Time) (result string) {
57
+	secs := t.Unix()
58
+	nano := t.UnixNano() - (secs * 1000000000)
59
+	return fmt.Sprintf("%d.%d", secs, nano)
60
+}
61
+
56 62
 type zncPlaybackTimes struct {
57 63
 	start   time.Time
58 64
 	end     time.Time
@@ -77,13 +83,25 @@ func (z *zncPlaybackTimes) ValidFor(target string) bool {
77 83
 }
78 84
 
79 85
 // https://wiki.znc.in/Playback
86
+func zncPlaybackHandler(client *Client, command string, params []string, rb *ResponseBuffer) {
87
+	if len(params) == 0 {
88
+		return
89
+	}
90
+	switch strings.ToLower(params[0]) {
91
+	case "play":
92
+		zncPlaybackPlayHandler(client, command, params, rb)
93
+	case "list":
94
+		zncPlaybackListHandler(client, command, params, rb)
95
+	default:
96
+		return
97
+	}
98
+}
99
+
80 100
 // PRIVMSG *playback :play <target> [lower_bound] [upper_bound]
81 101
 // e.g., PRIVMSG *playback :play * 1558374442
82
-func zncPlaybackHandler(client *Client, command string, params []string, rb *ResponseBuffer) {
102
+func zncPlaybackPlayHandler(client *Client, command string, params []string, rb *ResponseBuffer) {
83 103
 	if len(params) < 2 || len(params) > 4 {
84 104
 		return
85
-	} else if strings.ToLower(params[0]) != "play" {
86
-		return
87 105
 	}
88 106
 	targetString := params[1]
89 107
 
@@ -123,6 +141,9 @@ func zncPlaybackHandler(client *Client, command string, params []string, rb *Res
123 141
 
124 142
 	if params[1] == "*" {
125 143
 		zncPlayPrivmsgs(client, rb, "*", start, end)
144
+	} else if params[1] == "*self" {
145
+		zncPlayPrivmsgs(client, rb, "*", start, end)
146
+		targets = make(StringSet) // XXX non-nil but empty channel set means "no channels"
126 147
 	} else {
127 148
 		targets = make(StringSet)
128 149
 		for _, targetName := range strings.Split(targetString, ",") {
@@ -169,3 +190,22 @@ func zncPlayPrivmsgs(client *Client, rb *ResponseBuffer, target string, after, b
169 190
 		client.replayPrivmsgHistory(rb, items, "", true)
170 191
 	}
171 192
 }
193
+
194
+// PRIVMSG *playback :list
195
+func zncPlaybackListHandler(client *Client, command string, params []string, rb *ResponseBuffer) {
196
+	nick := client.Nick()
197
+	for _, channel := range client.Channels() {
198
+		_, sequence, err := client.server.GetHistorySequence(channel, client, "")
199
+		if err != nil {
200
+			client.server.logger.Error("internal", "couldn't get history sequence for ZNC list", err.Error())
201
+			continue
202
+		}
203
+		items, _, err := sequence.Between(history.Selector{}, history.Selector{}, 1) // i.e., LATEST * 1
204
+		if err != nil {
205
+			client.server.logger.Error("internal", "couldn't query history for ZNC list", err.Error())
206
+		} else if len(items) != 0 {
207
+			stamp := timeToZncWireTime(items[0].Message.Time)
208
+			rb.Add(nil, "*playback!znc@znc.in", "PRIVMSG", nick, fmt.Sprintf("%s 0 %s", channel.Name(), stamp))
209
+		}
210
+	}
211
+}

Loading…
Cancel
Save